ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

B12_运行时权限与ActivityResult

B12_运行时权限与ActivityResult Android 基础补强 B12运行时权限与 Activity Result一次拒绝之后应用该做什么发布摘要以录音入口为例设计权限状态理解声明、申请、拒绝、解释和重新检查并把权限结果与实际功能分开。标签Android 权限、Activity Result、生命周期。“点按钮申请权限允许后开始录音”只覆盖了最顺利的一条路径。实际用户可能拒绝、退出对话框、去设置关闭权限也可能在系统回收进程后返回应用。如果代码把第一次授权结果永久存成 true下一次调用受保护 API 仍可能失败。本篇研究权限流程本身录音只是帮助确定边界的场景。对应《第一行代码》第 8 章运行时权限并延伸到第 16 章权限库封装思路Activity Result API 属于现代实现补充。本文不复制书中的权限库也不把一个权限按钮当成完整录音功能。代码未在用户工程编译运行。一、声明和授权分别解决什么Manifest 声明应用需要的能力运行时授权由系统和用户决定。Android 6.0API 23引入危险权限的运行时申请当前应用应按目标 SDK 和具体权限规则适配。普通权限与危险权限不是同一套交互不能对每个 Manifest 条目都弹申请框。运行时权限流程本例功能是应用自己使用麦克风Manifest 声明 RECORD_AUDIO。用户点击录音时才检查并申请不在冷启动时把尚未使用的能力全部请求一遍。若功能只是选一张图片应优先考虑系统选择器不能把“媒体相关”统一理解成需要读取整个媒体库。权限状态不要只有允许和不允许还应考虑解释中、申请中和拒绝后的可继续浏览状态。拒绝录音权限不能把文章列表锁死授权失败影响的是录音功能。二、用 Activity Result 让结果回到正确的宿主下面是 Compose 核心组件。需要androidx.activity:activity-compose、AndroidX Core、Material3rememberLauncherForActivityResult来自androidx.activity.compose合约来自androidx.activity.result.contract.ActivityResultContracts权限常量和包管理类型来自 Android 平台。示例假设最低 API 23 及以上。ComposablefunMicrophonePermissionButton(onGranted:()-Unit,onDenied:()-Unit){valcontextLocalContext.currentvalgrantedActionbyrememberUpdatedState(onGranted)valdeniedActionbyrememberUpdatedState(onDenied)vallauncherrememberLauncherForActivityResult(ActivityResultContracts.RequestPermission()){granted-if(granted)grantedAction()elsedeniedAction()}Button(onClick{valhasPermissionContextCompat.checkSelfPermission(context,Manifest.permission.RECORD_AUDIO)PackageManager.PERMISSION_GRANTEDif(hasPermission){grantedAction()}else{launcher.launch(Manifest.permission.RECORD_AUDIO)}}){Text(开始语音笔记)}}Compose runtime 导入需要Composable、getValue、rememberUpdatedState上下文来自androidx.compose.ui.platform.LocalContext按钮和文字来自 Material3权限检查来自androidx.core.content.ContextCompat。Manifest 在 application 外声明uses-permission android:nameandroid.permission.RECORD_AUDIO /。这个最小组件展示检查与结果处理解释弹窗应由宿主在需要时放在启动申请之前。第一步先用按钮和状态文字验证结果第二步加入为何需要权限的解释第三步再连接真正录音控制器第四步处理撤销权限或资源忙导致的实际调用失败。授权成功只代表可以尝试功能不保证设备麦克风一定可用。三、拒绝后不要自动循环弹窗shouldShowRequestPermissionRationale用于判断是否应该展示解释但返回 false 不能单独证明“永久拒绝”首次尚未申请时也可能是 false。应结合是否实际申请过、当前功能入口和系统结果设计提示不要写成一个神奇的永久拒绝判断函数。用户拒绝后可以继续浏览用页面内说明告知语音笔记暂不可用用户再次主动尝试时再按系统状态决定解释或设置引导。不要在拒绝回调里立即再次 launch这会让应用变成连续索取授权的循环。跳转设置也是用户选择不能未经交互反复拉走页面。系统支持一次性授权、闲置权限自动重置等机制时过去的允许不代表现在仍允许。每次执行相关功能前重新检查实际受保护操作仍需要处理权限被撤销的异常。权限使用建议四、Activity Result 不是所有状态的保险箱传统 Activity 中的 launcher 应在宿主创建时无条件注册不能等用户点击后才临时注册多个 launcher 的注册顺序应稳定。启动发生在合适生命周期阶段结果回调依赖系统与注册表恢复但应用自己的待处理业务信息仍要保存。Activity Result 官方说明例如拍照返回只有成功布尔值而照片 URI 是你在启动相机前创建的。如果进程重建后待处理 URI 丢失回调不会替你推导原来的输出地址。权限申请同理授权回来了不代表草稿标题、文章编号和目标动作全部自动恢复。封装权限工具时合理目标是减少重复检查、统一结果表达它不能绕过系统授权也不应该隐藏所有版本分支。第 16 章的价值在于学习封装职责而不是继续扩展一个万能回调直到调用者无法知道实际请求了什么。五、故障实验与预期在干净安装状态首次点击选择拒绝。预期文章功能正常录音入口显示可理解原因第二次主动点击时检验解释与系统行为不假定所有设备都会弹同样的对话框。允许后到系统设置撤销权限再回到应用点击录音。预期重新检查不继续使用旧缓存布尔值。需要真实启动录音时还应处理检查之后被撤销的边界异常避免把一次检查当作不可变承诺。最后在外部授权界面期间制造宿主重建检查回调和业务草稿。预期回调注册稳定恢复规则明确“不保留活动”只检验活动销毁路径不能当作所有进程死亡场景的替代。六、原创面试问答与追问对应题库的权限申请以下为独立整理。问权限声明了为什么还会失败答危险权限可能没有运行时授权也可能已撤销功能还可能受其他运行条件限制。追问检查一次够吗每次受保护操作前应重新评估并处理实际失败。问rationale 返回 false 表示永久拒绝吗答不能这样单独判断首次申请前也可能为 false。追问应用应怎样提示结合实际交互历史提供解释和用户主动选择的设置入口。问Activity Result 能恢复所有拍照状态吗答不能它管理请求结果分发待处理 URI 等业务状态仍由应用保存。追问为什么回调有值仍可能找不到照片启动前的输出标识可能已经丢失。七、练习与验收建议安排在 D19 后的一次九十分钟基础训练先画权限状态图再实现允许、拒绝、撤销、宿主重建四条路径。不要一次请求麦克风、相机和存储把一个功能的规则先讲清楚。验收交付是 Manifest 与权限用途说明、四条真实操作记录、拒绝后的界面以及“检查授权”和“执行录音”分层的代码。没有接入录音控制器时博客应标明只完成权限流程实验。
返回列表