系列:HarmonyOS 开发入门 · 11

权限问题最怕“只记住一个 requestPermissionsFromUser()”。

真正完整的流程应该是:先声明 -> 再检查 -> 需要时请求 -> 处理拒绝 -> 决定是否引导二次授权。

1. 先在 module.json5 声明

例如申请相机权限:

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

具体字段要根据权限类型和当前 API 要求配置。

如果配置文件根本没声明,代码里再怎么申请都不会变魔术。

2. 创建 AtManager

import { abilityAccessCtrl, common, Permissions } from '@kit.AbilityKit'
import { BusinessError } from '@kit.BasicServicesKit'

const atManager = abilityAccessCtrl.createAtManager()

获取当前 UIAbilityContext:

const context = this.getUIContext().getHostContext() as common.UIAbilityContext

3. 先检查状态

新 API 下可以查询自身权限状态,不要每次按钮一点击就无脑申请。

思路是:

已授权 -> 直接执行业务
未确定 -> 发起首次申请
已拒绝 -> 根据场景考虑设置页/二次授权

权限请求应该由用户真实操作触发,比如用户点“拍照”时再申请相机权限,而不是 App 一启动就连续弹五个权限框。

4. 首次请求

const permissions: Array<Permissions> = ['ohos.permission.CAMERA']

atManager.requestPermissionsFromUser(context, permissions)
  .then((result) => {
    console.info(`permissions: ${result.permissions}`)
    console.info(`authResults: ${result.authResults}`)
  })
  .catch((error: BusinessError) => {
    console.error(`${error.code}: ${error.message}`)
  })

注意要检查 authResults,不是 Promise 成功就代表用户一定授权。

5. 为什么用户拒绝后,第二次不再弹

这是很多人真机调试时最容易疑惑的地方。

系统会限制重复打扰用户。用户拒绝过以后,再次直接调用首次请求接口,不一定会再次弹出同样授权框。

这时可以根据权限状态和业务场景,使用系统提供的二次授权/设置能力,或者引导用户进入应用权限设置。

不要写一个循环反复弹用户。

6. 一个更像真实项目的封装

export class PermissionHelper {
  static async requestCamera(context: common.UIAbilityContext): Promise<boolean> {
    const manager = abilityAccessCtrl.createAtManager()
    const permissions: Array<Permissions> = ['ohos.permission.CAMERA']

    try {
      const result = await manager.requestPermissionsFromUser(context, permissions)
      return result.authResults.length > 0 && result.authResults[0] === 0
    } catch (error) {
      const err = error as BusinessError
      console.error(`camera permission failed: ${err.code}, ${err.message}`)
      return false
    }
  }
}

后续再把“检查状态”“二次授权”补进去。

7. 能不用权限时,优先考虑系统 Picker

这是一个很实用的思路。

例如用户只是主动选择一张图片,系统 PhotoViewPicker 可以让用户自己选资源,并通过临时授权返回 URI,不一定需要你的 App 先申请读取整个图库的权限。

同样,CameraPicker 也适合某些简单拍照场景,并且能减少自己管理相机权限的成本。

能缩小权限范围,通常比“先申请再说”更好。

8. 权限文案别写成废话

例如:

需要相机权限

虽然没错,但用户不知道为什么。

更好的说明是:

用于拍摄并设置个人头像

权限申请越贴近当前操作,用户越容易理解。

总结

权限开发记住完整链路:

module.json5 声明
↓
查询权限状态
↓
业务触发时请求
↓
处理授权 / 拒绝
↓
必要时二次授权或设置页

下一篇就用系统 Picker 做一个非常常见的场景:从相册选择图片、调用系统相机拍照,以及把生成内容保存到用户媒体库。

Logo

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

更多推荐