【免费下载链接】android-RuntimePermissions
This sample has been deprecated/archived. Check this repo for related samples:
⚠️ 提示:该示例项目已被 Google 归档(只读、不再维护),但其权限申请的核心设计模式至今仍是 Android 开发的标准参考。
android-RuntimePermissions 是 Android 官方出品的运行时权限(Runtime Permissions)示例项目。它用一个极简的 Demo 演示了两条主线:如何一次性批量申请多个权限,以及在 onRequestPermissionsResult 回调中如何校验整批权限是否全部被用户授予。其中PermissionUtil.verifyPermissions的"全量校验"设计,是批量权限处理最值得学习的部分。
一、这个示例解决什么问题
从 Android 6.0(API 23)开始,CAMERA、READ_CONTACTS等"危险权限"不再随安装自动授予,必须在运行时动态申请。批量申请场景(一次要多个权限)有两个典型难点:
| 场景 | 申请方式 | 回调校验方式 |
|---|---|---|
| 单个权限(示例中相机) | 传 1 个元素的数组 +REQUEST_CAMERA | 直接判断grantResults[0] |
| 批量权限(示例中联系人读写) | 传多个权限数组 +REQUEST_CONTACTS | 用PermissionUtil.verifyPermissions遍历校验 |
示例的权限声明位于 AndroidManifest.xml:相机权限普通声明,联系人权限使用uses-permission-sdk-23标记为"仅 M 及以上才请求"的可选权限——这是批量申请前的标准做法。
二、批量申请的完整流程:四步走
核心实现在 MainActivity.java,流程可拆为四步:
- 预检查:点击按钮后先用
ActivityCompat.checkSelfPermission确认权限是否已授予,已授予则直接展示功能,避免反复弹窗打扰用户; - 解释用途:若用户之前拒绝过,调用
shouldShowRequestPermissionRationale判断是否需要用 Snackbar 先解释"为什么需要这个权限",解释完再由用户主动触发申请; - 批量申请:把
READ_CONTACTS和WRITE_CONTACTS组成数组PERMISSIONS_CONTACT,连同请求 IDREQUEST_CONTACTS一起交给ActivityCompat.requestPermissions发起申请——一次弹窗、多个权限; - 回调校验:在
onRequestPermissionsResult中按requestCode分流,批量场景调用PermissionUtil.verifyPermissions(grantResults)做整体验证。
💡 关键设计:requestCode(示例中REQUEST_CAMERA = 0、REQUEST_CONTACTS = 1)是区分"哪一次申请的结果回来了"的唯一依据,这是新手最常踩的坑。
三、PermissionUtil.verifyPermissions:批量校验的核心设计
工具类位于 PermissionUtil.java,全部逻辑只有十几行:
public static boolean verifyPermissions(int[] grantResults) { if (grantResults.length < 1) { return false; } for (int result : grantResults) { if (result != PackageManager.PERMISSION_GRANTED) { return false; } } return true; }三点设计值得借鉴:
- 全量通过才算成功:只要有一个权限不是
PERMISSION_GRANTED就整体返回false。对"读+写联系人"这种功能而言,缺一半权限功能无法完整使用,"部分授予"按失败处理是更稳妥的产品决策; - 防御性判空:先检查
grantResults.length < 1,避免空数组被误判为"全部授予"; - 与系统 API 对齐:返回值语义直接对应
Activity.onRequestPermissionsResult的grantResults参数,Javadoc 中用@see明确关联,降低理解成本。
四、onRequestPermissionsResult:三参数回调如何分流
回调签名(见 MainActivity.java 回调实现):
onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)requestCode:区分是哪次申请(相机 or 联系人);permissions:本次申请的权限列表,可用于日志或精细提示;grantResults:与permissions一一对应的每个权限的授予结果,这才是校验重点。
分流后的处理差异一目了然:相机场景只需grantResults.length == 1 && grantResults[0] == PERMISSION_GRANTED;联系人场景则整体交给PermissionUtil.verifyPermissions,通过后弹出 Snackbar 提示"权限已授予",否则提示"Permissions were not granted."。两条分支互不干扰,这正是"用 requestCode 分流 + 通用工具类校验"架构的价值。
五、Kotlin 版实现与一个隐藏的"坑"
项目附带完整的 Kotlin 重写版,位于 kotlinApp/app/src/main/java/com/example/android/system/runtimepermissions/MainActivity.kt。它把常用 API 封装成了扩展函数(如batchRequestPermissions、isPermissionGranted,见 AppCompatActivityExts.kt),回调校验则使用了 CollectionsExts.kt 中的扩展:
fun IntArray.containsOnly(num: Int): Boolean = filter { it == num }.isNotEmpty()⚠️避坑提醒:从方法名看它应表示"全部元素都等于 num",但实现是"过滤后非空",即只要有一个元素等于 num 就返回 true。这意味着用户只授予READ_CONTACTS而拒绝WRITE_CONTACTS时,该判断也会放行——与 Java 版verifyPermissions的"全部授予"语义不一致。若你在自己的项目中参考这套写法,请改为all { it == num }之类的严格校验。
六、批量权限申请:最佳实践清单
| 步骤 | 要点 |
|---|---|
| ① 声明 | 所有权限先在 AndroidManifest.xml 中声明 |
| ② 预检查 | checkSelfPermission已授予则跳过申请 |
| ③ 解释 | shouldShowRequestPermissionRationale判断是否需要二次说明 |
| ④ 申请 | 一次requestPermissions传入权限数组 + 唯一requestCode |
| ⑤ 校验 | 回调中按requestCode分流,批量结果用"全量通过"策略(参考PermissionUtil) |
七、示例文件导航
- 权限工具类:Application/src/main/java/com/example/android/system/runtimepermissions/PermissionUtil.java
- 主 Activity(申请与回调):Application/src/main/java/com/example/android/system/runtimepermissions/MainActivity.java
- 相机单权限场景:CameraPreviewFragment.java
- 联系人批量权限场景:ContactsFragment.java
- Kotlin 版扩展函数:extensions/ 目录
- 项目说明:README.md
获取示例代码
git clone https://gitcode.com/gh_mirrors/and/android-RuntimePermissions克隆后用 Android Studio 打开Application(Java 版)或kotlinApp(Kotlin 版)模块即可运行,在 Android 6.0 及以上设备上点击 "Show and add contacts" 按钮,即可完整体验多权限批量申请与回调校验的全过程。
【免费下载链接】android-RuntimePermissions
This sample has been deprecated/archived. Check this repo for related samples:
相关推荐
GoGoGo权限动态申请:onRequestPermissionsResult实现与用户引导
GoGoGo权限动态申请:onRequestPermissionsResult实现与用户引导 一、Android权限机制与定位类应用的特殊性 Android权限
移动开发AllLive完全指南:如何一站式获取四大直播平台实时弹幕与直播信息
AllLive完全指南:如何一站式获取四大直播平台实时弹幕与直播信息 想要同时观看虎牙、斗鱼、哔哩哔哩和抖音四大直播平台的精彩内容吗?AllLive正是您需要的
Apache Pulsar 多 Topic 权限批量授权与回收:PIP-383 设计与实现深度解析
Apache Pulsar 多 Topic 权限批量授权与回收:PIP 383 设计与实现深度解析 Apache Pulsar 在命名空间级别管理权限策略,当同
消息队列流处理后端微服务消息路由
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考