权限模型与M3设计原则
本章奠定课程的技术基础:从 Android 权限体系的演进出发,结合 Material Design 3(M3)的对话框设计理念,推导出权限对话框的 UX 指南。你后续所有实战代码和调试都依赖对这三层结构的清晰认知。
1.1 Android 权限体系
Android 权限模型经历了三个主要迭代:
| 阶段 | API 级别 | 关键特征 |
|---|---|---|
| 安装时授权 | < 23 | 安装时一次性授予,用户无法单独撤销 |
| 运行时权限 | 23+ | 危险权限需在运行时请求,用户可随时关闭 |
| 一次性权限 | 30+ | 仅当次有效,应用重新启动后需再次请求 |
权限按保护级别分类,核心区别如下:
| 级别 | 示例权限 | 授权方式 | 对话框需求 |
|---|---|---|---|
| Normal | INTERNET | 系统自动授予 | 无需对话框 |
| Dangerous | CAMERA | 运行时用户决定 | 必须使用系统或自定义对话框 |
| Signature | BIND_NOTIFICATION_LISTENER_SERVICE | 仅同签名应用 | 无需对话框 |
| Special Access | MANAGE_EXTERNAL_STORAGE | 系统设置中授予 | 通常引导用户跳转设置 |
实战注意:在 Android 14(API 34)中,系统对后台权限、通知权限和媒体权限实施了更严格的运行时流程,本章的设计原则对这些新增限制同样适用。
1.2 Material Design 3 对话框设计理念
M3 对话框遵循“响应式、适应性强、色彩分层”的原则,权限对话框应满足以下 M3 规范:
| 组件 | M3 规范要求 | 权限对话框中的应用 |
|---|---|---|
| 标题 | 16sp Medium,单行截断 | 权限名称(如“相机权限”) |
| 内容 | 14sp Body,最多三行 | 权限用途与隐私说明 |
| 按钮 | TextButton(否定)/ FilledButton(肯定) | “拒绝”和“允许” |
| 图标 | 40dp 圆形,使用 M3 色彩容器 | 使用对应权限的 Material 图标 |
| 形状 | Corner radius 28dp(全圆角) | 对话框容器圆角 |
M3 强调“对话框不应是唯一获取权限的方式”,你应当提供设置入口或逐步引导,仅在真正需要时弹出对话框。
1.3 权限对话框的 UX 指南
- 时机:只在用户主动触发了需要权限的功能后请求(如点击“拍照”按钮后才请求相机权限)。
- 理由:在系统对话框之前,先展示一个“教育性”的 M3 对话框,解释为什么需要该权限。
- 拒绝处理:用户拒绝后不要重复弹出,而是降级功能或显示“去设置中开启”的引导。
- 一次性权限:对 Android 11+ 标为
ONE_TIME的权限,确保对话框明确说明“仅本次使用”。 - 无障碍:所有对话框元素都需设置
contentDescription,并且按钮焦点顺序符合阅读习惯。
常见陷阱:在
onRequestPermissionsResult 中直接再次调用请求会使应用进入死循环。必须在拒绝回调中判断是否勾选“不再询问”,如果是,则应引导至系统设置。
1.4 代码示例:基础权限声明与运行时检查
以下是在 AndroidManifest.xml 中声明相机权限,并在 Kotlin 中检查权限的典型代码:
<manifest ...>
<uses-permission android:name="android.permission.CAMERA"
android:maxSdkVersion="32" />
<application ...>
...
</application>
</manifest>
// 检查权限是否已授予
if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA)
== PackageManager.PERMISSION_GRANTED) {
// 已有权限,直接使用相机
} else {
// 需要请求权限,后续章节将使用 M3 对话框包装请求
showPermissionRationale()
}
性能要点:
checkSelfPermission 是轻量调用,应在主线程直接使用,不要放到后台协程;权限请求结果回调必须在 Activity 或 Fragment 的 onRequestPermissionsResult 中处理,不要依赖生命周期外调用。
本章所阐述的权限模型与 M3 设计原则,将在后续课程中直接映射为 PermissionDialog 组件的状态机、布局和动画实现。你现在已清楚每个权限应何时显示什么样的对话框,这是整个组件的“需求规格书”。