Android6.0新的权限机制
这篇博客是学习完 Android 6.0 新的权限机制后所写。如有不妥之处,欢迎留言,谢谢~
早已听说 Android 6.0 更新了权限机制,但由于没有学习,在工作中一直尚未使用,为了防止新的权限机制带来的问题,将 targetSdkVersion
调为了 22,这显然是治标不治本的方法,所以今天抽空学习了 Android 6.0 的运行时权限处理机制。
前言
Android 6.0 已发布多时,新版本的 SDK 给开发者带了一些新控件的同时,也带来了新的权限机制。在上几篇文章中,介绍了一些 Android 6.0 带来的新控件,现在我们来学习下全新的权限机制。
新权限机制的变化
不知你是否和我一样反感一些APP滥用权限。
Android 6.0 之前,若你要使用 APP,你只能被迫同意这个 APP 的所有权限;不同意则意味着不能安装。倘若遇到有良心的开发者开发的 APP ,同意是没有问题的;但是当一个单机的斗地主 APP,需要访问通讯录、发送短信等权限时,你还会同意吗?
Android 6.0 之后,我们可以直接安装一款 APP,当这个 APP 需要使用某一权限时,会弹出提示框询问用户是否同意。当我们认为是不合理的权限时,我们完全可以拒绝此 APP 使用该权限。当我们之前同意(或拒绝)这个 APP 使用某一权限,但一段时间后,觉得不合理时,完全可以去权限设置中心进行对该 APP 进行解除(或授权)该权限。
为了更好保护用户的隐私及不影响用户体验,Android 将权限划分为两种:
- Normal Permissions ,表示正常权限,也就是不涉及用户隐私。这种权限是不需要用户进行授权的,如:手机震动、蓝牙等。
- Dangerous Permission ,表示危险权限,也就是涉及用户隐私。这种权限是需要用户进行授权的,如:访问通讯录、发送短信等。
其中,Dangerous Permission 危险权限又分为几组。那么分组对权限机制的影响有哪些呢?
假设现在 A和B是同一组危险权限。是这样的,当我们的 APP 已被用户授权了 A 权限,那么当我们使用到 B权限 时,系统会立刻授权,而不需要用户授权。例如:当我们的 APP 已授权了 SEND_SMS
权限时,当我们需要使用到 RECEIVE_SMS
权限时,系统会立刻授权。也就是说,只要同一组中的权限,只要其中有一个有授权,那么其他组员同样也会被授权。
为了防止后期版本中组权限的改变,强烈建议使用每一个危险权限都进行权限申请。
Normal Permissions
|
|
Dangerous Permission
|
|
使用步骤
在学习之前,一直听说 Android 6.0 换了新的权限机制,使用起来很麻烦。现在学了之后感觉只是在使用权限之前加了一层判断,繁琐点。不多说了,开始吧。
跟之前一样,在
AndroidManifest
清单文件中,添加需要的权限。试图申请一个没有声明的权限,可能会导致程序崩溃。
核实是否已授权权限
12345678// 例如:核实是否拥有发送短信的权限if (ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.SEND_SMS)!= PackageManager.PERMISSION_GRANTED) {// 需要申请授权} else {// 表示已授权}PS:核实的权限的 API :
ContextCompat.checkSelfPermission(@NonNull Context context, @NonNull String permission);
翻看源码可看到,此方法有两个返回:
- PackageManager.PERMISSION_DENIED,值为 -1,表示需要申请授权
- PackageManager.PERMISSION_GRANTED,值为 0,表示已授权
申请授权
123ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.SEND_SMS},MY_PERMISSIONS_REQUEST_SEND_SMS);PS:申请权限的 API:
ActivityCompat.requestPermissions(final @NonNull Activity activity, final @NonNull String[] permissions, final int requestCode)
参数说明:
- 第一个:Context
- 第二个:需要申请的权限字符串数组 [说明可以同时申请多个权限,但系统会通过对话框逐一询问用户是否授权]
- 第三个:申请返回的请求码
处理权限申请回调:
1234567891011121314151617public void onRequestPermissionsResult(int requestCode,@NonNull String[] permissions,@NonNull int[] grantResults) {switch (requestCode) {case MY_PERMISSIONS_REQUEST_SEND_SMS: {if (grantResults.length > 0&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {// 拥有权限} else {// 当弹出的申请权限申请提示框被拒绝时的逻辑}return;}}super.onRequestPermissionsResult(requestCode, permissions, grantResults);}执行申请回调后,首先是通过
requestCode
找到到你的申请,然后进行验证grantResults
对应的申请结果,这个数组对应了申请时的权限数组,你同时申请几个权限,grantResults
的长度就为多少,其分别记录了每个权限的申请结果。也就是说,当你申请成功时,你就可进行下一步的逻辑。
还有一个很重要的 API 需要介绍:
|
|
[发送短信]的例子
|
|
需要注意:
- 并非所有的通过Intent的方式都不需要申请权限。一般情况下,你是通过Intent打开另一个app,让用户通过该app去做一些事情,你只关注结果(onActivityResult),那么权限是不需要你处理的,而是由打开的app去处理。更多请参考 Consider Using an Intent。
项目地址
参考博文:
鸿洋- Android 6.0 运行时权限处理完全解析
作者简介:
刘广明(@cnLGMing),一步一步往上爬。
文章若有不对之处,欢迎指正,谢谢~
版权声明:原创作品,转载时请务必注明原始出处。