Android M的运行时权限相关要点
条评论2016-11-17 更新:如果已经了解运行时权限的基本使用,可以直接参考这篇文章:Android M 权限最佳实践
样例代码:https://github.com/kinneyyan/RuntimePermissionSample
1. 新的权限机制
6.0 开始将权限分为两类。
一类是 Normal Permissions,这类权限一般不涉及用户隐私,是不需要用户进行授权的,比如手机震动、访问网络等。此类权限在应用安装时就被授予(同 6.0 之前)。
另一类是 Dangerous Permission,一般是涉及到用户隐私的,在 app 使用时需要用户进行授权,比如读取 sdcard、访问通讯录等。此类权限是分组的:
同一组的任何一个权限被授权了,其他权限也自动被授权。
2016-03-11 更新:所有需要申请的权限还是必须在 AndroidManifest 中声明,否则,即使同组一个权限被授权了,一个未在 AndroidManifest 中声明的权限授权还是会失败。
2. 关于 targetSdkVersion 需要注意的
- 若 targetSdkVersion 低于 23,将使用旧有规则:用户在安装的时候不得不接受所有权限,安装后 app 就有了那些权限。不过用户依然可以在设置中取消已经同意的授权。
- 若 targetSdkVersion 高于 23,如果 app 在使用一些敏感权限的时候没有做运行时权限的代码处理,app 会直接 crash。
3. 相关 API 以及使用步骤
假设我们的 app 有添加联系人的功能:
- 在 AndroidManifest 文件中添加需要的权限 android.permission.WRITE_CONTACTS
- 在添加联系人的代码之前,检查权限
1 | int hasWriteContactsPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_CONTACTS); |
ContextCompat.checkSelfPermission
:用于检测某个权限是否已经被授予,返回值为PackageManager.PERMISSION_DENIED
或者PackageManager.PERMISSION_GRANTED
- 申请授权
1 | ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_CONTACTS}, REQUEST_CODE_WRITE_CONTACTS); |
ActivityCompat.requestPermissions
:第一个参数是 Context;第二个参数是需要申请的权限的字符串数组,很明显这里可以一次申请多个;第三个参数为 requestCode,主要用于回调的时候检测。
- 处理申请回调。不论用户同意还是拒绝,activity 的 onRequestPermissionsResult 都会被回调来通知结果。
1 |
|
onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
:第一个参数 requestCode 不用说;第二个参数为申请的权限,例如 Manifest.permission.WRITE_CONTACTS;第三个参数为申请结果。如果此次回调是一次申请多个权限的情况,那第二个参数和第三个参数为对应关系。
至此权限申请的步骤走通,不过还有个 API 需要提下:
ActivityCompat.shouldShowRequestPermissionRationale(Activity activity, String permission)
:该方法只有在用户在上一次已经拒绝过你的这个权限申请时返回 true;其余情况例如用户勾选了”不再显示”时均返回 false。这个 API 的目的主要用于给用户一个申请权限的解释,我们可以弹个对话框告知用户为什么需要这个权限,点击确定时再去申请权限。加入此方法的申请权限代码如下:
1 | int hasWriteContactsPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_CONTACTS); |
如果用户勾选了“不再显示”拒绝后,再次申请权限时,在 onRequestPermissionsResult 回调方法中走权限拒绝的方法,如果用户又想开启此权限的话,我们可以通过 shouldShowRequestPermissionRationale 返回值判断是否勾选“不再显示”,是的话在回调方法判断权限拒绝的代码块中弹一个对话框告知用户:在设置-应用-权限管理中去开启。
1 | case REQUEST_CODE_WRITE_CONTACTS: |
4. 第三方开源库
前两个使用了注解