十六、【鸿蒙 NEXT】如何申请权限

【前言】

在开发过程中经常会需要申请一些权限,才能调用一些系统接口,比如相机、获取位置信息等,一般按照授权类型,分为system_grant系统授权、user_grant用户授权、和manual_setting(手动设置授权)。本章主要讲下这几种授权如何实现

一、system_grant系统授权

系统授权由于不涉及用户个人数据,因此,只需要在module.json5的配置文件中声明权限后,系统会在用户安装应用时自动授予相应的权限。如下在module.json5中声明即可,系统权限类型参考,比如网络访问权限等。

二、user_grant用户授权

用户授权分为两步一是在module.json5中声明权限,二需要弹窗向用户授权

1、modue.json5声明权限

如下,name字段是权限名称,参考这里,reason是授权的目的,这个字段的内容,会在调用系统弹窗时展示在弹窗中,abilities表示在应用的那个uiability用到,when字段目前是预留字段,无实际作用

2、在代码中调用系统接口,向用户弹窗授权

主要分为3步骤:

(1)校验权限是否已经授权(调用接口checkAccessToken)

(2)未授权时弹出窗口授权(调用接口requestPermissionsFromUser,该接口只有首次授权时弹窗)

(3)如果用户首次授权拒绝后,二次提示用户弹窗(调用接口requestPermissionOnSetting)

完整代码实现如下

javascript 复制代码
import { abilityAccessCtrl, bundleManager, Permissions } from "@kit.AbilityKit";

export class PermissionUtils {
  public static async requestPermission(permission:Permissions) {
    // 1、校验权限是否已经授权
    let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
    let grantStatus: abilityAccessCtrl.GrantStatus = abilityAccessCtrl.GrantStatus.PERMISSION_DENIED;
    let tokenId: number = 0;
    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(() => { return abilityAccessCtrl.GrantStatus.PERMISSION_DENIED });
    if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
      console.log('checkAccessToken is granted')
      return
    }
    // 2、未授权情况下,使用requestPermissionsFromUser向用户弹窗授权(只有首次授权时有弹窗)
    let data = await atManager.requestPermissionsFromUser(getContext(), [permission])
    let grantResult: number[] = data.authResults;
    grantStatus = grantResult[0]
    if (grantStatus  === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
      console.log('requestPermissionsFromUser is granted')
      return
    }
    // 这里判断requestPermissionsFromUser是否有弹窗,如果有弹窗,则不再二次弹窗
    if (data.dialogShownResults?.[0] === true) {
      console.log('requestPermissionsFromUser is dialogShown')
      return false
    }
    // 3、后续二次授权弹窗
    let onSettingData = await atManager.requestPermissionOnSetting(getContext(), [permission])
    return onSettingData[0] === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED
  }
}

实现效果如下:

三、手动授权,跳转到系统设置页

最后一种是直接跳转到系统设置页面,让用户手动授权

javascript 复制代码
  public static goToSetting() {
    let bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION)
    let want:Want = {
      bundleName: 'com.huawei.hmos.settings',
      abilityName:'com.huawei.hmos.settings.MainAbility',
      uri:'application_info_entry',
      parameters: {
        pushParams: {
          bundleName:bundleInfo.name
        }
      }
    }
    let context = getContext() as common.UIAbilityContext
    context.startAbility(want)
  }

其中uri = 'application_info_entry'表示应用的设置页面,更多uri参考

相关推荐
前端不太难3 小时前
HarmonyOS 游戏里,Ability 是如何被重建的
游戏·状态模式·harmonyos
lbb 小魔仙3 小时前
【HarmonyOS实战】React Native 鸿蒙版实战:Calendar 日历组件完全指南
react native·react.js·harmonyos
一只大侠的侠3 小时前
Flutter开源鸿蒙跨平台训练营 Day 3
flutter·开源·harmonyos
盐焗西兰花3 小时前
鸿蒙学习实战之路-Reader Kit自定义字体最佳实践
学习·华为·harmonyos
_waylau4 小时前
鸿蒙架构师修炼之道-架构师的职责是什么?
开发语言·华为·harmonyos·鸿蒙
一只大侠的侠5 小时前
【Harmonyos】Flutter开源鸿蒙跨平台训练营 Day 2 鸿蒙跨平台开发环境搭建与工程实践
flutter·开源·harmonyos
小镇敲码人7 小时前
华为CANN框架中HCCL仓库的全面解析:分布式通信的引擎
分布式·华为
王码码20358 小时前
Flutter for OpenHarmony 实战之基础组件:第三十一篇 Chip 系列组件 — 灵活的标签化交互
android·flutter·交互·harmonyos
坚果派·白晓明8 小时前
在鸿蒙设备上快速验证由lycium工具快速交叉编译的C/C++三方库
c语言·c++·harmonyos·鸿蒙·编程语言·openharmony·三方库
小镇敲码人8 小时前
深入剖析华为CANN框架下的Ops-CV仓库:从入门到实战指南
c++·python·华为·cann