运行时权限的讲解在前一篇博客已经算是说的比较清楚了,这里就不说了,如果对6.0这个新特性不是很了解的朋友建议先看看(地址:),那么本篇就直接说怎么使用第三方开源库了,本人通过实践比较觉得PxPermissions这个开源库好用,这里就是他的使用说明书了。当然你可以去Github上搜索PxPermissions去查看源码学习,或者查看作者自己的使用说明。
当然这里也给出地址:下面开始正题:
首先是RxPermission库的引入,通过添加依赖即可:
在app的buildgradle文件中添加依赖:dependencies { ... //RxPermissions compile 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.4@aar' //RxJava2 compile "io.reactivex.rxjava2:rxjava:2.0.0"}
也可以在Project Strcuture里搜索这个依赖库,直接添加。
由于Rxjava的巨大优势和RxPremissions的优秀封装使用起来非常方便
RxPermissions rxPermissions = new RxPermissions(MainActivity.this);rxPermissions.request(Manifest.permission.CALL_PHONE) .subscribe(new Observer() { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(Boolean value) { if(value){ Toast.makeText(MainActivity.this, "同意权限", Toast.LENGTH_SHORT).show(); }else { Toast.makeText(MainActivity.this, "拒绝权限", Toast.LENGTH_SHORT).show(); } } @Override public void onError(Throwable e) { } @Override public void onComplete() { } });
如果需要同时生气多个权限并且要分别判断权限是否授予,可以使用如下写法:
RxPermissions rxPermission = new RxPermissions(getActivity()); rxPermission .requestEach(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_CALENDAR, Manifest.permission.READ_CALL_LOG, Manifest.permission.READ_CONTACTS, Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_SMS, Manifest.permission.RECORD_AUDIO, Manifest.permission.CAMERA, Manifest.permission.CALL_PHONE, Manifest.permission.SEND_SMS) .subscribe(new Consumer() { @Override public void accept(Permission permission) throws Exception { if (permission.granted) { // 用户已经同意该权限 Log.d(TAG, permission.name + " is granted."); } else if (permission.shouldShowRequestPermissionRationale) { // 用户拒绝了该权限,没有选中『不再询问』(Never ask again),那么下次再次启动时,还会提示请求权限的对话框 Log.d(TAG, permission.name + " is denied. More info should be provided."); } else { // 用户拒绝了该权限,并且选中『不再询问』 Log.d(TAG, permission.name + " is denied."); } } });
我还能说什么,真的是已经很简洁了,相比其他AndPremission和PremissionGen的有些缺陷和相对复杂的逻辑判断,我要说:这是我见过最简洁的运行时权限的写法了。当然如果你使用lambda表达式的会更简洁:
RxPermissions rxPermissions = new RxPermissions(MainActivity.this);rxPermissions .request(Manifest.permission.CALL_PHONE) .subscribe(granted -> { if (granted) { Toast.makeText(MainActivity.this, "同意权限", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(MainActivity.this, "拒绝权限", Toast.LENGTH_SHORT).show(); } });
我只想说,Premission遇到RxJava那就是Android界的一大福音啊,简直就是十月革命一声枪响,给我们送来马克思主义啊。
综合这两篇博客,我们可以看到运行时权限无非就是:权限判断,权限申请,授权监听,有权逻辑,无权提示这五步。代码量是比以前增加不少,还好危险权限相对不多,也可以集中申请,用时判断;再考虑到Android的每一次进步,都对我们开发者虽然眼前吃点苦,但长期来看也是有很大好处的,也就可以很愉快地接受了这个现实。
关于复杂业务场景权限判断的思考
以上实例是在处理单个或单一权限组的权限申请,也对应着一个权限逻辑,这并不意味每次危险权限都要单独执行上面的几步;其实可以只申请一次,然后针对不同权限执行不同的操作。如果是一次权限申请对应不同的权限逻辑,用户可能未授予全部权限,导致部分权限操作可以执行,部分不行,这里AndPermission也留了很好的扩展空间,在涉及到权限的方法里都有String[] permissions或者List grantedPermissions这样的权限数组和集合,从而实现针对对单个权限执行特殊操作。
结束语
有了RxPermissions,就可以直接秒杀6.0的这个新特性了。另外关于PermissionGen的失败回调,以及AndPermission的Fragment部分机型无法接收回调的事情,我只想说,希望国内的大牛再接在励,我们这些小辈也是要动劲了。
ok,运行时权限通过就说到这里吧。