HarmonyOS 鸿蒙Next中从相册选择图片然后推送到卡片

HarmonyOS 鸿蒙Next中从相册选择图片然后推送到卡片 https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-ui-widget-image-update

这个是官方文档里面的推送逻辑

// 在添加卡片时,打开一个本地图片并将图片内容传递给卡片页面显示
onAddForm(want: Want): formBindingData.FormBindingData {
  // 假设在当前卡片应用的tmp目录下有一个本地图片:head.PNG
  let tempDir = this.context.getApplicationContext().tempDir;
  hilog.info(DOMAIN_NUMBER, TAG, `tempDir: ${tempDir}`);
  let imgMap: Record<string, number> = {};
  try {
    // 打开本地图片并获取其打开后的fd
    let file = fileIo.openSync(tempDir + '/' + 'head.PNG');
    imgMap['imgBear'] = file.fd;
  } catch (e) {
    hilog.error(DOMAIN_NUMBER, TAG, `openSync failed: ${JSON.stringify(e as BusinessError)}`);
  }
}

1.第一个问题:使用的目录是tempDir目录,这个目录不是会自动清除吗,清除了之后,桌面卡片还会显示图片吗

2.第二个问题:官方这里指定了图片的名称,如果我从相册里面选择图片之后,图片的名称不是由我定义的,而且触发onAddForm的时候,我并不能把我想要推送的图片的名称,传递给卡片的生命周期,这个怎么解决


更多关于HarmonyOS 鸿蒙Next中从相册选择图片然后推送到卡片的实战教程也可以访问 https://www.itying.com/category-93-b0.html

9 回复

tempDir是应用沙箱内的临时目录,系统会在应用退出后自动清理该目录下的文件

建议

1.图片选择阶段:

使用photoAccessHelper.PhotoViewPicker选择图片

将图片拷贝至filesDir并保存路径到Preferences

2.卡片创建阶段:

通过onAddForm读取持久化路径并打开FD

确保跨进程传递时使用fd://协议

3.生命周期管理:

在onRemoveForm回调中关闭文件描述符

监听相册图片变更时调用formProvider.updateForm刷新卡片

更多关于HarmonyOS 鸿蒙Next中从相册选择图片然后推送到卡片的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在onRemoveForm回调中关闭文件描述符,卡片上的图片会被清除吗,我理解是需要打开图片后,把fd和file路径对应之后推送到卡片上,卡片才能显示图片,

找HarmonyOS工作还需要会Flutter的哦,有需要Flutter教程的可以学学大地老师的教程,很不错,B站免费学的哦:https://www.bilibili.com/video/BV1S4411E7LY/?p=17

理解了大佬,onRemoveForm是卡片销毁的生命周期回调函数,刚刚理解错了,感谢指导。

1.相册选择照片,然后拷贝出来,这个时候可以自定义写入的名称

import { photoAccessHelper } from '@kit.MediaLibraryKit';
import List from '@ohos.util.List';
import { fileIo } from '@kit.CoreFileKit';
import { promptAction } from '@kit.ArkUI';

@Entry
@Component
struct Day10Case14 {
  @State list: string[] = []

  saveLocal() {
    this.list.forEach(item => {
      let file = fileIo.openSync(item, fileIo.OpenMode.READ_ONLY);

      fileIo.copyFileSync(file.fd, getContext().filesDir + '/' + file.name)
      fileIo.closeSync(file)

      promptAction.showToast({
        message:"保存到沙箱成功"
      })
    })
  }

  //删除文件
  delFile(url:string){
    fileIo.unlinkSync(url)
  }
  
  build() {
    Column() {

      Grid() {
        ForEach(this.list, (item: string) => {
          GridItem() {
            Image(item).width("100%")
          }
        })
      }
      .layoutWeight(1)
      .columnsTemplate("1fr 1fr")
      .columnsGap(20)
      .rowsGap(20)
      .width("100%")

      Button("选中图片")
        .onClick(async () => {
          let photoView = new photoAccessHelper.PhotoViewPicker();
          let photo = await photoView.select({
            maxSelectNumber: 4
          });
          this.list = photo.photoUris

          this.saveLocal()
        })
    }
    .height('100%')
    .width('100%')
  }
}
  1. 相册图片选择:通过PhotoViewPicker接口获取用户选择的图片URI
  2. 文件路径处理:将图片复制到应用临时目录(确保卡片可访问)
  3. 卡片数据更新:通过FormProvider接口推送图片路径到卡片

关注,很好的问题

鸿蒙Next中通过Picker选择相册图片,使用FormProvider将图片数据推送到卡片。具体实现需调用MediaLibrary API获取图片URI,通过Want传递数据到卡片。卡片侧通过FormBindingData接收并更新显示。注意配置相册访问权限和卡片数据格式。

  1. tempDir目录确实会在应用退出后被系统清理,因此不适合用于持久存储卡片图片。建议使用filesDir目录存储图片,该目录在应用卸载前会一直存在,确保卡片能正常显示图片。

  2. 可以通过want参数传递图片信息。在启动卡片时,将选择的图片路径或标识通过want.parameters传递,在onAddForm中解析want参数获取图片信息,然后动态加载对应图片文件。具体实现需要在启动卡片的代码中设置参数,并在卡片provider中读取这些参数来定位图片文件。

回到顶部