3. 权限模型基础:权限分类与申请流程
权限管理,说白了就是系统给应用发的一张「通行证」。
我刚开始接触鸿蒙时,第一反应是:这玩意儿跟 Android 的权限有啥区别?后来踩了几个坑才明白——鸿蒙的权限模型,其实更细、更严,也更灵活。今天咱们就把它拆开揉碎了讲清楚。
3.1 权限分类:系统、应用、自定义
鸿蒙把权限分成了三大类。我个人习惯把它们比作「官方许可」「用户授权」「私人定制」。
3.1.1 系统权限
这类权限由系统预定义,普通应用拿不到。比如访问系统设置、修改网络配置、调用硬件底层接口等。说白了,只有系统级应用或系统服务才能申请。
特点:
- 定义在系统框架层
- 通常需要
signature等级 - 普通开发者基本不用操心
3.1.2 应用权限
这是咱们开发中最常打交道的。比如读取联系人、访问相册、使用摄像头等。鸿蒙把这些权限分成了几个等级,后面会细说。
我记得刚做鸿蒙适配时,有个同事直接把 Android 的权限声明搬过来用,结果应用死活跑不起来。嗯,鸿蒙的权限名称和 Android 不完全一样,得用 ohos.permission.xxx 这种格式。
3.1.3 自定义权限
这个就有点意思了。如果你的应用暴露了一些接口给其他应用调用,你可以自己定义一套权限来控制访问。
举个例子:你做了一个支付 SDK,其他应用想调用你的支付接口。你可以定义一个 com.example.payment.PAY 权限,只有声明了这个权限的应用才能调用。
// 在 config.json 或 module.json5 中声明
{
"permissions": [
{
"name": "com.example.payment.PAY",
"label": "支付权限",
"description": "允许应用调用支付接口",
"level": "dangerous"
}
]
}
3.2 权限等级:normal / dangerous / signature
权限等级决定了「申请流程有多麻烦」。鸿蒙分了三个等级,我一个个说。
| 等级 | 含义 | 申请方式 | 典型例子 |
|---|---|---|---|
| normal | 普通权限,风险低 | 声明即授权,无需弹窗 | 访问网络、读取设备信息 |
| dangerous | 危险权限,涉及隐私 | 需动态申请,用户弹窗确认 | 读取联系人、使用摄像头 |
| signature | 签名权限,系统级 | 仅同签名应用可获取 | 系统设置修改、硬件控制 |
normal 权限:说白了就是「你声明了,系统就给你」。比如网络访问权限,你只需要在配置文件中写上,系统安装时自动授予。
dangerous 权限:这个就得走动态申请流程了。用户得在弹窗里点「允许」才行。我曾经遇到过一个坑——用户拒绝了权限,应用直接崩溃了。后来我加了个判断:如果用户拒绝,就引导去设置里手动开启。
signature 权限:这个最严格。只有跟你用同一个签名证书签名的应用才能获取。说白了,这是系统给「自己人」用的权限。
3.3 权限申请流程
流程其实不复杂,但细节很多。我把它拆成三步:声明、申请、处理回调。
3.3.1 声明权限
在 module.json5 的 requestPermissions 字段里声明。注意,这里只声明你需要的权限,不是所有权限都要写。
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.CAMERA",
"reason": "用于扫码功能"
},
{
"name": "ohos.permission.READ_CONTACTS",
"reason": "用于导入联系人"
}
]
}
}
这里有个小细节:reason 字段是必填的。系统会在弹窗时显示这个原因,告诉用户「为什么你需要这个权限」。我建议写得诚恳一点,别写「用于优化体验」这种废话。
3.3.2 动态申请权限
对于 dangerous 权限,需要在代码里调用 API 申请。鸿蒙提供了 requestPermissionsFromUser 方法。
import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
let atManager = abilityAccessCtrl.createAtManager();
let permissions = ['ohos.permission.CAMERA'];
atManager.requestPermissionsFromUser(this.context, permissions).then((data) => {
// 申请结果
console.log('权限申请结果:' + JSON.stringify(data));
}).catch((err) => {
console.error('权限申请失败:' + JSON.stringify(err));
});
我个人习惯在申请前先检查一下权限状态。如果已经授权了,就别再弹窗了,用户体验会好很多。
3.3.3 处理授权结果
用户点击「允许」或「拒绝」后,系统会回调结果。你需要根据结果做相应的处理。
// 检查权限是否授予
if (data.authResults[0] === 0) {
// 权限已授予,执行操作
startCamera();
} else {
// 权限被拒绝,提示用户
showToast('需要相机权限才能扫码');
// 可选:跳转到设置页面
jumpToSettings();
}
3.4 小结
权限模型这块,说白了就是三件事:
- 分类:系统权限、应用权限、自定义权限
- 等级:normal(声明即得)、dangerous(动态申请)、signature(同签名才给)
- 流程:声明 → 申请 → 处理回调
你想想看,如果每个应用都能随便拿权限,那用户的隐私就成筛子了。鸿蒙这套机制,虽然开发时多写几行代码,但换来了用户的安全感。值不值?我觉得值。
下一章咱们聊聊权限组和权限校验的底层实现,到时候我会分享一个我在系统级应用开发中遇到的真实案例。