第五单元

2020-12-11  本文已影响0人  贤兵

一、RxPermission

1、背景

从Android6.0开始,权限分为一般权限和危险权限。危险权限除了需要再manifest中配置以外,还必须在相应功能使用前动态申请并得到用户授权。


图片.png

2、系统重要方法

1. ContextCompat.checkSelfPermission

检查应用是否具有某个危险权限。如果应用具有此权限,方法将返回 PackageManager.PERMISSION_GRANTED,并且应用可以继续操作。如果应用不具有此权限,方法将返回 PackageManager.PERMISSION_DENIED,且应用必须明确向用户要求权限。

2. ActivityCompat.requestPermissions

应用可以通过这个方法动态申请权限,调用后会弹出一个对话框提示用户授权所申请的权限。

3. ActivityCompat.shouldShowRequestPermissionRationale

如果应用之前请求过此权限但用户拒绝了请求,此方法将返回 true。如果用户在过去拒绝了权限请求,并在权限请求系统对话框中选择了 Don't ask again 选项,此方法将返回 false。如果设备规范禁止应用具有该权限,此方法也会返回 false。

4. onRequestPermissionsResult

当应用请求权限时,系统将向用户显示一个对话框。当用户响应时,系统将调用应用的 onRequestPermissionsResult() 方法,向其传递用户响应,处理对应的场景。

3、例子

public class DemoActivity extends AppCompatActivity {
    private static final int REQUEST_CALL_PHONE = 100;
    private static final int REQUEST_ALL = 101;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_demo);

        findViewById(R.id.button1).setOnClickListener(v -> {
            test1();
        });

        findViewById(R.id.button2).setOnClickListener(v -> {
            test2();
        });
    }

    private void test1() {
        int callPhoneState = ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE);
        if (callPhoneState == PackageManager.PERMISSION_GRANTED) {
            callPhone();
        } else {
            ActivityCompat.requestPermissions(this, new String[]{
                    Manifest.permission.CALL_PHONE
            }, REQUEST_CALL_PHONE);
        }
    }

    private void test2() {
        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.CALL_PHONE, Manifest.permission.WRITE_EXTERNAL_STORAGE},
                REQUEST_ALL);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull @org.jetbrains.annotations.NotNull String[] permissions, @NonNull @org.jetbrains.annotations.NotNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (REQUEST_CALL_PHONE == requestCode) {
            if (permissions[0] == Manifest.permission.CALL_PHONE && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                callPhone();
            }
        } else if (REQUEST_ALL == requestCode) {
            if (permissions.length == grantResults.length) {
                boolean allGranted = true;
                for (int result : grantResults) {
                    if (result != PackageManager.PERMISSION_GRANTED) {
                        allGranted = false;
                        break;
                    }
                }
                if (allGranted) {
                    callPhone();
                }
            }
        }
    }

    private void callPhone() {
        Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:18600955495"));
        startActivity(intent);
    }
}

4、RxPermission

1. 基本信息

This library allows the usage of RxJava with the new Android M permission model.
https://github.com/tbruyelle/RxPermissions

2.依赖
allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

dependencies {
    implementation 'com.github.tbruyelle:rxpermissions:0.12'
    implementation "io.reactivex.rxjava3:rxjava:3.0.8"
    implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
}
3.例子
package com.xianbing.permissiondemo;

import android.Manifest;
import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import com.tbruyelle.rxpermissions3.Permission;
import com.tbruyelle.rxpermissions3.RxPermissions;
import io.reactivex.rxjava3.functions.Consumer;

