Skip to content

权限声明流程

权限声明是应用获取权限的第一步,需要在 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. 权限声明字段详解

必填字段

字段类型说明
namestring权限名称,如 ohos.permission.CAMERA

可选字段

字段类型说明
reasonstring权限使用说明(引用字符串资源)
usedSceneobject使用场景配置

usedScene 子字段

字段类型说明
abilitiesstring[]可使用此权限的 Ability 列表
whenstring申请时机: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 配置格式和各字段含义。