HarmonyOS 鸿蒙Next中应用权限管理的最佳实践是什么?如何动态申请和管理敏感权限?

HarmonyOS 鸿蒙Next中应用权限管理的最佳实践是什么?如何动态申请和管理敏感权限?

5 回复

【背景知识】

应用权限申请:在HarmonyOS开发中,应用访问如相机、麦克风、位置、图库等系统资源或系统能力时,需通过系统Picker安全控件授权使用等方式来访问,以确保用户隐私安全。

【参考方案】

可参考考勤打卡位置获取示例,通过动态申请权限实现利用位置服务进行考勤打卡的效果。

  1. 校验应用是否被授权。
async checkPermissions(permissions: Array<Permissions>) {
  for (let permission of permissions) {
    let grantStatus: abilityAccessCtrl.GrantStatus = await this.checkAccessToken(permission);
    if (grantStatus !== abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
      return false;
    }
  }
  return true;
}

async checkAccessToken(permission: Permissions): Promise<abilityAccessCtrl.GrantStatus> {
  let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
  let grantStatus: abilityAccessCtrl.GrantStatus = abilityAccessCtrl.GrantStatus.PERMISSION_DENIED;

  // 获取应用程序的accessTokenID
  let tokenId: number = 0;
  try {
    let bundleInfo: bundleManager.BundleInfo =
      await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
    let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;
    tokenId = appInfo.accessTokenId;
    grantStatus = await atManager.checkAccessToken(tokenId, permission);
  } catch (error) {
    let err: BusinessError = error as BusinessError;
    hilog.error(0x000, 'testTag', `Failed to check access token  ${err.code}, message is ${err.message}`);
  }
  return grantStatus;
}
  1. 第一次弹窗申请用户授权。
async requestPermissions(context: UIContext, permissions: Array<Permissions>): Promise<boolean | undefined> {
  let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
  try {
    let data =
      await atManager.requestPermissionsFromUser(context.getHostContext() as common.UIAbilityContext, permissions)
    hilog.info(0x000, 'testTag', 'requestPermissions1 success', JSON.stringify(data))
    return data.dialogShownResults ? data.dialogShownResults[0] : undefined; // 返回请求是否有弹窗
  } catch (e) {
    hilog.error(0x000, 'testTag', `requestPermissions1 err Code is ${e.code}, message is ${e.message}`);
    return undefined;
  }
}
  1. 第二次半模态设置页面申请用户授权。
requestPermissionsOnSetting(context: UIContext, permissions: Array<Permissions>) {
  let keyPerms = JSON.stringify(permissions)
  let store = preferences.getPreferencesSync(context.getHostContext(), { name: 'permsHasOnSetting' });
  if (!store.hasSync(keyPerms)) {
    let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
    atManager.requestPermissionOnSetting(context.getHostContext(), permissions)
      .then((res: Array<abilityAccessCtrl.GrantStatus>) => {
        hilog.info(0x000, 'testTag', 'requestPermissions2 success', JSON.stringify(res))
        store.putSync(keyPerms, 1);
        store.flush()
      })
      .catch((err: BusinessError) => {
        hilog.info(0x000, 'testTag', 'requestPermissions2 err', JSON.stringify(err))
      })
  }
}

更多关于HarmonyOS 鸿蒙Next中应用权限管理的最佳实践是什么?如何动态申请和管理敏感权限?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


已知2种写法:方法1:简单把requestPermissionsFromUser封工具类,用权限的时候调用工具类。 方法2: 把requestPermissionsFromUser放aop代码,工具类直接请求,然后用aop对工具类做增强。 还有别的写法吗?

言简意赅地说,应用该干什么的时候才干什么,不能想干什么的时候就干什么

鸿蒙Next应用权限管理采用分级授权机制。应用需在config.json中声明所需权限,敏感权限需动态申请。使用abilityContext.requestPermissionsFromUser()触发运行时授权弹窗,通过回调函数处理授权结果。权限状态可通过verifySelfPermission()实时校验。对于敏感权限,系统会记录用户授权决策并在应用再次请求时自动应用。

在HarmonyOS Next中,应用权限管理的最佳实践包括以下关键点:

  1. 权限最小化原则:仅申请应用功能必需的权限,避免过度请求,以增强用户信任并降低安全风险。

  2. 动态权限申请:对于敏感权限(如位置、相机、麦克风等),应在运行时按需动态申请,而非在安装时一次性请求所有权限。使用abilityAccessCtrl模块的requestPermissionsFromUser方法触发授权弹窗,用户可实时控制权限授予。

  3. 透明解释权限用途:在申请权限前,通过界面提示或文档说明权限的使用场景(例如"需要位置权限用于地图导航"),帮助用户理解授权必要性。

  4. 优雅处理拒绝情况:若用户拒绝授权,应提供降级功能或引导用户手动开启权限(例如通过设置页),避免应用强制退出或功能中断。

  5. 持续权限状态监控:通过verifyAccessToken接口定期检查权限状态,应对用户随时在系统设置中更改权限的情况,确保功能与权限状态同步。

示例代码(动态申请权限):

import abilityAccessCtrl from '@ohos.abilityAccessCtrl';

let atManager = abilityAccessCtrl.createAtManager();
try {
  atManager.requestPermissionsFromUser(this.context, ['permission.CAMERA'], (err, data) => {
    if (err) {
      console.error(`Request permission failed, code: ${err.code}, message: ${err.message}`);
    } else {
      console.info('Permission granted:', data.permissions);
    }
  });
} catch (err) {
  console.error(`Request permission error, code: ${err.code}, message: ${err.message}`);
}

通过以上实践,可平衡功能需求与用户隐私保护,提升应用合规性和体验。

回到顶部