HarmonyOS鸿蒙Next中申请ohos.permission.READ IMAGEVIDEO和 ohos.permission.WRITEIMAGEVIDEO权限未被批准通过,请问如何处理?

HarmonyOS鸿蒙Next中申请ohos.permission.READ IMAGEVIDEO和 ohos.permission.WRITEIMAGEVIDEO权限未被批准通过,请问如何处理?

申请ohos.permission.READ_IMAGEVIDEO和ohos.permission.WRITE_IMAGEVIDEO这两个权限,但权限申请未被批准通过,给的方案未满足全部需求,请问如何处理?

8 回复

【背景知识】

ohos.permission.WRITE_IMAGEVIDEO作为受限开放权限,如果不满足可申请权限的特殊场景,暂时只能通过官方提供的替代方案实现。

通过安全控件授权弹窗的方式,将用户指定的媒体资源保存到图库中。

  • SaveButton:安全控件的保存控件,用户通过点击该保存按钮,可以临时获取存储权限,而不需要权限弹框授权确认。
  • showAssetsCreationDialog:调用接口拉起保存确认弹窗。用户同意保存后,返回已创建并授予保存权限的uri列表,该列表永久生效,应用可使用该uri写入图片/视频。如果用户拒绝保存,将返回空列表。弹框需要显示应用名称,无法直接获取应用名称,依赖于配置项的label和icon,因此调用此接口时请确保module.json5文件中的abilities标签中配置了label和icon项。

【解决方案】

批量保存图片/视频使用showAssetsCreationDialog弹窗授权,同时传入多个uri,可以避免多次弹窗,实现一次弹窗批量保存的效果。开发步骤:

  1. 将需要保存的所有图片先存入沙盒中,并将文件uri保存至数组中。
// 拷贝图片资源到沙箱,多次调用此方法保存多个uri至srcFileUris数组中
copyFile(pictureName: string) {
  let context = this.getContext(this);
  let srcFileDescriptor = context.resourceManager.getRawFdSync(pictureName);
  let pathDir = context.filesDir;
  let dstPath = pathDir + "/" + pictureName;
  let filePath = fileUri.getUriFromPath(dstPath);
  this.srcFileUris.push(filePath); // 将uri存入srcFileUris数组中
  let dest = fs.openSync(dstPath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);
  let bufsize = 4096;
  let buf = new ArrayBuffer(bufsize);
  let off = 0, len = 0, readedLen = 0;
  while (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
    if ((srcFileDescriptor.length - readedLen) < bufsize) {
      bufsize = srcFileDescriptor.length - readedLen
    }
  };
  fs.close(dest.fd);
}
  1. 指定待保存照片的创建选项,包括文件后缀和照片类型,标题和照片子类型可选。
// 指定待保存图片的创建选项
let photoCreationConfigs: Array<photoAccessHelper.PhotoCreationConfig> = [
  {
    title: 'pic1',
    fileNameExtension: 'png',
    photoType: photoAccessHelper.PhotoType.IMAGE,
    subtype: photoAccessHelper.PhotoSubtype.DEFAULT,
  },
  {
    title: 'pic2',
    fileNameExtension: 'png',
    photoType: photoAccessHelper.PhotoType.IMAGE,
    subtype: photoAccessHelper.PhotoSubtype.DEFAULT,
  }
];
  1. 调用showAssetsCreationDialog,基于弹窗授权的方式获取的目标媒体文件uri。
let desFileUris: Array<string> = await phAccessHelper.showAssetsCreationDialog(this.srcFileUris, photoCreationConfigs);
  1. 将应用沙箱的图片内容写入媒体库的目标uri。
if (desFileUris.length > 0) {
  for (let index = 0; index < desFileUris.length; index++) {
    let desFile: fileIo.File = await fileIo.open(desFileUris[index], fileIo.OpenMode.WRITE_ONLY);
    let srcFile: fileIo.File = await fileIo.open(this.srcFileUris[index], fileIo.OpenMode.READ_ONLY);
    await fileIo.copyFile(srcFile.fd, desFile.fd);
    fileIo.closeSync(srcFile);
    fileIo.closeSync(desFile);
    console.info('create asset by dialog successfully');
  }
}

更多关于HarmonyOS鸿蒙Next中申请ohos.permission.READ IMAGEVIDEO和 ohos.permission.WRITEIMAGEVIDEO权限未被批准通过,请问如何处理?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