public class DemoActivity2 extends AppCompatActivity {
    final RxPermissions rxPermissions = new RxPermissions(this);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_demo2);
        findViewById(R.id.button1).setOnClickListener(v -> {
            demo1();
        });

        findViewById(R.id.button2).setOnClickListener(v -> {
            demo2();
        });

        findViewById(R.id.button3).setOnClickListener(v -> {
            demo3();
        });

        findViewById(R.id.button4).setOnClickListener(v -> {
            demo4();
        });
    }

    private void demo1() {
        rxPermissions.request(Manifest.permission.CALL_PHONE).subscribe(new Consumer<Boolean>() {
            @Override
            public void accept(Boolean granted) throws Throwable {
                Log.i("Simon", "demo1 request CALL_PHONE aBoolean: " + granted);
            }
        });
    }

    private void demo2() {
        //同时请求多个权限,只有同意了,才会回调true
        rxPermissions
                .request(Manifest.permission.CALL_PHONE,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE)
                .subscribe(new Consumer<Boolean>() {
                    @Override
                    public void accept(Boolean granted) throws Throwable {
                        Log.i("Simon", "demo2 request CALL_PHONE android WRITE_EXTERNAL_STORAGE aBoolean: " + granted);
                        if (granted) {
                            //所有权限都授予
                            // All requested permissions are granted
                        } else {
                            //至少一个权限没有被授予
                            // At least one permission is denied
                        }
                    }
                });
    }

    private void demo3() {
        //每一个权限的请求结果都会回调
        rxPermissions
                .requestEach(Manifest.permission.CALL_PHONE,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE)
                .subscribe(new Consumer<Permission>() {
                    @Override
                    public void accept(Permission permission) throws Throwable {
                        Log.i("Simon", "demo3 requestEach permission: " + permission);
                        if (permission.granted) {
                            //权限被授予
                            // `permission.name` is granted !
                        } else if (permission.shouldShowRequestPermissionRationale) {
                            //权限被决绝,并且没有选中"不再询问"
                            // Denied permission without ask never again
                        } else {
                            //权限被决绝,并且选中"不再询问"
                            // Denied permission with ask never again
                            // Need to go to the settings
                        }
                    }
                });
    }

    private void demo4() {
        rxPermissions
                .requestEachCombined(Manifest.permission.CALL_PHONE,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE)
                .subscribe(permission -> { // will emit 1 Permission object
                    Log.i("Simon", "demo4 requestEachCombined permission: " + permission);
                    if (permission.granted) {
                        //所有权限都同意授予
                        // All permissions are granted !
                    } else if (permission.shouldShowRequestPermissionRationale) {
                        //至少有一个权限被拒绝,但并没有选择"不再询问"
                        // At least one denied permission without ask never again
                    } else {
                        //至少一个权限被拒绝,并且选择"不再询问"
                        // At least one denied permission with ask never again
                        // Need to go to the settings
                    }
                });
    }
}

二、RxLifeCycle

1、RxLifeCycle是什么

Lifecycle handling APIs for Android apps using RxJava
This library allows one to automatically complete sequences based on a second lifecycle stream.
This capability is useful in Android, where incomplete subscriptions can cause memory leaks.
https://github.com/trello/RxLifecycle

2、使用

1.依赖
implementation 'com.trello.rxlifecycle4:rxlifecycle:4.0.2'
// If you want to bind to Android-specific lifecycles
implementation 'com.trello.rxlifecycle4:rxlifecycle-android:4.0.2'
// If you want pre-written Activities and Fragments you can subclass as providers
implementation 'com.trello.rxlifecycle4:rxlifecycle-components:4.0.2'
2.例子
public class DemoActivity3 extends RxAppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_demo3);

        findViewById(R.id.button).setOnClickListener(v -> {
            test();
        });
    }

    private void test() {
        Observable.interval(1, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .compose(bindUntilEvent(ActivityEvent.DESTROY))
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                    }

                    @Override
                    public void onNext(@NonNull Long aLong) {
                        Log.i("Simon", "test onNext: " + aLong);
                    }

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

                    @Override
                    public void onComplete() {

                    }
                });
    }
}

修改的地方:
1、AppCompatActivity改为RxAppCompatActivity
2、新增: .compose(bindUntilEvent(ActivityEvent.DESTROY))

上一篇下一篇

猜你喜欢

热点阅读