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
    @Override
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
    @Override
5
    protected void onCreate(@Nullable 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

使用RxPermissions(基于RxJava2)

Android6.0执行时权限解析,RxPermissions的使用,自己封装一套权限框架

Android -- 开源库权限适配 RxPermissions 的基本使用

Android 中RxPermissions 的使用

第三方开源库-->那些酷炫的 权限 &数据库 开源库整理