RxPermissions
1.1、RxPermissions简介

RxPermissions是对Android6.0动态申请权限机制的简化的库,使用它能很方便的处理权限问题。

RxPermissionsGitHub上的网址:https://github.com/tbruyelle/RxPermissions

1.2、在build.gradle里面添加依赖

RxPermissions v1的依赖:

compile 'com.tbruyelle.rxpermissions:rxpermissions:0.9.4@aar'

RxPermissions v2的依赖:

compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.4@aar'

RxAndroid依赖RxJava,你可以指定RxJava的版本也可以不指定,让他自己处理依赖关系。

1.3、com.tbruyelle.rxpermissions2.Permission

com.tbruyelle.rxpermissions2.Permission是对申请的权限的结果表示。它的源码如下:

package com.tbruyelle.rxpermissions2;

public class Permission {
    public final String name;
    public final boolean granted;
    public final boolean shouldShowRequestPermissionRationale;

    public Permission(String name, boolean granted) {
        this(name, granted, false);
    }

    public Permission(String name, boolean granted, boolean shouldShowRequestPermissionRationale) {
        this.name = name;
        this.granted = granted;
        this.shouldShowRequestPermissionRationale = shouldShowRequestPermissionRationale;
    }

    @Override
    @SuppressWarnings("SimplifiableIfStatement")
    public boolean equals(final Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        final Permission that = (Permission) o;

        if (granted != that.granted) return false;
        if (shouldShowRequestPermissionRationale != that.shouldShowRequestPermissionRationale)
            return false;
        return name.equals(that.name);
    }

    @Override
    public int hashCode() {
        int result = name.hashCode();
        result = 31 * result + (granted ? 1 : 0);
        result = 31 * result + (shouldShowRequestPermissionRationale ? 1 : 0);
        return result;
    }

    @Override
    public String toString() {
        return "Permission{" +
                "name='" + name + '\'' +
                ", granted=" + granted +
                ", shouldShowRequestPermissionRationale=" + shouldShowRequestPermissionRationale +
                '}';
    }
}

需要注意的是,这个类的成员变量是公开的,我们可以直接使用它。

name是请求的权限名字。

granted表示用户是否授权了,如果您的targetSdkVersion被设置成了小于23, 系统根本就不会弹出让用户授权的弹出框,这时候,这个字段永远是true

shouldShowRequestPermissionRationale表示被用户拒绝了这个权限,并且也选择了不再提示, 那么以后我们就必须给用户提示,否则用户会觉得莫名其妙。

1.4、RxPermissions
1.4.1、构造方法
public RxPermissions(@NonNull Activity activity)
1.4.2、public Observable<Boolean> request(final String... permissions)

申请权限。结果只是一个Boolean值,表示是否申请成功。

示例1(申请一个权限):

RxPermissions rxPermissions = new RxPermissions(this);
rxPermissions
        .request(Manifest.permission.READ_EXTERNAL_STORAGE)
        .subscribe(new Observer<Boolean>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {

            }

            @Override
            public void onNext(@NonNull Boolean granted) {
                Log.d(TAG, "onNext()");
                if (granted) { //Manifest.permission.READ_EXTERNAL_STORAGE权限被授权了
                    //TODO
                }
            }

            @Override
            public void onError(@NonNull Throwable e) {

            }

            @Override
            public void onComplete() {

            }
        });

示例2(申请多个权限):

RxPermissions rxPermissions = new RxPermissions(this);
rxPermissions
        .request(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
        .subscribe(new Observer<Boolean>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {

            }

            @Override
            public void onNext(@NonNull Boolean granted) {
                Log.d(TAG, "onNext()");
                if (granted) { //Manifest.permission.READ_EXTERNAL_STORAGE和Manifest.permission.WRITE_EXTERNAL_STORAGE两个权限都被授权了
                    //TODO
                } else { //Manifest.permission.READ_EXTERNAL_STORAGE和Manifest.permission.WRITE_EXTERNAL_STORAGE两个权限中至少有一个权限没有被授权,但你不知道是哪个权限没有被授权

                }
            }

            @Override
            public void onError(@NonNull Throwable e) {

            }

            @Override
            public void onComplete() {

            }
        });
