本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新

一、权限分类与授权方式
  1. 权限类型

    • system_grant(系统授权) 无需用户手动操作,安装时自动授予,适用于低敏感权限(如网络访问、后台运行)。 示例:ohos.permission.INTERNETohos.permission.KEEP_BACKGROUND_RUNNING 。
    • user_grant(用户授权) 需运行时动态弹窗申请,涉及敏感数据(如位置、相机),用户可随时在设置中撤销。 示例:ohos.permission.CAMERAohos.permission.MICROPHONE 。
  2. 权限等级(APL)

    • normal:普通应用默认等级,可申请普通权限(如日历读写)。
    • system_basic:需签名证书,用于基础系统服务(如Wi-Fi配置)。
    • system_core:仅系统应用开放(不开放给三方应用)。
二、权限申请流程与核心API
  1. 声明权限(静态配置)

         在 module.json5 中声明权限,user_grant 类型需添加权限使用原因:

{
  "module": {
    "requestPermissions": [
      {
        "name": "ohos.permission.CAMERA",
        "reason": "$string:camera_permission_reason",
        "usedScene": {
          "abilities": ["EntryAbility"],
          "when": "always"
        }
      }
    ]
  }
}

注:reason:需多语言适配,如“用于拍摄照片和视频”。 

2.检查权限状态

  • 核心APIcheckAccessTokenSync() 检查用户是否已授权,返回 GrantStatus.PERMISSION_GRANTED 或 PERMISSION_DENIED
import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
import bundleManager from '@ohos.bundle.bundleManager';

// 获取应用唯一标识 tokenID
const bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
const tokenID = bundleInfo.appInfo.accessTokenId;

// 检查权限
const atManager = abilityAccessCtrl.createAtManager();
const status = atManager.checkAccessTokenSync(tokenID, 'ohos.permission.CAMERA');
if (status === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
  console.log('已授权');
}

3.动态申请权限

  • 核心APIrequestPermissionsFromUser() 触发系统弹窗,用户可选择“允许”“拒绝”或“仅本次允许”。
import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
import common from '@ohos.app.ability.common';

async function requestCameraPermission(context: common.UIAbilityContext) {
  const atManager = abilityAccessCtrl.createAtManager();
  const permissions: Array<Permissions> = ['ohos.permission.CAMERA'];
  try {
    const result = await atManager.requestPermissionsFromUser(context, permissions);
    if (result.authResults[0] === 0) {
      console.log('用户已授权');
    } else {
      console.log('用户拒绝');
    }
  } catch (err) {
    console.error(`申请失败: ${JSON.stringify(err)}`);
  }
}

弹窗行为说明

  • 首次拒绝后,后续调用可能无法弹窗,需引导用户前往设置页

4.处理用户拒绝场景

  • 二次引导APIrequestPermissionOnSetting() 跳转系统设置页,引导用户手动开启权限:
await atManager.requestPermissionOnSetting(context, ['ohos.permission.CAMERA']);
三、常用API总结
API方法 作用 示例场景
createAtManager() 创建权限管理实例 初始化权限检查或申请
checkAccessTokenSync() 同步检查权限状态 功能执行前的权限校验
requestPermissionsFromUser() 动态申请权限 用户触发敏感操作时弹窗
requestPermissionOnSetting() 跳转系统设置页 用户拒绝后的二次引导
四、注意事项
  1. 最小权限原则
    • 仅申请必要的权限,避免过度申请(如天气应用无需麦克风权限) 。
  2. 按需申请时机
    • 在用户触发功能时申请权限(如点击“拍照”按钮再请求相机权限) 。
  3. 用户体验优化
    • 申请前解释权限用途(如弹窗提示“需要访问位置以提供附近服务”)。
    • 用户拒绝后提供降级方案(如手动输入地址代替定位) 。
  4. 敏感权限处理
    • user_grant 权限需适配多语言说明,并通过应用市场审核 。

五、完整示例代码(相机权限申请) 

import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
import common from '@ohos.app.ability.common';
import bundleManager from '@ohos.bundle.bundleManager';

async function checkAndRequestCameraPermission(context: common.UIAbilityContext) {
  const atManager = abilityAccessCtrl.createAtManager();
  const permissions: Array<Permissions> = ['ohos.permission.CAMERA'];

  // 获取 tokenID
  const bundleInfo = bundleManager.getBundleInfoForSelfSync(
    bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION
  );
  const tokenID = bundleInfo.appInfo.accessTokenId;

  // 检查权限
  const status = atManager.checkAccessTokenSync(tokenID, permissions[0]);
  if (status === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
    console.log('已授权');
    return;
  }

  // 动态申请
  try {
    const result = await atManager.requestPermissionsFromUser(context, permissions);
    if (result.authResults[0] === 0) {
      console.log('用户同意授权');
    } else {
      console.log('用户拒绝,引导前往设置');
      await atManager.requestPermissionOnSetting(context, permissions);
    }
  } catch (err) {
    console.error(`权限申请异常: ${JSON.stringify(err)}`);
  }
}

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