Android 6.0 起, Android 加强了权限管理, 引入运行时权限概念对于:
1. Android 5.1(API 22)及以前版本, 应用权限必须声明在 AndroidManifest.xml 中, 应用在安装时, Android 会列出其所需的所有权限供用户确认安装
2. Android 6.0(API 23)及以后版本, 应用权限必须声明在 AndroidManifest.xml 中, 但权限分为普通权限 (Normal Permissions) 和危险权限(Dangerous Permissions), 以下会介绍区别:
普通权限: 不会给用户隐私带来风险
应用声明在 AndroidManifest.xml, 系统会自动授予, 无需应用申请
危险权限: 应用访问用户机密数据的权限, 会有风险
1. 此权限也必须声明在 AndroidManifest.xml 中
2. 此类权限属于运行时权限, 应用在启动后, 需执行相关需此类权限的操作前, 需调用系统 API 弹窗让用户授权, 弹窗内容应用不可修改如果缺少运行时权限(用户未授权), 那么应用强行执行操作或调用 API 会引起 APP FC 如下:
3-10 04:47:44.274 10405 8714 8714 E AndroidRuntime: java.lang.RuntimeException: Unable to create service xxxxxx.SmsBackgroundService: java.lang.SecurityException: Permission Denial: opening provider com.android.providers.telephony.MmsSmsProvider from ProcessRecord{48bbdaa 8714:xxxxxx/u0a405} (pid=8714, uid=10405) requires android.permission.READ_SMS or android.permission.WRITE_SMS
运行时权限的三种状态: 允许, 询问 (USER_SET), 拒绝(USER_FIXED) 用户可以在系统的权限管理中管理应用的每一项权限的状态
那么, 应用该如何适配运行时权限, 其标准做法是什么?
1. 在 AndroidManifest.xml 列出所有所需的权限, 包括普通权限和危险权限
2. 应用启动后, 需调用所需运行时权限的 API 前, 先调用系统 API, 如 checkSelfPermission 来查询自身是否已获取相关权限, 如已获取, 可继续正常执行 API 或后续操作等, 下面用伪代码表示:
- if (checkSeflPermission(...)) {
- // 应用未获取此危险权限
- if (shouldShowRequestPermissionRationale(...)) {
- // 用户对此权限是拒绝状态, 此时应用可自行弹窗告知用户, 注意: 如果用户在拒绝时勾选了不再询问, 此方法会返回 false, 不再可靠, 则可在 onRequestPermissionsResult 方法中再执行类似以下操作
- // 例如百度地图的做法, 会弹窗, 告知用户缺少相关权限, 请点击跳转到设置页面, 进行权限开启, 这也是多数应用的标准做法
- // ......
- } else {
- // 用户对此权限是询问状态, 应用可调用系统 API 弹窗去申请权限, 用户操作结果可在 overload 方法 onRequestPermissionsResult 中处理
- requestPermissions(...);
- }
- } else {
- // 已有此危险权限, 后面可放心执行相关操作
- // .....
- }
最后, 列出所有的危险权限, 注意, 这里有权限组 (Permission Groups) 的概念, 申请某个具体的权限时, 系统在弹窗中只会告知用户应用所需访问的权限组, 并不会描述该具体权限如果某个权限组中, 应用一个权限都还没被授权, 则会弹窗供用户选择授权; 如果某个权限组中, 应用已被授权了其中一个权限, 那么应用再次申请同一个权限组内其他权限时, 会被自动默认授权
参考:
- https://developer.android.com/training/permissions/requesting.html?hl=zh-cn
- https://developer.android.com/training/permissions/best-practices.html?hl=zh-cn
- https://developer.android.com/guide/topics/security/permissions.html?hl=zh-cn#normal-dangerous
来源: https://www.cnblogs.com/KevinSong/p/8583775.html