从Android动态权限到Rxpermissions实现
搞Android开发的同学可能都知道,Android 6.0最重要的新特性就是动态权限申请。
用户可直接在运行时管理应用权限,这种模式让用户能够更好地了解和控制权限。动态权限对于用户来说肯定是非常好的一个新特性,但对于开发者来说可能不是很友好。不过想想也挺好的,毕竟用户为大,保护用户的隐私最重要了。
唉,做Android真累。
让我们先来看看6.0以上的权限怎么申请吧~
动态权限申请步骤
步骤一
先在AndroidManifest中填写你要申请的权限。
我们只需要在对应的位置写入申请权限代码即可,例如我现在申请相机权限。
<uses-permission android:name="android.permission.CAMERA" />
步骤二
然后我们需要在打开相机的位置添加下面的代码。
public void requestPower() {
// checkSelfPermission 判断是否已经申请了此权限
if (ContextCompat.checkSelfPermission(this,Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
//如果应用之前请求过此权限但用户拒绝了请求,shouldShowRequestPermissionRationale将返回 true。
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.CAMERA)) {
} else {
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.CAMERA,}, 1);
}
}
}
步骤三
然后还需要在onRequestPermissionsResult回调方法中去进行处理。代码如下
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 1) {
for (int i = 0; i < permissions.length; i++) {
if (grantResults[i] == PERMISSION_GRANTED) {
Toast.makeText(this, "" + "权限" + permissions[i] + "申请成功", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "" + "权限" + permissions[i] + "申请失败", Toast.LENGTH_SHORT).show();
}
}
}
}
这些好了之后我们来看一看效果吧。
动态申请权限基本上就这样子了。 下面进入本文重点内容,讲解RxPermissions实现原理。
RxPermissions
RxPermissions是什么?
Android runtime permissions powered by RxJava2 ——官方解释 ,也就是说它是基于Rxjava的动态权限框架。
RxPermissions怎么用?
首先去gradle中引入依赖
implementation 'com.github.tbruyelle:rxpermissions:0.10.2'
然后添加如下代码即可。
private void rxPermissionTest() {
RxPermissions rxPermissions = new RxPermissions(this);
rxPermissions.request(Manifest.permission.CAMERA).subscribe(new Consumer<Boolean>() {
@Override
public void accept(Boolean granted) throws Exception {
if (granted) {
// 打开相机
} else {
// 权限被拒绝
}
}
});
}
实现效果与上面一样。我就不重复贴图了,大家可以自己试试看看。
RxPermissions实现原理。
上面写了这么多东西,相必大家早就想看最后部分了吧。 没错,这就是最后部分。
9648fc14eb1146b8839470cbe852be56.jpeg这里为大家献上我最喜欢的一句话, Talk is cheap, Show me the code.
意思就是,别叨叨了,有种上代码~~
我们先从RxPermissions的构造方法看起。
构造方法挺容易理解的,就是初始化RxPermissionsFragment,我们所有的权限申请、回调都是在这个Fragment中实现的,这也是RxPermissions框架最主要的部分,一切都是围绕这个展开的。
在getRxPermissionsFragment方法中将这个无界面的Fragment添加到FragmentManager。
接下来我们需要翻阅大概了解一下RxPermissionsFragment这个类。首先看处理权限返回的代码。
在上面我们讲过onRequestPermissionsResult这个方法是处理权限返回时候具体逻辑的,在这里我们就见到了吧。
该框架向外部暴露了一个onRequestPermissionsResult的重载方法,在这个方法中定义了一个PublishSubject,它将每个权限封装为Permission实体类,然后将它发出给订阅它的观察者进行处理。本篇暂时不讲Rxjava的用法。 我暂且认为大家都会Rxjava了。
让我们继续看,isGranted方法。在这个方法中我们看到了一个熟悉的方法checkSelfPermission,说明它是在这个方法中开始的权限申请。
RxPermissionsFragment主要的几个方法已经说完了,下面我们继续看RxPermissions类。
刚才在RxPermissions用法中已经写过,这个框架是调用request方法,所以我们看request方法是如何实现的。
看起来此方法通过compose进行了一个转换,具体实现在ensure中,我们继续点进去看ensure方法。
在这个方法中,我们还需要看一下request(o,permission)内部又实现了一些什么操作。
这个方法中是将Object转为了Observable Permission 具体转的实现还需要看requestImplementation方法的实现。
主要逻辑就是通过RxPermissionsFragment的isGranted方法进行判断,如果同意权限,返回Permission对象为true,否则返回false。
让我们再回到ensure方法
很明显,ensure中flatMap方法内,是将Object对象转为Boolean对象,如果permission对象同意授权返回true,反之返回false。
所以我们就可以将最终申请结果通过订阅关系返回给观察者,然后在Activity中进行处理。
看完这个框架,我决定还要继续学习Rxjava,因为有好多操作符使用我也不会。。。。
本人才疏学浅,如果有写错的地方,还希望大家指出来。
Stay hungry Stay foolish。
Bye~