在鸿蒙开发中,系统提供一种通用权限访问方式,允许应用访问系统资源(如通讯录)和系统能力(如摄像头、麦克风),以保护系统数据(包括用户个人数据)和功能,防止不当或恶意使用。

具体应用权限相关内容请参考官方文档:应用权限管控

完整应用权限列表请参考:应用权限列表

1. 应用权限授权方式

根据授权方式的不同,权限类型可分为 system_grant(系统授权)和 user_grant(用户授权)。

1.1. system_grant(系统授权)

system_grant 指的是系统授权类型,在该类型的权限许可下,应用被允许访问的数据不会涉及到用户或设备的敏感信息,应用被允许执行的操作对系统或者其他应用产生的影响可控。

    比如我们最常用的网络权限 "ohos.permission.INTERNET",他就是系统授权的一种。

    如果应用中申请了system_grant权限,系统会在用户安装应用时自动授予相应的权限。

    1.2. user_grant(用户授权)

    user_grant 指的是用户授权类型,在该类型的权限许可下,应用被允许访问的数据将会涉及到用户或设备的敏感信息,应用被允许执行的操作可能对系统或者其他应用产生严重的影响。

    比如:麦克风权限 "ohos.permission.MICROPHONE"相机权限 "ohos.permission.CAMERA"位置权限 "ohos.permission.LOCATION"等,属于用户授权类型。该类型权限需在安装包中申请,并在应用运行时通过弹窗请求用户授权。当用户手动允许授权后,应用才能获取相应权限,从而成功访问目标对象。

    2. 应用权限申请步骤(仅开放权限)

    应用在申请权限时,需在项目 module.json5 配置文件的 requestPermissions 标签中声明权限,并填写相应的属性。

    属性 含义 数据类型
    name 需要使用的权限名称。 字符串
    reason 申请权限的原因。 字符串
    usedScene

    权限使用的场景,该字段用于应用上架校验。包括abilities和when两个子项。

    - abilities:使用权限的UIAbility或者ExtensionAbility组件的名称。

    - when:调用时机。

    对象

    2.1. 系统授权

    该类权限申请时只需写权限名称即可,申请原因及使用场景可选填。以最常用的网络权限为例:

    // module.json5
    {
      "module": {
        // ....
        "requestPermissions": [
          {
            "name": "ohos.permission.INTERNET"
          }
        ],
        "pages": "$profile:main_pages",
        "abilities": [
          // ....
        ],
        "extensionAbilities": [
          // ....
        ]
      }
    }

    添加相应的权限后,点击右上角的 Sync Now 即可

    2.2. 用户授权

    该类型权限在申请时,需要在 requestPermissions 标签中填写完整属性,包括名称、申请原因、使用场景,而且还需要在应用动态运行时,使用 requestPermissionsFromUser( ) ,通过发送弹窗的方式请求用户授权。在用户手动允许授权后,应用才会真正获取相应权限,从而成功访问操作目标对象。

    但如果用户拒绝授权,可以通过 requestPermissionOnSetting( ) 直接拉起权限设置弹框,引导用户授权。示例代码如下:

    module.json5 文件⬇️

    "requestPermissions": [
      {
        "name": "ohos.permission.MICROPHONE",
        "reason": "$string:app_name",
        "usedScene": {
          "when": "inuse"
        }
      },
      {
        "name": "ohos.permission.INTERNET"
      },
      {
        "name": "ohos.permission.USE_BLUETOOTH"
      },
      {
        "name": "ohos.permission.KEEP_BACKGROUND_RUNNING"
      },
      {
        "name": "ohos.permission.CAMERA",
        "reason": "$string:app_name",
        "usedScene": {
          "when": "inuse"
        }
      },
      {
        "name": "ohos.permission.LOCATION",
        "reason": "$string:location_reason",
        "usedScene": {
          "when": "inuse"
        }
      },
      {
        "name": "ohos.permission.APPROXIMATELY_LOCATION",
        "reason": "$string:location_reason",
        "usedScene": {
          "when": "inuse"
        }
      }
    ],

    PermissionPlugin.ets 文件⬇️

    import { abilityAccessCtrl, Context, Permissions } from "@kit.AbilityKit";
    import { UIContext } from "@ohos.arkui.UIContext";
    
    // 上下文对象
    export const uiContext: UIContext = new UIContext()
    
    export class PermissionPlugin {
      // 申请权限
      async requestPermission(permissions: Array<Permissions>) {
        // 管理访问控制模块的实例
        const atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager()
        const res = await atManager.requestPermissionsFromUser(uiContext.getHostContext() as Context, permissions)
    
        // 判断所有权限是否授权成功
        const flag = res.authResults.every(item => item === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED)
    
        if (!flag) {
          permissions.forEach((item: Permissions, index: number) => {
            // 若未被允许的权限可通过该方法二次拉起权限设置弹框
            atManager.requestPermissionOnSetting(uiContext.getHostContext() as Context, [item])
          })
        }
      }
    }
    
    // 导出实例对象
    export const permissionPlugin = new PermissionPlugin()

    然后我们在 Index.ets 页面可以调用这个方法,并传入想要申请的权限名称:

    import { permissionPlugin } from '../utils/PermissionPlugin'
    
    @Entry
    @ComponentV2
    struct Index {
      build() {
        Column({ space: 20 }) {
          Button("申请权限")
            .width('90%')
            .onClick(() => permissionPlugin.requestPermission([
              "ohos.permission.CAMERA",  // 相机权限
              "ohos.permission.MICROPHONE",  // 麦克风权限
              "ohos.permission.LOCATION",  // 位置权限
              "ohos.permission.APPROXIMATELY_LOCATION"
            ]))
        }
        .height('100%')
        .width('100%')
      }
    }

    示例效果如下所示:

    由此可以看出,当用户拒绝授权某个权限时,系统会拉起半模态弹窗二次请求用户授权,如果此时用户再次拒绝,那么只能在系统设置中手动授权。


    该案例示例代码可通过链接获取:HarmonyOS_Permissions

    Logo

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

    更多推荐