鸿蒙开发如何配置应用权限?比如相机、存储权限的申请流程?

开发一个鸿蒙原生应用,需要调用相机拍照并保存到本地存储,但运行时提示“权限不足”,无法调用相机。已在config.json中添加了相机和存储的权限声明,但还是不行。请问鸿蒙应用权限申请的完整流程是什么?除了在配置文件中声明,还需要在代码中做哪些操作?有没有具体的代码示例,比如动态申请相机权限的逻辑?

阅读 664
avatarAI BotBETA

以下是鸿蒙(HarmonyOS)应用权限申请的完整流程及代码示例,包含相机和存储权限的配置与动态申请步骤:


1. 配置文件声明权限

config.json 中声明所需权限(必须步骤):

{
  "module": {
    "reqPermissions": [
      {
        "name": "ohos.permission.CAMERA",
        "reason": "需要拍照功能" // 权限申请理由(用户可见)
      },
      {
        "name": "ohos.permission.WRITE_USER_STORAGE",
        "reason": "保存图片到相册"
      }
    ]
  }
}

注意

  • WRITE_USER_STORAGE 用于写入外部存储(API 8及以下)
  • API 9+ 推荐使用 ohos.permission.READ_IMAGEohos.permission.WRITE_IMAGE 管理媒体文件

2. 动态申请权限(关键步骤)

仅声明权限不够,必须在运行时动态申请。流程如下:

步骤逻辑

  1. 检查权限是否已授权
  2. 若未授权,弹出系统权限申请弹窗
  3. 在回调中处理授权结果

完整代码示例(以相机权限为例)

import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.security.SystemPermission;

public class MainAbility extends Ability {
    private static final int PERMISSION_REQUEST_CODE = 1;
    private static final String[] PERMISSIONS = {
        SystemPermission.CAMERA,
        SystemPermission.WRITE_USER_STORAGE // 或 WRITE_IMAGE(API 9+)
    };

    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);
        // 检查并申请权限
        requestPermissions();
    }

    private void requestPermissions() {
        // 检查权限状态
        if (verifySelfPermission(PERMISSIONS[0]) != 0 || verifySelfPermission(PERMISSIONS[1]) != 0) {
            // 未授权,发起申请
            requestPermissionsFromUser(PERMISSIONS, PERMISSION_REQUEST_CODE);
        } else {
            // 已授权,执行拍照操作
            takePhoto();
        }
    }

    // 处理权限申请结果
    @Override
    public void onRequestPermissionsFromUserResult(int requestCode, String[] permissions, int[] grantResults) {
        if (requestCode == PERMISSION_REQUEST_CODE) {
            // 检查所有权限是否被授予
            boolean allGranted = true;
            for (int result : grantResults) {
                if (result != 0) { // 0 表示授权成功
                    allGranted = false;
                    break;
                }
            }
            if (allGranted) {
                takePhoto(); // 权限通过,执行拍照
            } else {
                // 处理拒绝逻辑(如提示用户)
                showToast("权限被拒绝,功能无法使用!");
            }
        }
    }

    private void takePhoto() {
        // 调用相机拍照的实现代码
    }
}

3. 关键API说明

方法作用
verifySelfPermission(String permission)检查单个权限状态(返回0表示已授权)
requestPermissionsFromUser(String[] permissions, int requestCode)弹出系统权限申请弹窗
onRequestPermissionsFromUserResult()处理权限申请结果回调

4. 用户拒绝后的处理策略

  • 引导用户手动开启:当权限被拒绝时,提示用户前往设置页开启:

    private void showPermissionGuideDialog() {
      new SystemDialog(this)
          .setTitle("权限提示")
          .setContent("请在设置中开启相机和存储权限")
          .setPositiveButton("去设置", (dialog, which) -> {
              // 跳转到应用设置页面
              Intent intent = new Intent();
              intent.setOperation(new Intent.OperationBuilder()
                  .withAction("ability.settings.app.info")
                  .build());
              startAbility(intent);
          })
          .show();
    }

5. 常见问题排查

  1. 权限名称拼写错误
    确认 config.json 中的权限名与代码中完全一致(区分大小写)。
  2. 未处理动态申请
    仅声明权限不会自动生效,必须调用 requestPermissionsFromUser()
  3. 未覆盖所有权限
    多权限需同时申请,确保数组包含所有必要权限。
  4. 设备兼容性问题
    API 9+ 使用新的媒体权限(READ_IMAGE/WRITE_IMAGE),旧权限可能失效。

6. 存储权限特殊说明(API 9+)

从 API 9 开始:

  • 使用 媒体库接口 替代直接文件路径操作
  • 申请媒体读写权限:

    {
      "name": "ohos.permission.READ_IMAGE",
      "reason": "读取照片"
    },
    {
      "name": "ohos.permission.WRITE_IMAGE",
      "reason": "保存照片"
    }

完整流程总结
配置文件声明运行时动态申请处理授权结果拒绝时引导用户手动开启
按此流程操作即可解决权限不足问题。

1 个回答
✓ 已被采纳

鸿蒙开发配置相机、存储权限,先在 module.json5 里通过 requestPermissions 声明权限并填写使用场景,再在代码中用 PermissionHelper 检查是否授权,未授权时调用 requestPermissions 动态申请,最后重写权限申请结果回调,判断授权成功后再调用对应功能即可。