权限模型与M3设计原则

本章奠定课程的技术基础:从 Android 权限体系的演进出发,结合 Material Design 3(M3)的对话框设计理念,推导出权限对话框的 UX 指南。你后续所有实战代码和调试都依赖对这三层结构的清晰认知。

1.1 Android 权限体系

Android 权限模型经历了三个主要迭代:

阶段API 级别关键特征
安装时授权< 23安装时一次性授予,用户无法单独撤销
运行时权限23+危险权限需在运行时请求,用户可随时关闭
一次性权限30+仅当次有效,应用重新启动后需再次请求

权限按保护级别分类,核心区别如下:

级别示例权限授权方式对话框需求
NormalINTERNET系统自动授予无需对话框
DangerousCAMERA运行时用户决定必须使用系统或自定义对话框
SignatureBIND_NOTIFICATION_LISTENER_SERVICE仅同签名应用无需对话框
Special AccessMANAGE_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 指南

  1. 时机:只在用户主动触发了需要权限的功能后请求(如点击“拍照”按钮后才请求相机权限)。
  2. 理由:在系统对话框之前,先展示一个“教育性”的 M3 对话框,解释为什么需要该权限。
  3. 拒绝处理:用户拒绝后不要重复弹出,而是降级功能或显示“去设置中开启”的引导。
  4. 一次性权限:对 Android 11+ 标为 ONE_TIME 的权限,确保对话框明确说明“仅本次使用”。
  5. 无障碍:所有对话框元素都需设置 contentDescription,并且按钮焦点顺序符合阅读习惯。
常见陷阱:在 onRequestPermissionsResult 中直接再次调用请求会使应用进入死循环。必须在拒绝回调中判断是否勾选“不再询问”,如果是,则应引导至系统设置。
Android 权限模型与 M3 对话框设计关系 Android 权限体系 普通权限(Normal) 危险权限(Dangerous) 特殊权限(Special) 运行时请求流程 M3 对话框组件 用户决策:允许 / 拒绝 / 不再询问 M3 规范:标题 / 内容 / 按钮 / 形状

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 组件的状态机、布局和动画实现。你现在已清楚每个权限应何时显示什么样的对话框,这是整个组件的“需求规格书”。