HarmonyOS 鸿蒙Next phAccessHelper.showAssetsCreationDialog保存图片失败

发布于 1周前 作者 sinazl 最后一次编辑是 5天前 来自 鸿蒙OS

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>&lt;string&gt; = [
        path <span class="hljs-comment">// 实际场景请使用真实的uri</span>
    ];

    <span class="hljs-keyword">let</span> photoCreationConfigs: <span class="hljs-built_in">Array</span>&lt;photoAccessHelper.PhotoCreationConfig&gt; = [
        {
            <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>&lt;string&gt; = 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

2 回复
保存图片需要调用fs.write将图片写入文件
import photoAccessHelper from '@ohos.file.photoAccessHelper';

import fs from ‘@ohos.file.fs’;

@Entry

@Component

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) =&gt; {

      <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 =&gt; {

                <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’;

@Entry

@Component

struct Index {

@State message: string = ‘Hello World’;

filePath: string = ‘’;

build() {

Column() {

  Button(<span class="hljs-string">"复制文件到沙箱"</span>)

    .onClick(() =&gt; {

      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(()=&gt;{

      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(() =&gt; {

      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) &lt; 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) =&gt; {

    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 &gt; <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 &lt; 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&lt;string&gt; = [</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>&lt;string&gt; = [<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>&lt;photoAccessHelper.PhotoCreationConfig&gt; = [

    {

      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>&lt;string&gt; = 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 &gt; <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 &lt; 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);

}

}

/**

  • 复制文件内容到目标文件

  • @param srcFilePath 源文件路径

  • @param destFilePath 目标文件路径

*/

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 &gt; <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 方法用于请求用户授权并显示资产创建对话框,通常用于保存图片到设备的存储中。若保存图片失败,可能的原因及解决方法如下:

  1. 权限未授予:确保应用已正确声明并请求了必要的存储权限(如读写外部存储权限)。用户需在权限请求对话框中点击“允许”。

  2. 存储路径问题:检查指定的存储路径是否正确,以及应用是否具有该路径的写入权限。路径错误或权限不足会导致保存失败。

  3. 图片数据问题:验证图片数据是否完整且格式正确。损坏或不完整的图片数据无法成功保存。

  4. 系统或API限制:确认使用的API版本与HarmonyOS版本兼容,且未触发系统安全策略限制。

  5. 异常处理:检查代码中是否有适当的异常捕获和处理逻辑,以便在保存失败时能够获取详细的错误信息。

如果以上检查均无误,但问题依旧存在,可能是系统或设备特定的bug。此时,建议通过官方渠道反馈问题,或尝试在不同的设备或系统版本上复现问题,以进一步定位原因。如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部