这里使用 的是 RxPermissions ,由RxJava2提供支持的Android运行时权限 ,让代码简洁,申请权限更加方便。
该库允许将RxJava与新的Android M权限模型一起使用。
使用时候导入依赖:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
dependencies {
implementation 'com.github.tbruyelle:rxpermissions:0.10.2'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
implementation 'io.reactivex.rxjava2:rxjava:2.1.6'
}
创建一个RxPermissions
实例:
final RxPermissions rxPermissions = new RxPermissions(this); //这是一个Activity或Fragment实例
注: new RxPermissions(this)
该this
参数可以是FragmentActivity或片段。如果您RxPermissions
在片段内使用,则应将片段instance(new RxPermissions(this)
)作为构造函数参数传递,而不是new RxPermissions(fragment.getActivity())
或者您可以面对java.lang.IllegalStateException: FragmentManager is already executing transactions
。
示例:请求CAMERA权限(为简洁起见,请使用Retrolambda,但不是必需的)
// 必须在初始化阶段完成,如onCreate
rxPermissions.request(Manifest.permission.CAMERA)
.subscribe(granted -> {
if (granted) { //
// 授权
} else {
// 权限被拒绝
}
});
如果需要从特定事件触发权限请求,则需要在初始化阶段将事件设置为可观察对象。
您可以使用JakeWharton / RxBinding将视图转换为可观察的(未包含在库中)。
示例:
// 必须在初始化阶段完成,如onCreate
RxView.clicks(findViewById(R.id.mPermissions))
.compose(rxPermissions.ensure(Manifest.permission.CAMERA))
.subscribe(granted -> {
// R.id.mPermissions 已被点击
});
如果同时有多个权限,则结果为:
rxPermissions.requestEach(mPermissions).subscribe(new Consumer() {
@Override
public void accept(Permission permission) {
Log.i("TAG", "accept: " + permission.toString());
if (permission.granted) {
//权限获取成功 处理事件
ThreadTask.getInstance().executorOtherThread(new Runnable() {
@Override
public void run() {
batchAddContact(MainActivity.this, models);
}
},10);
} else if (permission.shouldShowRequestPermissionRationale) {
//权限获取失败,但是没有永久拒绝, 可以自己设置一个对话框提示用户需授权使用
PermissionUtil.PermissionDialog(MainActivity.this, PermissionUtil.permissionText(mPermissions));
} else {
//权限获取失败,而且被永久拒绝
}
}
});
您还可以使用requestEach
或观察详细结果ensureEach
:
rxPermissions
.requestEach(Manifest.permission.CAMERA,
Manifest.permission.READ_PHONE_STATE)
.subscribe(permission -> { //将发出2权限对象
if (permission.granted) {
// `permission.name` 被授予!
} else if (permission.shouldShowRequestPermissionRationale) {
//拒绝权限,不要再问任何其他
} else {
//拒绝权限再问一次
//需要转到设置
}
});
您还可以使用requestEachCombined
或获得组合的详细结果ensureEachCombined
:
rxPermissions
.requestEachCombined(Manifest.permission.CAMERA,
Manifest.permission.READ_PHONE_STATE)
.subscribe(permission -> { //将发出1个权限对象
if (permission.granted) {
//所有权限授予!
} else if (permission.shouldShowRequestPermissionRationale)
//至少有一个被拒绝的权限,而不再问任何问题
} else {
//至少有一个被拒绝的权限再问一次
//需要去设置
}
});
如上所述,由于您的应用程序可能在权限请求期间重新启动,因此请求必须在初始化阶段完成。这可能是Activity.onCreate
,或者 View.onFinishInflate
,但不是暂停方法onResume
,因为您可能会创建无限的请求循环,因为您的请求活动在权限请求期间被框架暂停。
如果没有,并且如果您的应用程序在权限请求期间重新启动(例如,由于配置更改),则用户的答案将永远不会发送给订阅者。
避免担心框架版本。如果sdk是pre-M,则观察者将自动接收授予的结果。
阻止您在权限请求和结果处理之间拆分代码。目前没有此库,您必须在一个地方请求权限并处理结果Activity.onRequestPermissionsResult()
。
所有RX提供的转换,过滤,链接......