前言
Android6.0之后的有些权限需要去动态获取,这个过程中呢,我们或许会遇到这么几个方法。
1.ContextCompat.checkSelfPermission 检查权限是否允许
2.ActivityCompat.requestPermissions 请求某个或某几个权限
3.onRequestPermissionsResult 手动请求权限之后的结果回调
4.shouldShowRequestPermissionRationale ???
其中前三个的用途都非常清楚,大家也都知道怎么用的,这里不做过多解释,今天主要看下咱们的主角shouldShowRequestPermissionRationale,看下它是干什么用的。从shouldShowRequestPermissionRationale这么长的方法名,解释出来就是“应不应该解释下请求这个权限的目的”,接下来,咱们先看它的官方注释。
官方解释
/**
* Gets whether you should show UI with rationale for requesting a permission.
* You should do this only if you do not have the permission and the context in
* which the permission is requested does not clearly communicate to the user
* what would be the benefit from granting this permission.
*
* For example, if you write a camera app, requesting the camera permission
* would be expected by the user and no rationale for why it is requested is
* needed. If however, the app needs location for tagging photos then a non-tech
* savvy user may wonder how location is related to taking photos. In this case
* you may choose to show UI with rationale of requesting this permission.
*
*
* @param activity The target activity.
* @param permission A permission your app wants to request.
* @return Whether you can show permission rationale UI.
蹩脚翻译
获取是否应显示具有请求权限理由的UI,只有在没有权限并且上下文的情况下不能清晰明了的表明为什么需要这个权限时才应该这样做。举例,你要是实现一个照相的app,用户可以明白你为什么需要照相的权限,然而app却需要定位信息去给照片做标注,一个非技术又精明的用户可能很好奇一个拍照APP怎么会想要定位权限。在这种情况下您可以选择在请求定位权限之前先在UI上解释下为什么需要它。
返回:你是否可以展示权限的解释说明
看完之后你明白了吗?讲真,我是真不明白,这段注释只说明了Google工程师设计这个方法的初衷是什么,具体有什么功能,怎么用的,从这里我真的还看不错来。
网络资源参考
Android6.0动态权限shouldShowRequestPermissionRationale的含义这篇文章,说明的是比较有价值的:
以某个权限为例,
1.第一次请求权限时ActivityCompat.我使用的是8.0系统的手机=false;
2、第一次请求权限被禁止,但未选择【不再提醒】ActivityCompat.shouldShowRequestPermissionRationale=true;
3、允许某权限后ActivityCompat.shouldShowRequestPermissionRationale=false;
4、 禁止权限,并选中【禁止后不再询问】ActivityCompat.shouldShowRequestPermissionRationale=false;
文章中记录的结果和我真实手机跑程序打印的结果是一致的(我使用的是8.0系统的手机)。
shouldShowRequestPermissionRationale的功能价值何在
在此之前先说明下,由于不同的系统厂商定制的结果,
1.有的手机某些权限清单注册了权限就能用,不用动态申请(因为系统会在安装时自动app分配一些权限,具体怎么分配的这里暂不做讨论);
2.有的手机在弹出授权时选择拒绝就默认了不再弹出;
3.有的沿用了原生系统的规则;
4.设置-应用-权限中权限分“允许、询问、拒绝”三个级别,但是有的权限只有“允许、拒绝”两个级别;
这里先统一下名词:
允许-- 权限通过
拒绝--拒绝了但是还允许询问
禁止--拒绝了且不再允许询问(如4中所述的“拒绝”先定义为禁止)
从前面就可以看出来,这个方法大部分情况下是放回false的,只有被用户拒绝了权限,再次获取才会得到true;如果没有申请过,或者禁止了权限,都是返回的false。所以很多人想要通过shouldShowRequestPermissionRationale去判断是否权限被禁止,有时候是并不准确的,真要说怎样会准确的获取到权限被禁止的情况,那就是:
1.在requestPermissions之后在
onRequestPermissionsResult中获取到没给权限,并且shouldShowRequestPermissionRationale是false,此时可以认定该权限被用户禁止了;
2.还有一个点是是在onRequestPermissionsResult的参数值第三个参数grantResults是null,此时权限也是被拒绝的。(权限被拒绝后再次调用requestPermissions,没有返回结果)
总结
shouldShowRequestPermissionRationale,回到最初的解释“应不应该解释下请求这个权限的目的”。
1.都没有请求过这个权限,用户不一定会拒绝你,所以你不用解释,故返回false;
2.请求了但是被拒绝了,此时返回true,意思是你该向用户好好解释下了;
3.请求权限被禁止了,也不给你弹窗提醒了,所以你也不用解释了,故返回fasle;
4.请求被允许了,都给你权限了,还解释个啥,故返回false。
Google的初衷大概就是第一次requestPermissions的时候被拒绝时给你一次解释的机会,所以是让你在请求权限的回调中使用的。
其它
动态权限的适配就是检测、请求,然后看回调,再通过了权限后再去执行自己的方法,但是真正用的时候又很麻烦,每次调用相机、短信、打电话、访问通讯录、定位等等都要请求权限,写一堆跟业务无关的代码,是不是很烦呢? 最近整理了一个关于方便管理动态权限的库,[Android6.0动态权限获取:一个EasyPermission的权限管理库](https://www.jianshu.com/p/671fbbb48551)
附github源码:https://github.com/githubZYQ/easypermission