Appearance
权限声明流程
权限声明是应用获取权限的第一步,需要在 module.json5 中正确配置。
1. module.json5 结构
json5
{
"module": {
"name": "entry",
"type": "entry",
"srcEntry": "./ets/entryability/EntryAbility.ts",
"description": "$string:module_desc",
"mainElement": "EntryElement",
"deviceTypes": ["phone", "tablet"],
"deliveryWithInstall": true,
"installationFree": false,
"pages": "$profile:main_pages",
// 权限声明区域
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
},
{
"name": "ohos.permission.CAMERA",
"reason": "$string:camera_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
}
]
}
}2. 权限声明字段详解
必填字段
| 字段 | 类型 | 说明 |
|---|---|---|
name | string | 权限名称,如 ohos.permission.CAMERA |
可选字段
| 字段 | 类型 | 说明 |
|---|---|---|
reason | string | 权限使用说明(引用字符串资源) |
usedScene | object | 使用场景配置 |
usedScene 子字段
| 字段 | 类型 | 说明 |
|---|---|---|
abilities | string[] | 可使用此权限的 Ability 列表 |
when | string | 申请时机:inuse/always/foreground |
3. 完整声明示例
相机应用权限声明
json5
{
"module": {
"name": "camera_app",
"requestPermissions": [
// 网络权限(normal)
{
"name": "ohos.permission.INTERNET",
"reason": "$string:internet_reason"
},
// 相机权限(user_granted)
{
"name": "ohos.permission.CAMERA",
"reason": "$string:camera_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
},
// 存储权限(user_granted)
{
"name": "ohos.permission.READ_MEDIA",
"reason": "$string:read_media_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
},
{
"name": "ohos.permission.WRITE_MEDIA",
"reason": "$string:write_media_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
},
// 麦克风权限(user_granted,用于录像)
{
"name": "ohos.permission.MICROPHONE",
"reason": "$string:microphone_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
}
]
}
}字符串资源定义
json5
// resources/base/element/string.json
{
"string": [
{
"name": "camera_reason",
"value": "需要访问相机以进行拍照和录像"
},
{
"name": "internet_reason",
"value": "需要访问网络以下载和上传数据"
},
{
"name": "read_media_reason",
"value": "需要读取相册以选择照片"
},
{
"name": "write_media_reason",
"value": "需要保存照片到相册"
},
{
"name": "microphone_reason",
"value": "需要访问麦克风以录制视频声音"
}
]
}4. 权限声明最佳实践
1. 最小化原则
json5
// ✅ 推荐:只声明必要的权限
{
"requestPermissions": [
{ "name": "ohos.permission.CAMERA" }
]
}
// ❌ 不推荐:声明未使用的权限
{
"requestPermissions": [
{ "name": "ohos.permission.CAMERA" },
{ "name": "ohos.permission.LOCATION" }, // 未使用
{ "name": "ohos.permission.CONTACTS" } // 未使用
]
}2. 清晰的 reason 描述
json5
// ✅ 推荐:具体说明用途
{
"name": "ohos.permission.CAMERA",
"reason": "$string:camera_reason" // "用于扫描二维码登录"
}
// ❌ 不推荐:模糊描述
{
"name": "ohos.permission.CAMERA",
"reason": "$string:camera_reason" // "需要使用相机"
}3. 正确的 usedScene 配置
json5
// ✅ 推荐:精确指定 Ability
{
"name": "ohos.permission.CAMERA",
"usedScene": {
"abilities": ["CameraAbility"],
"when": "inuse"
}
}
// ❌ 不推荐:过度授权
{
"name": "ohos.permission.CAMERA",
"usedScene": {
"abilities": ["*"], // 所有 Ability
"when": "always" // 始终可用
}
}5. 权限声明验证
编译期检查
bash
# 构建时会检查权限声明
hvigorw assembleHap
# 如果有未声明但使用的权限,会有警告运行时检查
typescript
import { accessControl } from '@kit.ArkKit';
async function verifyPermissionDeclared(permissionName: string): Promise<void> {
try {
let result = await accessControl.verifyAccessToken({
permissionName: permissionName,
tokenId: await getTokenId()
});
if (result === 0) {
console.log('权限已授予');
} else if (result === 3) {
console.log('权限未授予,需要申请');
} else {
console.log('权限可能未声明');
}
} catch (error) {
console.error('权限检查失败:', error);
}
}6. 常见错误
错误 1:忘记声明权限
typescript
// ❌ 代码中使用相机,但未在 module.json5 中声明
// 运行时会抛出权限异常错误 2:reason 描述不清
json5
// ❌ 描述太模糊
{
"reason": "需要使用此权限"
}
// ✅ 描述具体用途
{
"reason": "需要访问您的位置以提供附近服务推荐"
}错误 3:usedScene 配置错误
json5
// ❌ abilities 列表为空
{
"usedScene": {
"abilities": [], // 错误:至少需要一个 Ability
"when": "inuse"
}
}7. 面试高频问题
Q1: 权限声明在哪里配置?
答:在 module.json5 文件的 requestPermissions 数组中配置。
Q2: reason 字段的作用?
答:reason 用于向用户说明申请此权限的原因,会在运行时授权弹窗中显示。
Q3: usedScene 的 when 有哪些值?
答:inuse(使用时)、always(始终)、foreground(仅前台)。推荐使用 inuse。
面试提示:权限声明流程是基础考点,需掌握 module.json5 配置格式和各字段含义。