Android 权限管理(原生、EasyPermissions、

作者: Kandy_JS | 来源:发表于2018-01-25 20:54 被阅读5001次

    前言:动态权限管理是Android6.0(Build.VERSION_CODES.M = Api23)推出的,提醒用户当前APP所需要的权限,防止滥用。这些权限一般分为三种:(1)普通权限:直接manifest清单文件中写上注册就行了 (2)危险权限:需要动态申请 (3)特殊权限:此处暂不说明。
    注意:这里我们就按照原生,和git上比较出名的第三方权限管理工具,EasyPermissions和RxPermissions

    一、参考

    1、android6.0权限管理工具EasyPermissionUtil
    2、Android M 新的运行时权限开发者需要知道的一切
    3、EasyPermissions Git Url
    4、RxPermissions Git Url

    二、异常

    异常:java.lang.SecurityException: getDeviceId: Neither user 10127 nor current process has android.permission.READ_PHONE_STATE.
    解释:走到方法getDeviceId这里异常,缺失权限:READ_PHONE_STATE,先检查manifest.xml清单文件里有没有,没有补上,如果有,那么这个权限就得动态获取了。

    三、流程

    1、第一次询问权限 -》允许权限(再次询问同样权限也不会弹框,已注册)
    2、第一次询问权限-》拒绝权限-》再次询问权限-》允许权限(再次询问同样权限也不会弹框,已注册)
    3、第一次询问权限-》拒绝权限-》再次询问权限-》不再询问(再次询问同样权限也不会有弹框,直接拒绝)
    --------------------几张图片说明--------------------
    first_request.png
    not_first_request.png
    not_first_request_and_not_ask_again.png

    四、实例

    1、原生,比较长且繁琐,先理解下
        /**
         * 测试:原生动态权限管理
         * */
        private void testOrgPermission(){
    
            //判断当前系统是否高于或等于6.0
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                //已注册权限
                if (ContextCompat.checkSelfPermission(instance, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
                    //todo something
                    LogUtil.i("testOrgPermission() : this camera permission is granted");
                }
    
                //未注册权限,申请权限
                else {
                    // v4向下兼容:询问权限(这里可以一个,也可以多个)
                    // 拒绝权限后再次询问
                    LogUtil.i("testOrgPermission() : this camera premission is denied , " +
                            "ready to request this permission");
                    ActivityCompat.requestPermissions(instance,
                            new String[]{Manifest.permission.CAMERA},
                            REQUEST_PERMISSION_CAMERA_CODE);
                }
            }
            //当前系统小于6.0,无需动态申请权限
            else {
                //todo something
            }
    
        }
    
        /**
         * 询问权限的回调函数
         * */
        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    
            switch (requestCode){
                case REQUEST_PERMISSION_CAMERA_CODE:
                    int cameraResult = grantResults[0];//相机权限
                    boolean cameraGranted = cameraResult == PackageManager.PERMISSION_GRANTED;//拍照权限
    
                    //注册权限
                    if (cameraGranted) {
                        LogUtil.i("onRequestPermissionsResult() : "+permissions[0]+
                                " request granted , to do something...");
                        //todo something
                    }
    
                    //拒绝注册权限
                    else {
    
                        //无权限,且被选择"不再提醒":提醒客户到APP应用设置中打开权限
                        if(!ActivityCompat.shouldShowRequestPermissionRationale(instance,Manifest.permission.CAMERA)){
                            LogUtil.e("onRequestPermissionsResult() : this "+permissions[0]+" is denied " +
                                    "and never ask again");
                            ToastUtil.showShort(instance,"拒绝权限,不再弹出询问框,请前往APP应用设置中打开此权限");
                            //todo nothing
                        }
    
                        //无权限,只是单纯被拒绝
                        else{
                            LogUtil.e("onRequestPermissionsResult() : "+permissions[0]+"request denied");
                            ToastUtil.showShort(instance,"拒绝权限,等待下次询问哦");
                            //todo request permission again
                        }
    
    
                    }
                    break;
    
                default:break;
            }
    
        }
    
    2、EasyPermissions:挺简洁的
    //build中依赖easypermissions
    dependencies {
        implementation 'pub.devrel:easypermissions:1.1.2'
    }
    
    #notice:这里要实现回调接口 Activity implements EasyPermissions.PermissionCallbacks
    
        /**
         * 测试:EasyPermission
         * https://github.com/googlesamples/easypermissions
         * */
        private void testEasyPermission(){
            String[] perms = {Manifest.permission.CAMERA};
            if (EasyPermissions.hasPermissions(this, perms)) {
                //todo something
                LogUtil.i("testEasyPermission() : this camera permission is granted");
            } else {
                LogUtil.i("testEasyPermission() : this camera premission is denied , " +
                        "ready to request this permission");
                EasyPermissions.requestPermissions(this, "你TM开相机权限啊!!",
                        REQUEST_PERMISSION_CAMERA_CODE, perms);
            }
    
    //自定义询问框内容部分,可试试看
    //        EasyPermissions.requestPermissions(
    //                new PermissionRequest.Builder(this, RC_CAMERA_AND_LOCATION, perms)
    //                        .setRationale(R.string.camera_and_location_rationale)
    //                        .setPositiveButtonText(R.string.rationale_ask_ok)
    //                        .setNegativeButtonText(R.string.rationale_ask_cancel)
    //                        .setTheme(R.style.my_fancy_style)
    //                        .build());
        }
    
        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            // Forward results to EasyPermissions
            EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
        }
    
        @Override
        public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) {
            //省略switch requestCode
            LogUtil.i("EasyPermission CallBack onPermissionsGranted() : "+perms.get(0)+
                               " request granted , to do something...");
            //todo somthing
        }
    
        @Override
        public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
            //省略switch requestCode
            //无权限,且被选择"不再提醒":提醒客户到APP应用设置中打开权限
            if (!ActivityCompat.shouldShowRequestPermissionRationale(instance, Manifest.permission.CAMERA)) {
                LogUtil.e("EasyPermission CallBack onPermissionsDenied() : this " + perms.get(0) + " is denied " +
                        "and never ask again");
                ToastUtil.showShort(instance, "拒绝权限,不再弹出询问框,请前往APP应用设置中打开此权限");
                //todo nothing
            }
    
            //无权限,只是单纯被拒绝
            else {
                LogUtil.e("EasyPermission CallBack onPermissionsDenied() : " + perms.get(0) + "request denied");
                ToastUtil.showShort(instance, "拒绝权限,等待下次询问哦");
                //todo request permission again
            }
    
    
        }
    
    3、RxPermissions:个人觉得更简洁,最好在activity的onCreate()中使用哦
    //build中依赖rxjava,rxandroid和rxpermissions
    dependencies {
        compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
        compile 'io.reactivex.rxjava2:rxjava:2.0.1'
        compile 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.5@aar'
    }
    
    /**
         * 测试:RxPermission
         * https://github.com/tbruyelle/RxPermissions
         * */
        private void testRxPermission(){
            RxPermissions rxPermissions = new RxPermissions(this); // where this is an Activity instance
    
            rxPermissions
                    .requestEach(
                            Manifest.permission.CAMERA)
                    .subscribe(new Consumer<Permission>() {
                        @Override
                        public void accept(Permission permission) throws Exception {
                            if (permission.granted) {
                                LogUtil.i("testRxPermission CallBack onPermissionsGranted() : "+permission.name+
                                        " request granted , to do something...");
                                //todo somthing
                            }
                            else if (permission.shouldShowRequestPermissionRationale) {
                                LogUtil.e("testRxPermission CallBack onPermissionsDenied() : " + permission.name + "request denied");
                                ToastUtil.showShort(instance, "拒绝权限,等待下次询问哦");
                                //todo request permission again
                            }
                            else {
                                LogUtil.e("testRxPermission CallBack onPermissionsDenied() : this " + permission.name + " is denied " +
                                        "and never ask again");
                                ToastUtil.showShort(instance, "拒绝权限,不再弹出询问框,请前往APP应用设置中打开此权限");
                                //todo nothing
                            }
                        }
                    });
    
        }
    

    其他自定义弹出框UI,多个权限询问等

    相关文章

      网友评论

        本文标题:Android 权限管理(原生、EasyPermissions、

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