codecamp

鸿蒙OS 权限开发指导

场景介绍

HarmonyOS 支持开发者自定义权限来保护能力或接口,同时开发者也可申请权限来访问受权限保护的对象。

权限申请

开发者需要在 config.json 文件中的“reqPermissions”字段中声明所需要的权限。

{
    "reqPermissions": [{
        "name": "ohos.permission.CAMERA",
        "reason": "$string:permreason_camera",
        "usedScene": {
            "ability": ["com.mycamera.Ability", "com.mycamera.AbilityBackground"],
            "when": "always"
        }
    },{
    ...
    }]
}

权限申请格式采用数组格式,可支持同时申请多个权限,权限个数最多不能超过 1024 个。

值说明 类型 取值范围 默认值 规则约束
name 必须,填写需要使用的权限名称。 字符串 自定义 未填写时,解析失败。
reason 可选,当申请的权限为 user_grant 权限时此字段必填。描述申请权限的原因。 字符串 显示文字长度不能超过 256 个字节。 user_grant 权限必填,否则不允许在应用市场上架。需做多语种适配。
usedScene 可选,当申请的权限为 user_grant 权限时此字段必填。描述权限使用的场景和时机。场景类型有:ability、when(调用时机)。可配置多个ability。 ability:字符串数组 when:字符串 ability:ability 的名称 when:inuse(使用时)、always(始终) ability:空 when:inuse user_grant权限必填 ability,可选填when。

如果声明使用的权限的 grantMode 是 system_grant, 则权限会在当应用安装的时候被自动授予。

如果声明使用的权限的 grantMode 是 user_grant,则必须经用户手动授权(用户在弹框中授权或进入权限设置界面授权)才可使用。用户会看到 reason 字段中填写的理由,来帮助用户决定是否给予授权。

说明

对于授权方式为 user_grant 的权限,每一次执行需要这一权限的操作时,都需要检查自身是否有该权限。当自身具有权限时,才可继续执行,否则应用需要请求用户授予权限。示例参见[动态申请权限开发步骤]。

自定义权限

开发者需要在 config.json 文件中的“defPermissions”字段中自定义所需的权限:

{
    "defPermissions": [{
        "name": "com.myability.permission.MYPERMISSION",
        "grantMode": "system_grant",
        "availableScope": ["signature"]
    }, {
    ...
    }]
}

权限定义格式采用数组格式,可支持同时定义多个权限,自定义的权限个数最多不能超过 1024个。权限定义的字段描述详见[表2]。

值说明 类型 取值范围 默认值 规则约束
name 必填,权限名称。为最大可能避免重名,采用反向域公司名+应用名+权限名组合。 字符串 自定义 第三方应用不允许填写系统存在的权限,否则安装失败。未填写解析失败。权限名长度不能超过 256 个字符。
grantMode 必填,权限授予方式。 字符串 user_grant(用户授权)system_grant(系统授权)取值含义参见:[表3]。 system_grant 未填值或填写了取值范围以外的值时,自动赋予默认值;不允许第三方应用填写 user_grant,填写后会自动赋予默认值。
availableScope 选填,权限限制范围。不填则表示此权限对所有应用开放。 字符串数组 signatureprivilegedrestricted 可参见。取值含义请见:[表4]。 填写取值范围以外的值时,权限限制范围不生效。由于第三方应用并不在 restricted 的范围内,很少会出现权限定义者不能访问自身定义的权限的情况,所以不允许三方应用填写restricted。
label 选填,权限的简短描述,若未填写,则使用到简短描述的地方由权限名取代。 字符串 自定义 需要多语种适配。
description 选填,权限的详细描述,若未填写,则使用到详细描述的地方由 label 取代。 字符串 自定义 需要多语种适配。

授予方式(grantMode) 说明 自定义权限是否可指定该级别 取值样例
system_grant 在“config.json”里面声明,安装后系统自动授予。 GET_NETWORK_INFO 、GET_WIFI_INFO
user_grant 在“config.json”里面声明,并在使用时动态申请,用户授权后才可使用。 否,如自定义则强制修改为 system_grant。 CAMERA、MICROPHONE

权限范围(availableScope) 说明 自定义权限是否可指定该级别 取值样例
restricted 需要开发者向华为申请后才能被使用的特殊权限。 ANSWER_CALL、READ_CALL_LOG、RECEIVE_SMS
signature 权限定义方和使用方的签名一致。需在“config.json”里面声明后,由权限管理模块负责签名校验一致后,可使用。 对应用(或 Ability)操作的系统接口上由系统定义权限以及应用自定义的权限。如:find某Ability,连接某Ability。
privileged 预置在系统版本中的特权应用可申请的权限。 SET_TIME、MANAGE_USER_STORAGE

访问权限控制

  • Ability的访问权限控制

在 config.json 中填写“abilities”到“permissions”字段,即只有拥有该权限的应用可访问此Ability。下面的例子表明只有拥有“ohos.permission.CAMERA”权限的应用可以访问此ability。

  "abilities": [{
          "name": ".MainAbility",
          "description": "$string:description_main_ability",
          "icon": "$media:hiworld.png",
          "label": "HiCamera",
          "launchType": "standard",
          "orientation": "portrait",
          "visible": false,
          "permissions": [
              "ohos.permission.CAMERA"
          ],
      }]
值说明 类型 取值范围 默认值 规则约束
permissions 选填,权限名称。用以表示此 ability 受哪个权限保护,即只有拥有此权限的应用可访问此 ability。 字符串 自定义 目前仅支持填写一个权限名,若填写多个权限名,仅第一个权限名称有效。

  • Ability 接口的访问权限控制

