RxPermissions 动态权限 简介 案例
Posted baiqiantao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RxPermissions 动态权限 简介 案例相关的知识,希望对你有一定的参考价值。
基本使用步骤
1、配置
allprojects {
repositories {
maven { url ‘https://jitpack.io‘ }
}
}
5
5
1
allprojects {
2
repositories {
3
maven { url ‘https://jitpack.io‘ }
4
}
5
}
implementation ‘com.github.tbruyelle:rxpermissions:0.10.2‘
1
1
1
implementation ‘com.github.tbruyelle:rxpermissions:0.10.2‘
2、创建 RxPermissions 实例
final RxPermissions rxPermissions = new RxPermissions(this); // where this is an Activity or Fragment instance
1
1
1
final RxPermissions rxPermissions = new RxPermissions(this); // where this is an Activity or Fragment instance
注意:this 参数可以是 FragmentActivity 或 Fragment。如果你在 fragment 中使用 RxPermissions,你应该传递 fragment 实例作为构造函数参数而不是 fragment.getActivity(),否则你可能抛出异常 java.lang.IllegalStateException: FragmentManager is already executing[执行]
3、请求权限,必须在初始化阶段比如 onCreate 中调用
// Must be done during an initialization phase like onCreate
rxPermissions.request(Manifest.permission.CAMERA)
.subscribe(granted -> {
if (granted) { // Always true pre-M
// I can control the camera now
} else {
// Oups permission denied
}
});
9
9
1
// Must be done during an initialization phase like onCreate
2
rxPermissions.request(Manifest.permission.CAMERA)
3
.subscribe(granted -> {
4
if (granted) { // Always true pre-M
5
// I can control the camera now
6
} else {
7
// Oups permission denied
8
}
9
});
If you need to trigger触发 the permission request from a specific event特定事件, you need to setup your event as an observable inside an initialization phase初始化阶段.
RxView.clicks(view)
.compose(new RxPermissions(this).ensure(Manifest.permission.CAMERA))
.subscribe(granted -> Toast.makeText(this, granted ? "已赋予权限" : "已拒绝权限", Toast.LENGTH_SHORT).show());
3
3
1
RxView.clicks(view)
2
.compose(new RxPermissions(this).ensure(Manifest.permission.CAMERA))
3
.subscribe(granted -> Toast.makeText(this, granted ? "已赋予权限" : "已拒绝权限", Toast.LENGTH_SHORT).show());
注意事项和优点
注意:
如上所述,由于您的应用程序可能在权限请求期间重新启动,因此请求必须在初始化阶段完成。这可能是 Activity.onCreate 或View.onFinishInflate,但不能在 onResume 等 pausing 方法中,因为由于您请求的 activity 在权限请求期间被框架暂停了,因此您可能会创建一个无限的请求循环。
如果没有,并且如果您的应用程序在权限请求期间重新启动了(例如,由于配置更改),则用户的响应将永远不会发送给订阅者。
你可以在这里找到更多相关细节。
优点
- 不需要担心框架的版本。 如果sdk是 pre-M,则观察者将自动接收授予的结果。
- 您不需要拆分权限请求和结果处理之间的代码。目前,如果没有这个库,你必须在一个地方请求权限,并在 Activity.onRequestPermissionsResult() 中处理结果。
- 所有RX提供的转换、过滤、链接[transformation, filter, chaining]......
API
构造方法
RxPermissions(FragmentActivity activity) //不可以是普通 Activity ,因为他的原理是通过 FragmentManager 操作 Fragment 实现的
RxPermissions(Fragment fragment)
2
2
1
RxPermissions(FragmentActivity activity) //不可以是普通 Activity ,因为他的原理是通过 FragmentManager 操作 Fragment 实现的
2
RxPermissions(Fragment fragment)
请求权限
Observable<Boolean> request(String... permissions)
<T> ObservableTransformer<T, Boolean> ensure(final String... permissions) //与 compose 操作符一起使用
2
2
1
Observable<Boolean> request(String... permissions)
2
<T> ObservableTransformer<T, Boolean> ensure(final String... permissions) //与 compose 操作符一起使用
观察详细的结果
Observable<Permission> requestEach(String... permissions) //申请了多少个权限就回调多少次,相当于 flatMap 的效果
Observable<Permission> requestEachCombined(String... permissions) //只回调一次,回调对象的的属性值是多个原始对象的组合值
<T> ObservableTransformer<T, Permission> ensureEach(final String... permissions)
<T> ObservableTransformer<T, Permission> ensureEachCombined(final String... permissions)
4
4
1
Observable<Permission> requestEach(String... permissions) //申请了多少个权限就回调多少次,相当于 flatMap 的效果
2
Observable<Permission> requestEachCombined(String... permissions) //只回调一次,回调对象的的属性值是多个原始对象的组合值
3
<T> ObservableTransformer<T, Permission> ensureEach(final String... permissions)
4
<T> ObservableTransformer<T, Permission> ensureEachCombined(final String... permissions)
其他方法
boolean isGranted(String permission) //是否已赋予权限
void setLogging(boolean logging)
Observable<Boolean> shouldShowRequestPermissionRationale(Activity activity, String... permissions)
3
3
1
boolean isGranted(String permission) //是否已赋予权限
2
void setLogging(boolean logging)
3
Observable<Boolean> shouldShowRequestPermissionRationale(Activity activity, String... permissions)
测试案例
入口Activity
public class RxPermissionsActivity extends ListActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] array = {"最简单实用的案例,request",
"和 RxView 一起使用,compose + ensure",
"一次请求多个权限",
"观察详细的结果,requestEach、ensureEach",
"观察详细的结果,requestEachCombined 和 ensureEachCombined",
"shouldShowRequestPermissionRationale 和 isGranted 的使用 ",};
setListAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, Arrays.asList(array)));
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Intent intent = new Intent(this, RxPermissionsFragmentActivity.class);
intent.putExtra("type", position);
startActivity(intent);
}
}
20
1
public class RxPermissionsActivity extends ListActivity {
2
3
protected void onCreate(Bundle savedInstanceState) {
4
super.onCreate(savedInstanceState);
5
String[] array = {"最简单实用的案例,request",
6
"和 RxView 一起使用,compose + ensure",
7
"一次请求多个权限",
8
"观察详细的结果,requestEach、ensureEach",
9
"观察详细的结果,requestEachCombined 和 ensureEachCombined",
10
"shouldShowRequestPermissionRationale 和 isGranted 的使用 ",};
11
setListAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, Arrays.asList(array)));
12
}
13
14
15
protected void onListItemClick(ListView l, View v, int position, long id) {
16
Intent intent = new Intent(this, RxPermissionsFragmentActivity.class);
17
intent.putExtra("type", position);
18
startActivity(intent);
19
}
20
}
FragmentActivity
public class RxPermissionsFragmentActivity extends FragmentActivity {
private TextView view;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
view = new TextView(this);
view.setBackgroundColor(0xff00ff00);
setContentView(view);
int type = getIntent().getIntExtra("type", 0);
init(type);
}
private void init(int type) {
switch (type) {
case 0:
new RxPermissions(this)
.request(Manifest.permission.WRITE_EXTERNAL_STORAGE)
.subscribe(granted -> {
if (granted) { //在 Android M(6.0) 之前始终为true
Toast.makeText(this, "已赋予权限", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "已拒绝权限", Toast.LENGTH_SHORT).show();
}
});
break;
case 1:
RxView.clicks(view)
.compose(new RxPermissions(this).ensure(Manifest.permission.CAMERA))
.subscribe(granted -> Toast.makeText(this, granted ? "已赋予权限" : "已拒绝权限", Toast.LENGTH_SHORT).show());
break;
case 2:
new RxPermissions(this)
.request(Manifest.permission.CALL_PHONE, Manifest.permission.SEND_SMS)//只有所有权限都赋予了才会回调成功
.subscribe(granted -> Toast.makeText(this, granted ? "已赋予权限" : "已拒绝权限", Toast.LENGTH_SHORT).show());
RxView.clicks(view)
.compose(new RxPermissions(this).ensure(Manifest.permission.CALL_PHONE, Manifest.permission.SEND_SMS))
.subscribe(granted -> Toast.makeText(this, granted ? "已赋予权限" : "已拒绝权限", Toast.LENGTH_SHORT).show());
break;
case 3:
RxView.clicks(view)
.compose(new RxPermissions(this).ensureEach(Manifest.permission.CALL_PHONE, Manifest.permission.SEND_SMS))
.subscribe(permission -> {//申请了多少个权限就回调多少次,相当于 flatMap 的效果
if (permission.granted) {
Toast.makeText(this, "已赋予权限:" + permission.name, Toast.LENGTH_SHORT).show();
} else if (permission.shouldShowRequestPermissionRationale) { //拒绝了权限,但是没有勾选"ask never again"
Toast.makeText(this, "已拒绝权限:" + permission.name + " ,但可以继续申请", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "已拒绝权限:" + permission.name + " ,并且不会再显示", Toast.LENGTH_SHORT).show();
}
});
break;
case 4:
RxView.clicks(view)
.compose(new RxPermissions(this).ensureEachCombined(Manifest.permission.CALL_PHONE, Manifest.permission.SEND_SMS))
.subscribe(permission -> {//只回调一次,回调的 permission 的属性值是多个原始 permission 的组合值
if (permission.granted) {
Toast.makeText(this, "已赋予全部所需的权限:" + permission.name, Toast.LENGTH_SHORT).show();
} else if (permission.shouldShowRequestPermissionRationale) { //拒绝了权限,但是没有勾选"ask never again"
Toast.makeText(this, "有权限被拒绝:" + permission.name + " ,但可以继续申请", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "有权限被拒绝:" + permission.name + " ,并且不会再显示", Toast.LENGTH_SHORT).show();
}
});
break;
case 5:
boolean isGranted = new RxPermissions(this).isGranted(Manifest.permission.CAMERA);
Toast.makeText(this, "是否已赋予权限:" + isGranted, Toast.LENGTH_SHORT).show();
new RxPermissions(this)
.shouldShowRequestPermissionRationale(this, Manifest.permission.CALL_PHONE, Manifest.permission.SEND_SMS)
.subscribe(granted -> Toast.makeText(this, granted ? "全部权限已授权,或有权限被拒绝但可以继续申请" :
"有权限被拒绝,并且不会再显示", Toast.LENGTH_SHORT).show());
break;
default:
break;
}
}
}
x
1
public class RxPermissionsFragmentActivity extends FragmentActivity {
2
private TextView view;
3
4
5
protected void onCreate( Bundle savedInstanceState) {
6
super.onCreate(savedInstanceState);
7
view = new TextView(this);
8
view.setBackgroundColor(0xff00ff00);
9
setContentView(view);
10
int type = getIntent().getIntExtra("type", 0);
11
init(type);
12
}
13
14
private void init(int type) {
15
switch (type) {
16
case 0:
17
new RxPermissions(this)
18
.request(Manifest.permission.WRITE_EXTERNAL_STORAGE)
19
.subscribe(granted -> {
20
if (granted) { //在 Android M(6.0) 之前始终为true
21
Toast.makeText(this, "已赋予权限", Toast.LENGTH_SHORT).show();
22
} else {
23
Toast.makeText(this, "已拒绝权限", Toast.LENGTH_SHORT).show();
24
}
25
});
26
break;
27
case 1:
28
RxView.clicks(view)
29
.compose(new RxPermissions(this).ensure(Manifest.permission.CAMERA))
30
.subscribe(granted -> Toast.makeText(this, granted ? "已赋予权限" : "已拒绝权限", Toast.LENGTH_SHORT).show());
31
break;
32
case 2:
33
new RxPermissions(this)
34
.request(Manifest.permission.CALL_PHONE, Manifest.permission.SEND_SMS)//只有所有权限都赋予了才会回调成功
35
.subscribe(granted -> Toast.makeText(this, granted ? "已赋予权限" : "已拒绝权限", Toast.LENGTH_SHORT).show());
36
RxView.clicks(view)
37
.compose(new RxPermissions(this).ensure(Manifest.permission.CALL_PHONE, Manifest.permission.SEND_SMS))
38
.subscribe(granted -> Toast.makeText(this, granted ? "已赋予权限" : "已拒绝权限", Toast.LENGTH_SHORT).show());
39
break;
40
case 3:
41
RxView.clicks(view)
42
.compose(new RxPermissions(this).ensureEach(Manifest.permission.CALL_PHONE, Manifest.permission.SEND_SMS))
43
.subscribe(permission -> {//申请了多少个权限就回调多少次,相当于 flatMap 的效果
44
if (permission.granted) {
45
Toast.makeText(this, "已赋予权限:" + permission.name, Toast.LENGTH_SHORT).show();
46
} else if (permission.shouldShowRequestPermissionRationale) { //拒绝了权限,但是没有勾选"ask never again"
47
Toast.makeText(this, "已拒绝权限:" + permission.name + " ,但可以继续申请", Toast.LENGTH_SHORT).show();
48
} else {
49
Toast.makeText(this, "已拒绝权限:" + permission.name + " ,并且不会再显示", Toast.LENGTH_SHORT).show();
50
}
51
});
52
break;
53
case 4:
54
RxView.clicks(view)
55
.compose(new RxPermissions(this).ensureEachCombined(Manifest.permission.CALL_PHONE, Manifest.permission.SEND_SMS))
56
.subscribe(permission -> {//只回调一次,回调的 permission 的属性值是多个原始 permission 的组合值
57
if (permission.granted) {
58
Toast.makeText(this, "已赋予全部所需的权限:" + permission.name, Toast.LENGTH_SHORT).show();
59
} else if (permission.shouldShowRequestPermissionRationale) { //拒绝了权限,但是没有勾选"ask never again"
60
Toast.makeText(this, "有权限被拒绝:" + permission.name + " ,但可以继续申请", Toast.LENGTH_SHORT).show();
61
} else {
62
Toast.makeText(this, "有权限被拒绝:" + permission.name + " ,并且不会再显示", Toast.LENGTH_SHORT).show();
63
}
64
});
65
break;
66
case 5:
67
boolean isGranted = new RxPermissions(this).isGranted(Manifest.permission.CAMERA);
68
Toast.makeText(this, "是否已赋予权限:" + isGranted, Toast.LENGTH_SHORT).show();
69
70
new RxPermissions(this)
71
.shouldShowRequestPermissionRationale(this, Manifest.permission.CALL_PHONE, Manifest.permission.SEND_SMS)
72
.subscribe(granted -> Toast.makeText(this, granted ? "全部权限已授权,或有权限被拒绝但可以继续申请" :
73
"有权限被拒绝,并且不会再显示", Toast.LENGTH_SHORT).show());
74
break;
75
default:
76
break;
77
}
78
}
79
}
2018-8-30
以上是关于RxPermissions 动态权限 简介 案例的主要内容,如果未能解决你的问题,请参考以下文章
Android6.0------权限申请RxPermissions
Android6.0执行时权限解析,RxPermissions的使用,自己封装一套权限框架