HarmonyOS鸿蒙Next中如何使用授权弹窗showAssetsCreationDialog保存图片到相册,预览界面存在空白方框问题
HarmonyOS鸿蒙Next中如何使用授权弹窗showAssetsCreationDialog保存图片到相册,预览界面存在空白方框问题
- 使用showAssetsCreationDialog 弹窗保存图片的时候,预览界面是空白
鉴于解决方式零零散散的,解决起来很麻烦,很繁琐特此收集解决方式归整记录
解决方式
2.1 需要使用 getUriFromPath() 方法把你要处理的沙箱路径包裹一下
let srcFileUri = fileUri.getUriFromPath(sandboxPath);
2.2 如果沙箱路径不正确,也会导致预览图出不来,关于沙箱路径的获取方式如下代码
async getSandboxPath(pixelMap: PixelMap, context: Context): Promise<string> {
// 获取应用文件路径
let filesDir: string = context.cacheDir;
let picName = '/tempImage' + new Date().getTime() + '.jpg';
// 新建并打开文件
let file = fs.openSync(filesDir + picName, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);
// 创建图像编码ImagePacker对象
const imagePackerApi = image.createImagePacker();
// 设置编码输出流和编码参数。format为图像的编码格式;quality为图像质量,范围从0-100,100为最佳质量
const options: image.PackingOption = { format: 'image/jpeg', quality: 98 };
await imagePackerApi.packToFile(pixelMap, file.fd, options);
return file.path;
}
2.3 弹窗打开同意授权保存沙箱照片到媒体
const sandboxPath = await PermissionUtils.getSandboxPath(this.pixelMap!, this.context);
// 获取相册的保存路径
let srcFileUri = fileUri.getUriFromPath(sandboxPath);
// 指定待保存到媒体库的位于应用沙箱的图片uri。
let srcFileUris: Array<string> = [
srcFileUri
];
let desFileUris: Array<string> = await phAccessHelper.showAssetsCreationDialog(srcFileUris, photoCreationConfigs);
// 将来源于应用沙箱的照片内容写入媒体库的目标uri。
let desFile: fileIo.File = await fileIo.open(desFileUris[0], fileIo.OpenMode.WRITE_ONLY);
let srcFile: fileIo.File = await fileIo.open(srcFileUri, fileIo.OpenMode.READ_ONLY);
await fileIo.copyFile(srcFile.fd, desFile.fd);
fileIo.closeSync(srcFile);
fileIo.closeSync(desFile);
this.getUIContext().getPromptAction().showToast({ message: $r('app.string.saved_to_album') });
完整片段
async getSandboxPath(pixelMap: PixelMap, context: Context): Promise<string> {
// 获取应用文件路径
let filesDir: string = context.cacheDir;
let picName = '/tempImage' + new Date().getTime() + '.jpg';
// 新建并打开文件
let file = fs.openSync(filesDir + picName, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);
// 创建图像编码ImagePacker对象
const imagePackerApi = image.createImagePacker();
// 设置编码输出流和编码参数。format为图像的编码格式;quality为图像质量,范围从0-100,100为最佳质量
const options: image.PackingOption = { format: 'image/jpeg', quality: 98 };
await imagePackerApi.packToFile(pixelMap, file.fd, options);
return file.path;
}
----------------
async showDiaLog(phAccessHelper: photoAccessHelper.PhotoAccessHelper) {
const sandboxPath = await PermissionUtils.getSandboxPath(this.pixelMap!, this.context);
// 获取相册的保存路径
let srcFileUri = fileUri.getUriFromPath(sandboxPath);
// 指定待保存到媒体库的位于应用沙箱的图片uri。
let srcFileUris: Array<string> = [
srcFileUri
];
// 指定待保存照片的创建选项,包括文件后缀和照片类型,标题和照片子类型可选。
let photoCreationConfigs: Array<photoAccessHelper.PhotoCreationConfig> = [
{
title: sandboxPath.split('/').pop()!.split('.')[0], // 可选
fileNameExtension: 'jpeg',
photoType: photoAccessHelper.PhotoType.IMAGE,
subtype: photoAccessHelper.PhotoSubtype.DEFAULT, // 可选
}
];
try {
// 基于弹窗授权的方式获取媒体库的目标uri。
let desFileUris: Array<string> = await phAccessHelper.showAssetsCreationDialog(srcFileUris, photoCreationConfigs);
// 将来源于应用沙箱的照片内容写入媒体库的目标uri。
let desFile: fileIo.File = await fileIo.open(desFileUris[0], fileIo.OpenMode.WRITE_ONLY);
let srcFile: fileIo.File = await fileIo.open(srcFileUri, fileIo.OpenMode.READ_ONLY);
await fileIo.copyFile(srcFile.fd, desFile.fd);
fileIo.closeSync(srcFile);
fileIo.closeSync(desFile);
this.getUIContext().getPromptAction().showToast({ message: $r('app.string.saved_to_album') });
} catch (err) {
console.error(`failed to create asset by dialog successfully errCode is: ${err.code}, ${err.message}`);
this.getUIContext().getPromptAction().showToast({ message: $r('app.string.reauthorization') });
}
}
最终预览图正常显示
更多关于HarmonyOS鸿蒙Next中如何使用授权弹窗showAssetsCreationDialog保存图片到相册,预览界面存在空白方框问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html
2 回复
关于HarmonyOS Next中使用showAssetsCreationDialog保存图片时预览空白的问题,您提供的解决方案已经非常全面。这里补充几点关键说明:
-
使用getUriFromPath()转换沙箱路径是必须的,因为直接使用沙箱路径无法被媒体库识别。
-
图片编码质量建议保持98,过高可能导致文件过大,过低则影响画质。
-
文件操作完成后务必调用closeSync()释放资源,避免内存泄漏。
-
异常处理中建议区分用户取消授权和其他错误情况,可针对不同错误码提供更精准的提示。
-
临时文件命名加入时间戳是个好做法,可避免文件名冲突。
您提供的完整代码片段已经涵盖了从图片编码、路径转换到授权保存的完整流程,是解决这个问题的标准方案。