Android6.0权限管理以及使用权限该注意的地方
来源:互联网 发布:贝克汉姆助攻数据 编辑:程序博客网 时间:2024/06/05 12:41
Android 6.0 Marshmallow首次加入了运行时权限管理,这对用户来说,可以更好的了解、控 制 app 涉及到的权限。然而对开发者来说却是一件比较蛋疼的事情,需要兼容适配,并保证程序功能的正常运行。
什么叫运行时权限管理呢?在Android 6.0以下的系统中,当我们在安装应用的时候,该应用就会提示我们这个应用所需要的权限,如果你要安装,那就必须同意赋予所有权限,但是如果不同意,那就只能取消安装了,有点流氓。而且安装完后,你不可以收回这个权限。
而6.0就做到了运行时权限管理,即使安装的时候给了权限,也可以到系统设置里,去关闭该权限。
下面分几种情况来讲,因为运行时权限只有在Android6.0及以上的手机版本才有,所以这里只考虑设备版本大于6.0的手机,低版本的手机在安装时就已经赋予了所有的权限,也不可能收回,就不考虑了,下面的情况只分targetSdkVersion:
- targetSDKVersion大于等于23的时候,那么权限是可以被回收(revoke),这里还要分权限,google将权限分为两种,一种是normal permission,另一种是dangerous permission。normal permission是指与用户隐私无关的权限,可以理解为无关紧要的权限,比如说访问网络的权限,对用户来说没什么关系;dangerous permission就是会涉及到用户隐私的权限,例如读取用户手机联系人、短信等等。如果是normal permission的话,那么在安装的时候就会给,而且不会开放接口让用户回收该权限,app会一直拥有该权限,所以不用考虑这种类型的权限。如果是dangerous permission的话,在安装的时候并未授予权限,系统开放接口允许用户回收或者赋予权限。下面是某个应用的权限,第一张图是dangerous permission,可以回收和赋予的。
点击上面的所有权限,可以查看到该应用所有的权限。
那么对于dangerous permission的话,在使用前需要去检查该permission是否已经被授予
checkSelfPermission(Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED
如果该权限已经被授予,那么可继续执行你的代码,如果未授予,则需要向用户询问是否需要授予权限,弹出的框是系统界面,界面如下:
调用代码:
requestPermissions(new String[]{Manifest.permission.READ_PHONE_STATE}, 1);
系统询问是否授予权限的页面结束后会有回调
@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 1) { if(grantResults[0] == PackageManager.PERMISSION_GRANTED){ //your implementations }else{ ToastUtil.show(this, "权限不足,支付失败"); } }}
- 如果targetSdkVersion是小于23的,那么将认为app没有用23新权限测试过,那么继续使用老规则:系统在安装的时候会默认给app赋予所有的权限,app可以照常运行。但是!但是!但是!用户依然可以回收权限,不过此回收非彼回收。先看下关闭权限时弹的页面:
看到了么,如果targetSDKVersion小于23的话,在关闭权限的时候,会弹一个警告框,告诉你这是旧版的android,关闭会有问题,如果你按拒绝,那么该权限将会关闭,而且界面上,权限的开关会显示关,但是这个权限却没有被回收(nexus 5x的手机亲测,当然其他的机子我也不敢打包票),checkSelfPermission返回granted。我看了下,如果targetSDKVersion等于23的话,系统日志是:
如果targetSDKVersion是小于23的话,则日志是:
Permission related app op changed.
不过我猜想如果你要支持runtime permission的话,还是要把targetSDKVersion设为23。如果你的targetSDKVersion是小于23的话,那么还是要加上checkSelfPermission,以防万一,谁知道google会出什么坑。
还有就是权限的话,有分组的概念,看如下图:
如果一组中有一个被授予了,那么组内的也会默认被授予。
而且也支持同时申请多个权限,具体情况android developer官网。
下面是stackoverflow问题的网址:
http://stackoverflow.com/questions/36328151/ive-revoke-the-android-permission-but-checkselfpermission-still-return-granted
如有问题和错误的地方请指出。
下面就是要讲一些权限管理注意的地方。
对于权限的话,Activity和Fragment都有自己的requestPermissions和onRequestPermissionsResult回调,但是Activity是有checkSelfPermission,但是fragment是没有的,所以fragment如果想要检查权限,还得调用宿主activity的checkSelfPermission。
对了,平时直接调用checkSelfPermission和requestPermissions会报什么api错误,虽然编译不会通过,但是看着就是烦啊,可以调用ActivityCompat.checkSelfPermission(在supportv4包中)。
先看下Activity的requestSelfPermission这个方法:
public final void requestPermissions(@NonNull String[] permissions, int requestCode) { Intent intent = getPackageManager().buildRequestPermissionsIntent(permissions); startActivityForResult(REQUEST_PERMISSIONS_WHO_PREFIX, intent, requestCode, null);}
看下这里是直接打开另一个Activity进行操作,还用了startActivityForResult,回调会通过onRequestPermissionResult,我想这个回调应该是在onActivityResult里面处理,然后调这个onRequestPermissionResult函数的。
那么问题来了,如果我在onResume函数中申请某一个权限,调用requestPermissions,那么现象是什么样的呢?
第一次进入页面,弹出申请权限的对话框,如果点击同意,则正常,对话框不会再显示,但是如果第一次点击拒绝,则点击拒绝后又一次弹出对话框来申请权限,如果你一直点拒绝,则对话框一直弹出,这是为什么呢?因为第一次进入页面并执行onResume函数时申请权限,进入另一个页面,弹出对话框,如果你点击拒绝,先是回调onRequestPermissionResult,然后再执行onResume函数,这时又会再一次去检查权限,因为发现无权限,则再一次请求,如是,进入一个循环之中,除非你点同意,否则是个无限循环。所以申请权限最好还是不要写在onResume中,或者加一个标志位判断。
接下来再讲讲Fragment请求权限。
public final void requestPermissions(@NonNull String[] permissions, int requestCode) { if (mHost == null) { throw new IllegalStateException("Fragment " + this + " not attached to Activity"); } mHost.onRequestPermissionsFromFragment(this, permissions,requestCode);}
这里看到其实是调用mHost请求权限的方法,mHost就是这个fragment的宿主Activity,所以Fragment请求权限实际上也是通过宿主Activity,当权限结果回调时,activity判断是从Fragment中来的还是从自己Activity中来的,再进行分发结果。
Github上也有一些比较好用的权限库:https://github.com/hotchemi/PermissionsDispatcher
- Android6.0权限管理以及使用权限该注意的地方
- android6.0的权限管理
- Android6.0权限管理
- android6.0 权限管理
- android6.0权限管理
- Android6.0权限管理
- Android6.0权限管理
- Android6.0权限管理
- Android6.0权限管理
- Android6.0 权限管理
- Android6.0------权限管理
- Android6.0权限的使用
- android6.0新权限申请以及RxPermissions库的使用
- Android6.0运行时权限以及RxPermissions的使用
- Android6.0权限管理依赖库的介绍和使用
- android6.0以及以上的权限处理
- Android6.0的权限管理(相机权限的举例)
- Android6.0的权限管理(相机权限的举例)
- Burp Suite使用介绍(一)
- ArrayList中调用set()方法,没有插入数据的问题
- 15数字排序 最后一个最小
- CodeForces 17B Hierarchy
- Master-Master架构
- Android6.0权限管理以及使用权限该注意的地方
- Android AutoLayout全新的适配方式 堪称适配终结者
- 将博客搬至CSDN
- 多元线性回归multivariable linear regression
- 面试准备android(二)
- select 中option 值在不同游览器的取值问题
- 判断素数并求和用平方根算法(C语言)
- C++中的GetTickCount()和Sleep()
- 为eclipse的lib文件夹中的jar包关联源码说明