HarmonyOS 鸿蒙Next phAccessHelper.showAssetsCreationDialog保存图片失败
HarmonyOS 鸿蒙Next phAccessHelper.showAssetsCreationDialog保存图片失败
点击同意返回的事-3006 也没有给授权的路径
async saveImagePath(path: string) {
console.info(‘ShowAssetsCreationDialogDemo.’);
<span class="hljs-comment">// 文件不存在</span>
<span class="hljs-keyword">if</span> (!fileIo.accessSync(path)) {
<span class="hljs-keyword">return</span>;
}
<span class="hljs-keyword">let</span> context = getContext(<span class="hljs-keyword">this</span>);
<span class="hljs-keyword">let</span> phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
<span class="hljs-keyword">try</span> {
<span class="hljs-comment">// 获取需要保存到媒体库的位于应用沙箱的图片/视频uri</span>
<span class="hljs-keyword">let</span> srcFileUris: <span class="hljs-built_in">Array</span><string> = [
path <span class="hljs-comment">// 实际场景请使用真实的uri</span>
];
<span class="hljs-keyword">let</span> photoCreationConfigs: <span class="hljs-built_in">Array</span><photoAccessHelper.PhotoCreationConfig> = [
{
<span class="hljs-comment">// 可选</span>
fileNameExtension: <span class="hljs-string">'jpg'</span>,
photoType: photoAccessHelper.PhotoType.IMAGE,
subtype: photoAccessHelper.PhotoSubtype.MOVING_PHOTO <span class="hljs-comment">// 可选</span>
}
];
<span class="hljs-keyword">let</span> desFileUris: <span class="hljs-built_in">Array</span><string> = await phAccessHelper.showAssetsCreationDialog(srcFileUris, photoCreationConfigs);
<span class="hljs-keyword">let</span> file = await fs.open(desFileUris[<span class="hljs-number">0</span>], fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
await fs.copy(path, desFileUris[<span class="hljs-number">0</span>]);
await fs.close(file.fd);
promptAction.showToast({
message: <span class="hljs-string">'已保存至相册!'</span>
});
} <span class="hljs-keyword">catch</span> (err) {
console.error(<span class="hljs-string">'showAssetsCreationDialog failed, errCode is '</span> + err.code + <span class="hljs-string">', errMsg is '</span> + err.message);
promptAction.showToast({
message: <span class="hljs-string">'保存失败,请稍后再试'</span>
});
}
}
更多关于HarmonyOS 鸿蒙Next phAccessHelper.showAssetsCreationDialog保存图片失败的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
import photoAccessHelper from '@ohos.file.photoAccessHelper';
import fs from ‘@ohos.file.fs’;
struct Index {
@State message: string = ‘Hello World’
build() {
Row() {
Column() {
Image($r(<span class="hljs-string">'app.media.startIcon'</span>))
.height(<span class="hljs-number">300</span>)
.width(<span class="hljs-number">300</span>)
SaveButton().onClick(async (_event: ClickEvent, result: SaveButtonOnClickResult) => {
<span class="hljs-keyword">if</span> (result == SaveButtonOnClickResult.SUCCESS) {
<span class="hljs-keyword">try</span> {
<span class="hljs-keyword">const</span> context = getContext(<span class="hljs-keyword">this</span>);
<span class="hljs-keyword">let</span> helper = photoAccessHelper.getPhotoAccessHelper(context);
<span class="hljs-comment">// onClick触发后5秒内通过createAsset接口创建图片文件,5秒后createAsset权限收回。</span>
<span class="hljs-keyword">let</span> uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, <span class="hljs-string">'jpg'</span>);
<span class="hljs-comment">// 使用uri打开文件,可以持续写入内容,写入过程不受时间限制</span>
<span class="hljs-keyword">let</span> file = await fs.open(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
<span class="hljs-keyword">try</span> {
context.resourceManager.getMediaContent($r(<span class="hljs-string">'app.media.startIcon'</span>).id, <span class="hljs-number">0</span>)
.then(async value => {
<span class="hljs-keyword">let</span> media = value.buffer;
<span class="hljs-comment">// 写到媒体库文件中</span>
await fs.write(file.fd, media);
await fs.close(file.fd);
AlertDialog.show({message:<span class="hljs-string">'已保存至相册!'</span>});
});
}
<span class="hljs-keyword">catch</span> (err) {
console.error(<span class="hljs-string">"error is "</span>+ <span class="hljs-built_in">JSON</span>.stringify(err))
}
} <span class="hljs-keyword">catch</span> (error) {
console.error(<span class="hljs-string">"error is "</span>+ <span class="hljs-built_in">JSON</span>.stringify(error));
}
}
<span class="hljs-keyword">else</span> {
AlertDialog.show({ message: <span class="hljs-string">"设置权限失败"</span> })
}
})
}
.width(<span class="hljs-string">'100%'</span>)
}
.height(<span class="hljs-string">'100%'</span>)
}
}
您需要申请相册管理模块权限’ohos.permission.WRITE_IMAGEVIDEO’和’ohos.permission.READ_IMAGEVIDEO’
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/restricted-permissions-V5
请参考demo:
import { common } from ‘@kit.AbilityKit’;
import { fileIo as fs, fileUri, ReadOptions, WriteOptions } from ‘@kit.CoreFileKit’
import { photoAccessHelper } from ‘@kit.MediaLibraryKit’;
import json from ‘@ohos.util.json’;
struct Index {
@State message: string = ‘Hello World’;
filePath: string = ‘’;
build() {
Column() {
Button(<span class="hljs-string">"复制文件到沙箱"</span>)
.onClick(() => {
console.log(<span class="hljs-string">'开始复制文件到沙箱'</span>)
<span class="hljs-keyword">this</span>.copyFile()
console.log(<span class="hljs-string">'复制文件到沙箱完成'</span>)
})
Button(<span class="hljs-string">'沙箱文件保存到相册'</span>)
.onClick(()=>{
console.log(<span class="hljs-string">'开始沙箱文件保存到相册'</span>)
<span class="hljs-keyword">this</span>.syncToSysAlbum(photoAccessHelper.PhotoType.IMAGE,<span class="hljs-string">'png'</span>, <span class="hljs-keyword">this</span>.filePath)
})
Button(<span class="hljs-string">'沙箱文件保存到相册'</span>)
.onClick(() => {
console.log(<span class="hljs-string">'开始沙箱文件保存到相册'</span>)
<span class="hljs-keyword">this</span>.example()
})
}
.height(<span class="hljs-string">'100%'</span>)
.width(<span class="hljs-string">'100%'</span>)
}
copyFile() {
console.log(<span class="hljs-string">"开发复制文件"</span>)
<span class="hljs-keyword">let</span> context = getContext(<span class="hljs-keyword">this</span>) as common.UIAbilityContext;
<span class="hljs-keyword">let</span> srcFileDescriptor = context.resourceManager.getRawFdSync(<span class="hljs-string">'background.png'</span>); <span class="hljs-comment">//这里填rawfile文件夹下的文件名(包括后缀)</span>
<span class="hljs-keyword">let</span> stat = fs.statSync(srcFileDescriptor.fd)
console.log(`stat isFile:${stat.isFile()}`);
<span class="hljs-comment">// 通过UIAbilityContext获取沙箱地址filesDir,以Stage模型为例</span>
<span class="hljs-keyword">let</span> pathDir = context.filesDir;
console.log(<span class="hljs-string">"沙箱文件目录路径:"</span>, pathDir)
<span class="hljs-keyword">let</span> dstPath = pathDir + <span class="hljs-string">"/background.png"</span>;
<span class="hljs-keyword">this</span>.filePath = fileUri.getUriFromPath(dstPath)
console.log(<span class="hljs-string">"沙箱文件URI"</span> + <span class="hljs-keyword">this</span>.filePath);
<span class="hljs-keyword">let</span> dest = fs.openSync(dstPath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE)
<span class="hljs-keyword">let</span> bufsize = <span class="hljs-number">4096</span>
<span class="hljs-keyword">let</span> buf = <span class="hljs-keyword">new</span> <span class="hljs-built_in">ArrayBuffer</span>(bufsize)
<span class="hljs-keyword">let</span> off = <span class="hljs-number">0</span>, len = <span class="hljs-number">0</span>, readedLen = <span class="hljs-number">0</span>
<span class="hljs-keyword">while</span> (len = fs.readSync(srcFileDescriptor.fd, buf, { offset: srcFileDescriptor.offset + off, length: bufsize })) {
readedLen += len
fs.writeSync(dest.fd, buf, { offset: off, length: len })
off = off + len
<span class="hljs-keyword">if</span> ((srcFileDescriptor.length - readedLen) < bufsize) {
bufsize = srcFileDescriptor.length - readedLen
}
}
fs.close(dest.fd)
}
async syncToSysAlbum(fileType: photoAccessHelper.PhotoType, extension: string, …filePath: string[]) {
<span class="hljs-comment">//此处获取的phAccessHelper实例为全局对象,后续使用到phAccessHelper的地方默认为使用此处获取的对象,如未添加此段代码报phAccessHelper未定义的错误请自行添加</span>
<span class="hljs-keyword">let</span> context = getContext(<span class="hljs-keyword">this</span>);
<span class="hljs-keyword">let</span> phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
<span class="hljs-keyword">try</span> {
<span class="hljs-keyword">const</span> srcFileUris: string[] = []
filePath.forEach((path) => {
srcFileUris.push(path)
})
<span class="hljs-keyword">const</span> config: photoAccessHelper.PhotoCreationConfig[] = []
config.push({
title: <span class="hljs-string">'background'</span>, <span class="hljs-comment">// 可选</span>
fileNameExtension: extension,
photoType: fileType,
subtype: photoAccessHelper.PhotoSubtype.DEFAULT, <span class="hljs-comment">// 可选</span>
})
console.log(<span class="hljs-string">"syncToSysAlarm fileUri:"</span> + json.stringify(srcFileUris) + <span class="hljs-string">",config:"</span> + json.stringify(config))
<span class="hljs-keyword">const</span> desFileUris = await phAccessHelper.showAssetsCreationDialog(srcFileUris, config)
console.debug(`目标图片 uri is : ${<span class="hljs-built_in">JSON</span>.stringify(desFileUris)}`)
<span class="hljs-keyword">if</span> (desFileUris.length > <span class="hljs-number">0</span>) {
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> index = <span class="hljs-number">0</span>; index < desFileUris.length; index++) {
<span class="hljs-keyword">this</span>.copyFileContentTo(srcFileUris[index], desFileUris[index])
}
}
} <span class="hljs-keyword">catch</span> (err) {
console.log(<span class="hljs-string">"syncToSysAlarm filePath:"</span> + filePath + <span class="hljs-string">",error:"</span> + json.stringify(err))
}
}
async example() {
console.info(<span class="hljs-string">'ShowAssetsCreationDialogDemo.'</span>);
<span class="hljs-keyword">let</span> context = getContext(<span class="hljs-keyword">this</span>) as common.UIAbilityContext
<span class="hljs-keyword">let</span> phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
<span class="hljs-keyword">try</span> {
<span class="hljs-comment">// 获取需要保存到媒体库的位于应用沙箱的图片/视频uri</span>
<span class="hljs-comment">// let srcFileUris: Array<string> = [</span>
<span class="hljs-comment">// // 实际场景请使用真实的uri</span>
<span class="hljs-comment">// // 'file://com.example.test35/data/storage/el2/base/haps/entry/files/background.png'</span>
<span class="hljs-comment">// this.filePath</span>
<span class="hljs-comment">// ];</span>
<span class="hljs-keyword">let</span> srcFileUri: <span class="hljs-built_in">Array</span><string> = [<span class="hljs-keyword">this</span>.filePath]
console.debug(`图片 uri is : ${<span class="hljs-built_in">JSON</span>.stringify(srcFileUri)}`)
<span class="hljs-keyword">let</span> photoCreationConfigs: <span class="hljs-built_in">Array</span><photoAccessHelper.PhotoCreationConfig> = [
{
title: <span class="hljs-string">'background'</span>, <span class="hljs-comment">// 可选</span>
fileNameExtension: <span class="hljs-string">'png'</span>,
photoType: photoAccessHelper.PhotoType.IMAGE,
subtype: photoAccessHelper.PhotoSubtype.DEFAULT, <span class="hljs-comment">// 可选</span>
}
];
console.log(<span class="hljs-string">"syncToSysAlarm fileUri:"</span> + <span class="hljs-built_in">JSON</span>.stringify(srcFileUri) + <span class="hljs-string">",config:"</span> +
<span class="hljs-built_in">JSON</span>.stringify(photoCreationConfigs))
<span class="hljs-keyword">let</span> desFileUris: <span class="hljs-built_in">Array</span><string> = await phAccessHelper.showAssetsCreationDialog(srcFileUri, photoCreationConfigs);
console.debug(`目标图片 uri is : ${<span class="hljs-built_in">JSON</span>.stringify(desFileUris)}`)
<span class="hljs-keyword">if</span> (desFileUris.length > <span class="hljs-number">0</span>) {
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> index = <span class="hljs-number">0</span>; index < desFileUris.length; index++) {
<span class="hljs-keyword">this</span>.copyFileContentTo(srcFileUri[index], desFileUris[index])
}
}
} <span class="hljs-keyword">catch</span> (err) {
console.error(<span class="hljs-string">'showAssetsCreationDialog failed, errCode is '</span> + err.code + <span class="hljs-string">', errMsg is '</span> + err.message);
}
}
/**
*/
copyFileContentTo(srcFilePath: string, destFilePath: string) {
<span class="hljs-keyword">let</span> srcFile = fs.openSync(srcFilePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)
<span class="hljs-keyword">let</span> destFile = fs.openSync(destFilePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)
<span class="hljs-comment">// 读取源文件内容并写入至目的文件</span>
<span class="hljs-keyword">let</span> bufSize = <span class="hljs-number">4096</span>;
<span class="hljs-keyword">let</span> readSize = <span class="hljs-number">0</span>;
<span class="hljs-keyword">let</span> buf = <span class="hljs-keyword">new</span> <span class="hljs-built_in">ArrayBuffer</span>(bufSize);
<span class="hljs-keyword">let</span> readOptions: ReadOptions = {
offset: readSize,
length: bufSize
};
<span class="hljs-keyword">let</span> readLen = fs.readSync(srcFile.fd, buf, readOptions);
<span class="hljs-keyword">while</span> (readLen > <span class="hljs-number">0</span>) {
readSize += readLen;
<span class="hljs-keyword">let</span> writeOptions: WriteOptions = {
length: readLen
};
fs.writeSync(destFile.fd, buf, writeOptions);
readOptions.offset = readSize;
readLen = fs.readSync(srcFile.fd, buf, readOptions);
}
<span class="hljs-comment">// 关闭文件</span>
fs.closeSync(srcFile);
fs.closeSync(destFile);
}
}
更多关于HarmonyOS 鸿蒙Next phAccessHelper.showAssetsCreationDialog保存图片失败的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙系统中,phAccessHelper.showAssetsCreationDialog
方法用于请求用户授权并显示资产创建对话框,通常用于保存图片到设备的存储中。若保存图片失败,可能的原因及解决方法如下:
-
权限未授予:确保应用已正确声明并请求了必要的存储权限(如读写外部存储权限)。用户需在权限请求对话框中点击“允许”。
-
存储路径问题:检查指定的存储路径是否正确,以及应用是否具有该路径的写入权限。路径错误或权限不足会导致保存失败。
-
图片数据问题:验证图片数据是否完整且格式正确。损坏或不完整的图片数据无法成功保存。
-
系统或API限制:确认使用的API版本与HarmonyOS版本兼容,且未触发系统安全策略限制。
-
异常处理:检查代码中是否有适当的异常捕获和处理逻辑,以便在保存失败时能够获取详细的错误信息。
如果以上检查均无误,但问题依旧存在,可能是系统或设备特定的bug。此时,建议通过官方渠道反馈问题,或尝试在不同的设备或系统版本上复现问题,以进一步定位原因。如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html