在 Ability 实现中,如需要对特定接口对调用者做访问控制,可在服务侧的接口实现中,主动通过 verifyCallingPermission、 verifyCallingOrSelfPermission 来检查访问者是否拥有所需要的权限。

  if (verifyCallingPermission("ohos.permission.CAMERA") != IBundleManager.PERMISSION_GRANTED) {
      // 调用者无权限,做错误处理
  }
      // 调用者权限校验通过,开始提供服务

API接口说明

接口原型 接口详细描述
public int verifyPermission(String permissionName, int pid, int uid) 接口功能:查询指定 PID、UID 的应用是否已被授予某权限输入参数:permissionName:权限名;pid:进程id;uid:uid 输出参数:无返回值: IBundleManager.PERMISSION_DENIED、IBundleManager.PERMISSION_GRANTED
public int verifyCallingPermission(String permissionName) 接口功能:查询 IPC 跨进程调用方的进程是否已被授予某权限输入参数:permissionName:权限名输出参数:无返回值: IBundleManager.PERMISSION_DENIED、IBundleManager.PERMISSION_GRANTED
public int verifySelfPermission(String permissionName) 接口功能:查询自身进程是否已被授予某权限输入参数:permissionName:权限名输出参数:无返回值: IBundleManager.PERMISSION_DENIED、IBundleManager.PERMISSION_GRANTED
public int verifyCallingOrSelfPermission(String permissionName) 接口功能:当有远端调用检查远端是否有权限,否则检查自身是否拥有权限输入参数:permissionName:权限名输出参数:无返回值: IBundleManager.PERMISSION_DENIED、IBundleManager.PERMISSION_GRANTED
public boolean canRequestPermission(String permissionName) 接口功能:向系统权限管理模块查询某权限是否不再弹框授权了输入参数:permissionName:权限名输出参数:无返回值:true 允许弹框,false 不允许弹框
void requestPermissionsFromUser (String[] permissions, int requestCode) 接口功能:向系统权限管理模块申请权限(接口可支持一次申请多个。若下一步操作涉及到多个敏感权限,可以这么用,其他情况建议不要这么用。因为弹框还是按权限组一个个去弹框,耗时比较长。用到哪个权限就去申请哪个)输入参数: permissionNames:权限名列表;requestCode: 请求应答会带回此编码以匹配本次申请的权限请求输出参数:无返回值:无
void onRequestPermissionsFromUserResult (int requestCode, String[] permissions, int[] grantResults) 接口功能:调用 requestPermissionsFromUser 后的应答接口输入参数:requestCode:requestPermission 中传入的requestCode;permissions:申请的权限名;grantResults:申请权限的结果输出参数:无返回值:无

动态申请权限开发步骤

  1. 在 config.json 文件中声明所需要的权限。

   {
       " reqPermissions": [{
           "name": "ohos.permission.CAMERA",
           "reason": "$string:permreason_camera",
           "usedScene": {
               "ability": ["com.mycamera.Ability", "com.mycamera.AbilityBackground"],
               "when": "always"}
           }, {
           ...
           }]
       }]
   }

  1. 使用 ohos.app.Context.verifySelfPermission 接口查询应用是否已被授予该权限。

  • 如果已被授予权限,可以结束权限申请流程。
  • 如果未被授予权限,继续执行下一步。

  1. 使用 canRequestPermission 查询是否可动态申请。

  • 如果不可动态申请,说明已被用户或系统永久禁止授权,可以结束权限申请流程。
  • 如果可动态申请,继续执行下一步。

  1. 使用 requestPermissionFromUser 动态申请权限,通过回调函数接受授予结果。

样例代码如下:

   if (verifySelfPermission("ohos.permission.CAMERA") != IBundleManager.PERMISSION_GRANTED) {
       // 应用未被授予权限
       if (canRequestPermission("ohos.permission.CAMERA")) {
           // 是否可以申请弹框授权(首次申请或者用户未选择禁止且不再提示)
           requestPermissionsFromUser(
                   new String[] { "ohos.permission.CAMERA" } , MY_PERMISSIONS_REQUEST_CAMERA);
       } else {
           // 显示应用需要权限的理由,提示用户进入设置授权
       }
   } else {
       // 权限已被授予
   }

    
   @override
   public void onRequestPermissionsFromUserResult (int requestCode, String[] permissions, int[] grantResults){
       switch (requestCode) {
           case MY_PERMISSIONS_REQUEST_CAMERA: {
               // 匹配requestPermissions的requestCode
               if (grantResults.length > 0
                   && grantResults[0] == IBundleManager.PERMISSION_GRANTED) {
                   // 权限被授予
                   // 注意:因时间差导致接口权限检查时有无权限,所以对那些因无权限而抛异常的接口进行异常捕获处理
               } else {
                   // 权限被拒绝
               }
               return;
           }
       }
   }
鸿蒙OS 权限概述
鸿蒙OS 权限应用权限列表
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

鸿蒙OS 开发

鸿蒙OS 术语

鸿蒙OS Java API参考

鸿蒙OS ohos.aafwk.ability

鸿蒙OS ohos.aafwk.abilityjet.activedata

鸿蒙OS ohos.aafwk.content

鸿蒙OS java.lang

鸿蒙OS java.Util

鸿蒙OS java.Util class

鸿蒙OS ohos.data.dataability

鸿蒙OS ohos.data.dataability class

鸿蒙OS ohos.agp.components

鸿蒙OS ohos.agp.components interface

鸿蒙OS ohos.agp.components class

鸿蒙OS ohos.global.configuration

鸿蒙OS java.io

鸿蒙OS ohos.data.resultset

鸿蒙OS ohos.data.resultset interface

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }