HarmonyOS 鸿蒙Next使用showAssetsCreationDialog保存沙盒图片到相册无效

发布于 1周前 作者 itying888 来自 鸿蒙OS

HarmonyOS 鸿蒙Next使用showAssetsCreationDialog保存沙盒图片到相册无效

async saveNew() {
try {
let src = ‘/data/storage/el2/base/haps/entry/cache/custom/f8eae6750519389e078e1eb1bcb3d708.jpg’;
let res = FileUtil.accessSync(src);
let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(getContext());
// 获取需要保存到媒体库的位于应用沙箱的图片/视频uri
let srcFileUris: Array<string> = [src];
let photoCreationConfigs: Array<photoAccessHelper.PhotoCreationConfig> = [{
title: ‘imageName’, // 可选
fileNameExtension: ‘jpg’,
photoType: photoAccessHelper.PhotoType.IMAGE, // 可选,支持:普通图片、动态图片
subtype: photoAccessHelper.PhotoSubtype.DEFAULT,
}];
let desFileUris: Array<string> = await phAccessHelper.showAssetsCreationDialog(srcFileUris, photoCreationConfigs);

if (desFileUris.length > 0) {
FileUtil.copyFile(src, desFileUris[0]);
}
console.info('showAssetsCreationDialog success, data is ’ + desFileUris);
} catch (err) {
console.error('showAssetsCreationDialog failed, errCode is ’ + err.code + ', errMsg is ’ + err.message);
}
}

我通过以上代码保存沙盒中的图片到相册中没有保存成功,且无错误日志,沙盒中有对应的图片文件

另外我打断点发现,showAssetsCreationDialog返回的desFileUris中url和文件原位置一样,不是新路径,这是为什么呀?

4 回复
你们 showAssetsCreationDialog 能显示缩略图吗?

应该是没读取到沙箱里面的文件,可以参考以下demo,先往沙箱里拷贝一个图片,使用fileUri.getUriFromPath获取沙箱路径再保存

import { common } from '@kit.AbilityKit'
import { BusinessError } from '@kit.BasicServicesKit'
import fs from '@ohos.file.fs';
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { fileUri } from '@kit.CoreFileKit';
import { buffer } from '@kit.ArkTS';
export function myRawfileCopy(context: common.UIAbilityContext) {
  context.resourceManager.getRawFileContent("background.png", (err: BusinessError, data: Uint8Array) => {
    if (err != null) {
      console.error(`open aaa.txt failed: ${err.message}`)
    } else {
      let buffer = data.buffer
      let sanboxPath = context.filesDir
      console.log('myRawfileCopy path' + sanboxPath)
      let file = fs.openSync(context.filesDir + '/test.png', fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE)
      try {
        fs.writeSync(file.fd, buffer) // 拷贝文件到沙箱,为了简便,这里是直接getrawfilecontent然后写入,当文件过大时内存压力会很大,如需优化,可通过buffer进行读取
        fs.close(file.fd)
      } catch (err) {
        console.log('myRawfileCopy error')
      }
    }
  })
}
let context = getContext(this);
let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
export async function saveImgToPhoto(context: Context) {
  try {
    let phAccessHelper: photoAccessHelper.PhotoAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
    let photoCreationConfigs: Array<photoAccessHelper.PhotoCreationConfig> = [
      {
        title: 'test2', // 可选
        fileNameExtension:  'png',
        photoType: photoAccessHelper.PhotoType.IMAGE,
        subtype: photoAccessHelper.PhotoSubtype.DEFAULT, // 可选
      }
    ];
    let srcFileUris: Array<string> = [
      fileUri.getUriFromPath(context.filesDir+ '/test.png')
    ];
    let desFileUris: Array<string> = await phAccessHelper.showAssetsCreationDialog(srcFileUris, photoCreationConfigs);
    let file1 = fs.openSync(context.filesDir+ '/test.png', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
    let arrayBuffer = new ArrayBuffer(4096000);
    let readLen = fs.readSync(file1.fd, arrayBuffer);
    let buf = buffer.from(arrayBuffer, 0, readLen);
    console.info(`content of File: ${buf.toString()}`);
    let file2 = fs.openSync(desFileUris[0], fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
    let writeLen = fs.writeSync(file2.fd, arrayBuffer);
    fs.closeSync(file2);
    fs.closeSync(file1);
    console.info('showAssetsCreationDialog success, data is ' + desFileUris);
  } catch (err) {
    console.error('showAssetsCreationDialog failed, errCode is ' + err.code + ', errMsg is ' + err.message);
  }
  return false
}
[@Component](/user/Component)
[@Entry](/user/Entry)
struct Index {
  build() {
    Column() {
      Button('拷贝文件到沙箱').onClick(() => {
        myRawfileCopy(getContext(this) as common.UIAbilityContext)
      })
      Button('保存到').onClick(() => {
        saveImgToPhoto(getContext(this) as common.UIAbilityContext)
      })
    }
  }
}

嗯,找到原因了, 1.我文件路径写的是/data/ 这样的path,需要用fileUri转成uri 2.复制文件时直接使用了fs.copy( ),也无效,需要改成Buffer的方式

😮‍💨感觉鸿蒙保存图片、视频到相册不太方便,应该和iOS类似,开发者传递沙盒文件路径由系统自动保存,而不是开发者写copy过程;

针对HarmonyOS 鸿蒙Next使用showAssetsCreationDialog保存沙盒图片到相册无效的问题,以下是一些可能的解决方案:

  1. 权限检查:确保应用已正确申请并获得了存储权限,如“ohos.permission.WRITE_IMAGEVIDEO”。在鸿蒙系统中,权限管理较为严格,未获得相应权限可能导致文件无法写入。
  2. 保存路径:检查图片是否被保存在了系统认可的图片存储目录下。如果图片被保存在了不支持显示的文件夹中,也可能导致无法在图库中看到。
  3. 系统刷新:保存图片后,系统可能需要一定时间刷新相册视图。可以尝试使用系统提供的广播或内容观察者机制,监听相册内容的变更,从而触发相册的刷新。
  4. 媒体扫描:确认是否在保存图片时调用了系统的媒体扫描接口,如MediaScannerConnection.scanFile,这有助于系统立即识别新保存的图片。

如果以上步骤均正确无误,但问题依旧存在,可能是由于系统缓存或特定版本的bug导致。此时,可以尝试清除应用缓存或重启设备看是否能解决问题。如果问题依旧无法解决,请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部