这两个权限属于system_basic级别且启用了ACL,需以normal等级申请。仅适用于需要克隆、备份或同步用户公共目录图片/视频的场景,且需通过华为AGC审核。DevEco Studio调试阶段可通过ACL临时申请,但正式商用版本必须通过应用市场申请发布证书和Profile文件。

楼主试一下替代方案:

  • 优先使用系统安全控件,通过<saveButton>控件保存媒体资源,无需直接申请权限。
  • 使用PhotoViewPicker选择图片/视频(通过Picker访问无需权限)。

若必须使用权限,需在应用描述中明确说明符合以下场景:

  • 用户主动触发的媒体文件备份/同步功能
  • 涉及用户隐私保护的核心功能(如实名认证)
  1. 楼主的应用是什么类型的呢,你看是否满足后面两项要求

    cke_918.png

    受限开放权限-应用权限列表-应用权限管控-程序访问控制-安全-系统 - 华为HarmonyOS开发者

    1. 批量保存图片的话可以改造一下下面方法,循环存储
    saveImage(filePath: string, context: Context) {
      let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
      let assetChangeRequest: photoAccessHelper.MediaAssetChangeRequest =
        photoAccessHelper.MediaAssetChangeRequest.createImageAssetRequest(context, filePath);
      // 改造这个方法,使用for循坏来保存
      phAccessHelper.applyChanges(assetChangeRequest).then((event) => {
        this.successDialog()
      })
        .catch((err: BusinessError) => {
          this.failedDialog('保存至图库失败' + err.code)
          LogUtil.e(Tag, err, '保存至图库失败')
        })
        .finally(() => {
          try {
            fs.unlinkSync(filePath)
          } catch (e) {
            LogUtil.d(Tag, e)
          }
        })
    }
    
  2. 使用安全控件存储会获取10秒的存储时间,能满足大部分的场景需求

    使用保存控件-使用安全控件-程序访问控制-安全-系统 - 华为HarmonyOS开发者

    cke_9930.png

楼主你好,现在的使用场景有哪些?官方回复提供的替代方案中,应该是涵盖大部分场景的,有哪些需求场景不满足麻烦描述下,我们根据情况再分析有没有其他合适方案。

申请原因:因为需要使用图片/视频批量上传、下载、拍照上传等相册功能所以需要ohos.permission.WRITE_IMAGEVIDE权限。

需要支持用户对图片进行批量下载,但用建议的替代技术方案貌似无法满足需求。

在鸿蒙Next中,若READ_IMAGEVIDEO/WRITE_IMAGEVIDEO权限未通过:

  1. 确保在module.json5的"requestPermissions"中正确定义权限:

    "requestPermissions": [
      {
        "name": "ohos.permission.READ_IMAGEVIDEO",
        "reason": "$string:reason"
      }
    ]
    
  2. 检查权限级别是否为normal(无需动态申请),若为system_basic/system_core需签名证书。

  3. 验证设备是否支持该权限(通过canIRequest接口)。

  4. 确保应用类型与权限匹配(如媒体类应用)。

权限未通过通常由配置错误或应用类型不符导致。

在HarmonyOS Next中,若遇到ohos.permission.READ_IMAGEVIDEO和ohos.permission.WRITE_IMAGEVIDEO权限申请未通过的情况,请按以下步骤排查:

  1. 检查权限声明:
  • 确保在module.json5中已正确声明权限:
"requestPermissions": [
  {
    "name": "ohos.permission.READ_IMAGEVIDEO",
    "reason": "需要访问相册"
  },
  {
    "name": "ohos.permission.WRITE_IMAGEVIDEO", 
    "reason": "需要保存图片到相册"
  }
]
  1. 权限级别验证:
  • 这两个权限属于normal级别,理论上不需要用户手动授权,但需要确保:
    • 应用已上架华为应用市场
    • 设备系统版本支持自动授权机制
  1. 运行时处理:
  • 虽然normal权限通常自动授予,但建议仍添加运行时检查:
import abilityAccessCtrl from '@ohos.abilityAccessCtrl';

let atManager = abilityAccessCtrl.createAtManager();
try {
  let status = await atManager.checkAccessToken(tokenId, "ohos.permission.READ_IMAGEVIDEO");
  if (status !== abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
    // 处理未授权情况
  }
} catch (err) {
  console.error(`检查权限失败: ${err}`);
}
  1. 常见问题排查:
  • 确认应用BundleName与上架时一致
  • 检查设备系统版本是否≥HarmonyOS 4.0
  • 清除应用数据后重试

若仍不通过,需要检查具体报错信息或设备日志,确认是否涉及其他限制条件。

回到顶部