美文网首页
第五单元

第五单元

作者: 贤兵 | 来源:发表于2020-12-11 01:45 被阅读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))

    相关文章

      网友评论

          本文标题:第五单元

          本文链接:https://www.haomeiwen.com/subject/ghorgktx.html