Android 运行时权限设计与兼容
Android 运行时权限设计与兼容
运行时权限不仅是调用一次系统弹窗。不同系统版本会调整权限粒度,用户可能拒绝、仅允许一次、选择部分内容,或者在系统设置中撤销权限。正确设计应以功能能力为中心,按使用时机请求,并为每种明确结果提供可理解的后续路径。
一、先判断是否真的需要权限
权限请求越少,用户决策成本和合规风险越低。开发前可以确认:
- 是否有系统选择器可以完成同一目标。
- 是否只需访问用户主动选择的单个文件。
- 是否可以使用不需要敏感权限的项目现有组件。
- 功能是否能在没有权限时降级。
不要为了未来可能使用而在首次启动集中请求权限。
二、在功能触发时解释用途
用户点击拍照、定位或通知功能时,再结合当前场景说明用途,通常比无上下文弹窗更容易理解。说明应包含权限用于什么、拒绝后哪些功能受影响,不应通过强制或误导文案诱导授权。
系统弹窗由系统控制,应用自己的说明页不能冒充授权结果。
三、使用项目统一权限入口
基于 Activity Result 的权限请求可以把注册与回调集中管理:
private val cameraPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { granted ->
if (granted) {
openCameraFeature()
} else {
renderCameraUnavailable()
}
}
该能力由 AndroidX 提供,实际项目应使用已有封装,并确认依赖版本与最低兼容范围一致。
请求前先检查当前权限状态,已经授权时直接进入功能:
fun startCamera() {
val granted = ContextCompat.checkSelfPermission(
requireContext(),
Manifest.permission.CAMERA
) == PackageManager.PERMISSION_GRANTED
if (granted) {
openCameraFeature()
} else {
cameraPermissionLauncher.launch(Manifest.permission.CAMERA)
}
}
四、不要只保存上一次授权结果
用户可以在系统设置中修改权限,系统也可能重置长期未使用应用的授权。进入功能前应查询系统当前状态,而不是依赖本地布尔值。
本地可以记录“是否已经展示过业务说明”等产品状态,但不能代替系统权限事实。
五、处理拒绝和不再询问
一次拒绝后,可以在用户再次触发功能时解释原因并允许重试。系统不再展示弹窗时,应用可以提供进入设置的明确入口,但不应循环弹窗阻塞其他功能。
是否显示权限理由可以参考系统提供的判断能力,但它不能单独精确区分所有历史状态。界面策略应结合本次操作和项目记录设计,不需要猜测超出系统可知范围的信息。
六、适配版本差异
媒体、通知和附近设备等权限在不同系统版本可能拆分。请求前要根据当前系统和项目最低版本选择真实存在的权限集合。
fun requiredMediaPermissions(): Array<String> {
return if (Build.VERSION.SDK_INT >= projectMediaPermissionVersion) {
arrayOf(currentImagePermission)
} else {
arrayOf(legacyStoragePermission)
}
}
示例中的版本与权限常量应由项目兼容层提供。业务页面不应散落多个版本判断,更不能引用最低兼容版本不支持的 API 而不加保护。
七、允许部分授权结果
批量请求多个权限时,结果可能部分成功。不要使用“全部成功或全部失败”的单一布尔值,应逐项判断功能实际需要的能力。
例如图片选择和拍照可以是两个独立入口。相机权限被拒绝时,仍可保留不依赖相机的选择方式。
八、权限与业务状态分离
拥有系统权限不代表业务条件满足。定位权限已授予时,定位服务仍可能关闭;通知权限存在时,某个业务订阅可能未开启。
可以把最终能力建模为:
sealed interface LocationCapability {
data object Available : LocationCapability
data object PermissionRequired : LocationCapability
data object ServiceDisabled : LocationCapability
data object Restricted : LocationCapability
}
界面根据能力状态提供对应动作,比直接展示系统权限值更贴近用户目标。
九、关注隐私与日志
授权结果、定位和媒体元数据不应在日志中完整输出。权限说明文案、隐私声明和实际使用行为必须一致。功能停止使用敏感能力后,应及时释放监听和资源。
十、测试权限矩阵
至少验证:
- 首次请求并允许。
- 首次拒绝后再次触发。
- 不再询问后的设置入口。
- 仅允许一次或部分授权。
- 系统设置中撤销后重新进入。
- 不同系统版本的权限集合。
- 页面旋转或重建时不重复弹窗。
总结
运行时权限设计应围绕用户触发的功能能力。优先减少权限,在合适时机请求,每次使用前查询真实状态,并通过兼容层处理版本差异。拒绝、部分授权和设置撤销都是正常路径,页面应提供清晰而不过度打扰的后续操作。
- 点赞
- 收藏
- 关注作者
评论(0)