1.4.3、public Observable<Permission> requestEach(final String... permissions)

申请权限。申请几个权限,就会发送几个Permission结果。

示例1(申请一个权限):

RxPermissions rxPermissions = new RxPermissions(this);
rxPermissions
        .requestEach(Manifest.permission.READ_EXTERNAL_STORAGE)
        .subscribe(new Observer<Permission>() {
    @Override
    public void onSubscribe(@NonNull Disposable d) {
        Log.d(TAG, "onSubscribe()");
    }

    @Override
    public void onNext(@NonNull Permission permission) {
        Log.d(TAG, "onNext()" + permission);
        if (permission.granted) {
            //TODO
        } else if (permission.shouldShowRequestPermissionRationale){
            //客户没有授权,需要提示用户
            Toast.makeText(MainActivity.this, "您曾经选择过不授权,您想再授权,请到设置里进行授权", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onError(@NonNull Throwable e) {
        Log.e(TAG, "onError()", e);
    }

    @Override
    public void onComplete() {
        Log.d(TAG, "onComplete()");
    }
});

示例2(申请多个权限):

RxPermissions rxPermissions = new RxPermissions(this);
rxPermissions
        .requestEach(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
        .subscribe(new Observer<Permission>() {
    @Override
    public void onSubscribe(@NonNull Disposable d) {
        Log.d(TAG, "onSubscribe()");
    }

    @Override
    public void onNext(@NonNull Permission permission) {
        Log.d(TAG, "onNext()" + permission);
        if (Manifest.permission.READ_EXTERNAL_STORAGE.equals(permission.name)) {
            if (permission.granted) {

            } else if (permission.shouldShowRequestPermissionRationale){
                //客户没有授权,需要提示用户
                Toast.makeText(MainActivity.this, "您曾经选择过不授权,您想再授权,请到设置里进行授权", Toast.LENGTH_SHORT).show();
            }
        } else if (Manifest.permission.WRITE_EXTERNAL_STORAGE.equals(permission.name)) {
            if (permission.granted) {

            } else if (permission.shouldShowRequestPermissionRationale){
                //客户没有授权,需要提示用户
                Toast.makeText(MainActivity.this, "您曾经选择过不授权,您想再授权,请到设置里进行授权", Toast.LENGTH_SHORT).show();
            }
        }
    }

    @Override
    public void onError(@NonNull Throwable e) {
        Log.e(TAG, "onError()", e);
    }

    @Override
    public void onComplete() {
        Log.d(TAG, "onComplete()");
    }
});
1.4.4、public <T> ObservableTransformer<T, Boolean< ensure(final String... permissions)

申请权限。无论申请多少个权限,只发射一个结果。这个方法的返回值通常与compose操作符一起使用, 或者与RxBinding一起使用。

示例1(申请一个权限):

RxPermissions rxPermissions = new RxPermissions(this);
RxView.clicks(findViewById(R.id.text_view))
        .compose(rxPermissions.ensure(Manifest.permission.READ_EXTERNAL_STORAGE))
        .subscribe(new Observer<Boolean>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {
                Log.d(TAG, "onSubscribe()");
            }

            @Override
            public void onNext(@NonNull Boolean granted) {
                Log.d(TAG, "onNext()");
                if (granted) { //Manifest.permission.READ_EXTERNAL_STORAGE权限被授权了
                     //TODO
                }
            }

            @Override
            public void onError(@NonNull Throwable e) {
                Log.e(TAG, "onError()", e);
            }

            @Override
            public void onComplete() {
                Log.d(TAG, "onSubscribe()");
            }
        });

示例2(申请多个权限):

RxPermissions rxPermissions = new RxPermissions(this);
RxView.clicks(findViewById(R.id.text_view))
        .compose(rxPermissions.ensure(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE))
        .subscribe(new Observer<Boolean>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {
                Log.d(TAG, "onSubscribe()");
            }

            @Override
            public void onNext(@NonNull Boolean granted) {
                Log.d(TAG, "onNext()");
                if (granted) { //Manifest.permission.READ_EXTERNAL_STORAGE和Manifest.permission.WRITE_EXTERNAL_STORAGE两个权限都被授权了
                    //TODO
                } else { //Manifest.permission.READ_EXTERNAL_STORAGE和Manifest.permission.WRITE_EXTERNAL_STORAGE两个权限中至少有一个权限没有被授权,但你不知道是哪个权限没有被授权
                    //TODO
                }
            }

            @Override
            public void onError(@NonNull Throwable e) {
                Log.e(TAG, "onError()", e);
            }

            @Override
            public void onComplete() {
                Log.d(TAG, "onSubscribe()");
            }
        });
1.4.5、public <T> ObservableTransformer<T, Boolean< ensure(final String... permissions)

申请权限。申请几个权限,就会发送几个Permission结果。这个方法的返回值通常与compose操作符一起使用, 或者与RxBinding一起使用。

示例1(申请一个权限):

RxPermissions rxPermissions = new RxPermissions(this);
RxView.clicks(findViewById(R.id.text_view))
        .compose(rxPermissions.ensureEach(Manifest.permission.READ_EXTERNAL_STORAGE))
        .subscribe(new Observer<Permission>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {
                Log.d(TAG, "onSubscribe()");
            }

            @Override
            public void onNext(@NonNull Permission permission) {
                Log.d(TAG, "onNext()" + permission);
                if (permission.granted) {
                     //TODO
                } else if (permission.shouldShowRequestPermissionRationale) {
                     //客户没有授权,需要提示用户
                     Toast.makeText(MainActivity.this, "您曾经选择过不授权,您想再授权,请到设置里进行授权", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onError(@NonNull Throwable e) {
                Log.e(TAG, "onError()", e);
            }

            @Override
            public void onComplete() {
                Log.d(TAG, "onSubscribe()");
            }
        });

示例2(申请多个权限):

RxPermissions rxPermissions = new RxPermissions(this);
RxView.clicks(findViewById(R.id.text_view))
        .compose(rxPermissions.ensureEach(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE))
        .subscribe(new Observer<Permission>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {
                Log.d(TAG, "onSubscribe()");
            }

            @Override
            public void onNext(@NonNull Permission permission) {
                Log.d(TAG, "onNext()" + permission);
                if (Manifest.permission.READ_EXTERNAL_STORAGE.equals(permission.name)) {
                    if (permission.granted) {

                    } else if (permission.shouldShowRequestPermissionRationale) {
                        //客户没有授权,需要提示用户
                        Toast.makeText(MainActivity.this, "您曾经选择过不授权,您想再授权,请到设置里进行授权", Toast.LENGTH_SHORT).show();
                    }
                } else if (Manifest.permission.WRITE_EXTERNAL_STORAGE.equals(permission.name)) {
                    if (permission.granted) {
                        //TODO
                    } else if (permission.shouldShowRequestPermissionRationale) {
                        //客户没有授权,需要提示用户
                        Toast.makeText(MainActivity.this, "您曾经选择过不授权,您想再授权,请到设置里进行授权", Toast.LENGTH_SHORT).show();
                    }
                }
            }

            @Override
            public void onError(@NonNull Throwable e) {
                Log.e(TAG, "onError()", e);
            }

            @Override
            public void onComplete() {
                Log.d(TAG, "onSubscribe()");
            }
        });
1.4.6、public boolean isGranted(String permission)

判断权限是否已经被授权了。

示例:

RxPermissions rxPermissions = new RxPermissions(this);
if (rxPermissions.isGranted(Manifest.permission.READ_EXTERNAL_STORAGE)) {

} else {

}
1.4.7、public boolean isRevoked(String permission)

判断权限是否已经被决绝了。

示例:

RxPermissions rxPermissions = new RxPermissions(this);
if (rxPermissions.isRevoked(Manifest.permission.READ_EXTERNAL_STORAGE)) {

} else {

}
1.4.8、public void setLogging(boolean logging)

设置日志开关。可以通过adb logcat观察日志,以RxPermissions作为TAG

示例(打开日志开关):

rxPermissions.setLogging(true);