Android6.0之后,APP有些用到的权限需要动态申请,虽然这个功能已经出来好久了,但一直没有研究过,只知道用法简单,到时候copy一下就好了,github上也有许多开源的框架供大家使用。本篇博客先介绍一下Android动态权限申请的使用方法(虽然可以copy,但还是要研究一下的),接着分析一下RxPermissions的源码,然后博主自己也写了一个开源lib,Kotlin版的,如果项目使用Kotlin作为开发语言的,可以考虑使用一下。
Android动态权限申请
Android6.0之后,权限级别分为正常权限和危险权限:
正常权限对用户隐私或其他应用操作风险较小,只需要在应用声明中声明即可使用。
危险权限涉及到用户隐私信息的数据或资源,因此,在应用声明之后,还需要用户动态向应用赋予该权限。
危险权限详见:Android系统权限
这里的使用方法直接介绍v4包里集成的:
检查权限
请求权限之前,先要检查是否具有该权限
if (ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
//无权限时执行此处
}
用户历史权限操作
当用户拒绝权限,再次打开APP,需要再次向用户需要申请改权限时,可以向用户说明该权限的重要性,拒绝权限可能会影响使用
if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permission, requestCode)) {
//用户拒绝过改权限时,执行此处
}
请求权限
向用户请求所使用的权限,这里的permissions可以是多少权限。
ActivityCompat.requestPermissions(activity, permissions)
请求权限回调结果
在Activity中实现以下方法,其中requestCode为请求权限是所传的请求码,permissions为所请求权限的数组,grantResults为对应的权限请求结果。
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
RxPermissions源码分析
RxPermissions一共有三个类,Permission、RxPermissions、RxPermissionFragment。
Permission类
Permission类为权限类,name、granted、shouldShowRequestPermissionRationale分别对应权限名称、请求权限结果和用户是否拒绝过权限。
RxPermissions类
RxPermissions类提供了初始化、请求权限的接口、提供Transformer的一些接口,并持有一个RxPermissionsFragment实例,在RxPermissionsFragment实现请求权限。
优点:
本框架可以提供对RxJava的支持,也可以支持查看每项权限的申请结果。
缺点:
想开始用的时候还有些疑惑,为什么google给出的请求权限的方法都需要去实现回调,而这个框架就不需要呢?
之后仔细看了一下源码,发现在新建RxPermissions类的时候,框架会悄悄的新建一个RxPermissionsFragment类,也就是说框架在内部封装了一个没有界面的fragment,这样做的好处是请求权限的回调可以在Fragment中实现,不需要用户再去调用,不过我总是觉得这样做对android性能优化不是很好,源码如下:
private RxPermissionsFragment getRxPermissionsFragment(Activity activity) {
RxPermissionsFragment rxPermissionsFragment = findRxPermissionsFragment(activity);
boolean isNewInstance = rxPermissionsFragment == null;
if (isNewInstance) {
rxPermissionsFragment = new RxPermissionsFragment();
FragmentManager fragmentManager = activity.getFragmentManager();
fragmentManager
.beginTransaction()
.add(rxPermissionsFragment, TAG)
.commitAllowingStateLoss();
fragmentManager.executePendingTransactions();
}
return rxPermissionsFragment;
}
KPermissions
这是博主自己封装的一个请求权限lib,使用kotlin语言编写,采用android v4包提供的权限请求方法,源码以放在了github:KPermissions,欢迎star,也希望路过的大神可以多加指点,下面说一下框架的用法及功能。
集成
在APP build.gradle中,minSdkVersion必须大于等于14.
build.gradle配置如下:
repositories {
jcenter() // If not already there
}
dependencies {
compile 'cn.hchstudio:kpermissions:1.0.8'
}
用法
创建KPermissions实例:
var kPermission: KPermission = KPermission(this)
请求权限:
kPermission.requestPermission(arrayOf(Manifest.permission.CAMERA), {
Log.i(TAG, "isAllow---$it")
}, {
Log.i(TAG, "permission---$it")
})
第一个参数为需要请求权限的数组,第二个为是否全部请求成功的回调,第三个为请求每项权限时的回调。
实现onRequestPermissionsResult回调:
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
kPermission.onRequestPermissionsResult(requestCode, permissions, grantResults)
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
框架也支持在java中使用,详细见JavaActivity