解析动态权限适配遇到的问题
从6.0版本开始,Android系统做了一次大的改动,对于部分权限,App需要在代码中动态申请相应的权限。
Android权限分为2种:普通权限和危险权限,这2种权限都需要在Manifest清单文件中声明
普通权限(Normal Permission)
在程序运行时期自动获取,只需要在清单文件中声明即可。最常用的就是INTERNET网络权限
危险权限(Dangerous Permission)
App中可能存在一些操作会查看用户隐私相关的信息,比如通讯录或图库。对于这一类操作,Android系统要求App主动向用户展示操作所需要的权限,只有用户授权后才可以进行下一步操作
简单的描述就是:
在调用requestPermission之前,还有一步比较重要的操作:判断是否需要展示shouldShowRequestPermissionRationale
shouldShowRequestPermissionRationale这个方法会返回以下2种情况:
针对true的情况很容易处理,这种情况表示用户已经拒绝过申请操作,但是并没有选中“Never ask again”选项,因此我们只需要再次调用requestPermission方法申请权限即可,系统会自动弹出申请权限的对话框
但是对于返回false的情况麻烦点,因为有2种情况会返回false,而针对这2种情况所对应的相应反馈操作也不同。
比如用户从没申请过,那就和返回true一样,直接调用requestPermission方法申请权限即可;
但是如果是因为用户之前拒绝申请操作,并勾选“Never ask again” ,此时我们不应该再执行requestPermission方法,而是应该弹出自定义的对话框,提示用户此操作必须通过权限申请之后才可继续进行,并提供给用户进入权限设置的界面入口
需要注意!shouldShowRequestPermissionRationale 返回true的情况在很多国内厂商的手机中设置了自动屏蔽,也就是没有返回true的情况!!!,比如华为,小米
以申请通讯录权限为例来演示如何进行动态权限适配。首先需要判断系统版本是否高于23,代码如下:
只有在高于23版本的系统中才需要动态申请权限,在申请之前还需要检查当前App是否已经获取到相应的权限,避免重复申请,如下:
上图中的PackageManager.PERMISSION_GRANT表示权限已经获取
接下来就是申请权限的流程,在申请权限之前,需要调用shouldShowRequestPermissionRationale 方法判断用户之前的操作
①处shouldShowRequestPermissionRationale 返回true,直接调用requestPermission 再次申请权限即可
但是对于返回false的情况需要特殊处理,因为有2中情况返回false,可以借助SharedPreference来判断,是否用户第一次申请权限的操作
使用SP来保存用户是否第一次申请权限的状态值,默认情况为true,当执行一次申请操作之后需要将其设置为false
封装进一个Util类,并提供给调用者相应的回调接口