3. 权限分类与映射表
Android 运行时权限体系将权限划分为三类:正常权限(Normal Permissions)、危险权限(Dangerous Permissions) 和 特殊权限(Special Permissions)。准确理解三者的定义、清单及 API 级别对应关系,是设计 Runtime 权限申请流程的前提条件。
3.1 适用场景
- 新功能开发阶段,需要确定目标权限类型并选取正确的申请策略。
- 遗留项目权限适配(如 targetSdkVersion 升级至 23+)时,对比现有权限与最新分类。
- 代码审查或合规审计时,验证权限声明与用户隐私保护要求是否一致。
3.2 前置条件
- 已配置 Android SDK 环境,了解
AndroidManifest.xml中<uses-permission>标签的基本用法。 - 明确项目当前
compileSdk、minSdk和targetSdk版本。 - 获得 Android 官方权限参考文档(或本课程提供的汇总表)。
3.3 操作步骤
步骤 1:识别权限类型定义
| 类型 | 定义 | 系统行为 | API 版本 |
|---|---|---|---|
| 正常权限 | 不直接涉及用户隐私,不会造成严重安全风险的系统功能调用,如网络状态、蓝牙连接。 | 安装时自动授权,无需运行时弹窗。 | API 1+ |
| 危险权限 | 涉及用户隐私数据(通讯录、位置、相机等),必须通过运行时弹窗显式获取用户同意。 | 需要调用 requestPermissions() 并处理回调。 |
API 23+ 引入运行时机制,但权限本身从早期版本即存在 |
| 特殊权限 | 系统级开关控制的功能(如“在其他应用上层显示”“无障碍服务”),需要额外跳转系统设置页面授予。 | 使用 Settings.ACTION_MANAGE_OVERLAY_PERMISSION 等 Intent 引导用户手动打开。 |
API 23+ 逐步引入 |
步骤 2:对照危险权限分组清单(核心映射表)
下表列出截至 Android 14 的主要危险权限组及对应权限标识。同一组中只要授权一项,组内其他权限即自动允许。
| 权限组 | 权限名 | 引入 API | 备注 |
|---|---|---|---|
| CALENDAR | READ_CALENDAR | API 1 | 日历读写 |
| WRITE_CALENDAR | API 1 | ||
| (组内无新增) | – | ||
| CAMERA | CAMERA | API 1 | 相机使用 |
| (组内仅此项) | – | ||
| CONTACTS | READ_CONTACTS | API 1 | 通讯录读写 |
| WRITE_CONTACTS | API 1 | ||
| GET_ACCOUNTS | API 5 | ||
| LOCATION | ACCESS_FINE_LOCATION | API 1 | GPS / 网络位置 |
| ACCESS_COARSE_LOCATION | API 1 | ||
| (Android 10+ 拆分) | ACCESS_BACKGROUND_LOCATION | API 29 | 后台位置特殊处理 |
| PHONE | READ_PHONE_STATE | API 1 | 电话/IMEI等 |
| CALL_PHONE | API 1 | ||
| READ_CALL_LOG / WRITE_CALL_LOG / ADD_VOICEMAIL / USE_SIP | API 16+ | 子项较多 | |
| STORAGE | READ_EXTERNAL_STORAGE / WRITE_EXTERNAL_STORAGE | API 1 (但运行时自 API 23) | Android 10+ 被细化,建议改用 MediaStore / SAF |
| SMS | SEND_SMS / RECEIVE_SMS / READ_SMS / RECEIVE_WAP_PUSH / RECEIVE_MMS | API 1 | 短信相关 |
| (组内五项) | – | ||
| BODY_SENSORS | BODY_SENSORS | API 20 | 心率等传感器 |
| BODY_SENSORS_BACKGROUND | API 33 | 后台身体传感器 |
步骤 3:特殊权限清单及操作方式
| 特殊权限 | 权限名 (常量) | 引导 Action | 检查方法 | 引入 API |
|---|---|---|---|---|
| 浮动窗口 | SYSTEM_ALERT_WINDOW | Settings.ACTION_MANAGE_OVERLAY_PERMISSION |
Settings.canDrawOverlays(context) |
API 23 |
| 修改系统设置 | WRITE_SETTINGS | Settings.ACTION_MANAGE_WRITE_SETTINGS |
Settings.System.canWrite(context) |
API 23 |
| 无障碍服务 | BIND_ACCESSIBILITY_SERVICE | Settings.ACTION_ACCESSIBILITY_SETTINGS |
检查已启用的服务列表 | API 18+ |
| 通知监听 | BIND_NOTIFICATION_LISTENER_SERVICE | Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS |
检查已激活监听器 | API 18+ |
| 安装未知来源应用 | REQUEST_INSTALL_PACKAGES | Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES |
PackageManager.canRequestPackageInstalls() |
API 26 |
| 后台位置(部分视为特殊) | ACCESS_BACKGROUND_LOCATION | 与前台位置一同申请,或通过位置设置页面 | checkSelfPermission 后单独处理 |
API 29 |
关键提醒: 特殊权限不能通过
requestPermissions() 弹窗申请,必须使用 Intent 跳转到系统设置页面,并监听 onActivityResult 判断是否成功。
3.4 输入输出物
| 类型 | 输入物 | 输出物 |
|---|---|---|
| 文档 | Android 官方权限清单、项目需求文档 | 本章提供的分类对照表(可直接作为团队通用参考资料) |
| 代码 | AndroidManifest.xml 中的 <uses-permission> 声明 | 权限类型标注清单,用于后续流程设计 |
3.5 责任边界
- Android 开发工程师: 负责对照表格将项目所用权限划分类别,并确保
targetSdk对应的行为正确。 - 技术 PM / 架构师: 审核权限分类是否覆盖所有功能,是否存在过度申请。
- QA 测试: 验证不同 API 版本下权限行为是否与分类预期一致(如 Android 10+ 后台位置需单独处理)。
3.6 记录材料
- 项目权限登记表:建议以 CSV 或 Markdown 格式记录“权限名 → 类型 → 引入 API → 申请方式”。
- 版本变更记录:当
compileSdk升级时,同步更新该表。
# 示例权限登记表片段
| 权限名 | 类型 | API 引入 | 申请方式 |
|--------------------------------|----------|----------|------------------------|
| android.permission.CAMERA | dangerous| API 1 | requestPermissions() |
| android.permission.SYSTEM_ALERT_WINDOW | special | API 23 | Settings intent |
| android.permission.INTERNET | normal | API 1 | 自动授权 |
3.7 异常处理
- 权限分类混淆: 例如将
SYSTEM_ALERT_WINDOW当作危险权限使用弹窗申请,导致始终被拒绝。解决方案:对照特殊权限清单及时修正代码逻辑。 - API 版本兼容: 部分权限(如
ACCESS_BACKGROUND_LOCATION)仅在 API 29+ 存在,低版本机型需做条件判断,避免 NoSuchMethodError。 - 分组误解: 误以为同组权限只要申请一项即可完全替代其他项。实际上只有同一组的权限才共享授权,跨组必须分别申请。
避坑指南: Android 14(API 34)新增
NEARBY_WIFI_DEVICES 属于危险权限但被归入 NEARBY_DEVICES 组,不再与 ACCESS_FINE_LOCATION 合并。升级时务必对照最新官方分组。
3.8 验收标准
- 项目所有声明的权限均能在本章表格中找到对应分类。
- 对特殊权限,已正确实现“跳转设置 → 返回检查”的引导逻辑。
- 对不同 API 版本(特别是 targetSdk 23+),危险权限的运行时申请路径已设计到位。
- 团队内可借助记录的权限登记表快速定位后续流程中的申请方式。