Android 权限管理(原生、EasyPermissions、RxPermissions)

简介: 前言:动态权限管理是Android6.0(Build.VERSION_CODES.M = Api23)推出的,提醒用户当前APP所需要的权限,防止滥用。

前言:动态权限管理是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、第一次询问权限-》拒绝权限-》再次询问权限-》不再询问(再次询问同样权限也不会有弹框,直接拒绝)
--------------------几张图片说明--------------------
img_552d85ce7650c44debd1c2614fd6c8a3.png
first_request.png

img_ac762347a2af181ef3bc894167807a10.png
not_first_request.png

img_7abc9ce940585fc4a75f7beba746a9b0.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,多个权限询问等

目录
相关文章
|
1月前
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
160 4
|
7月前
|
数据采集 小程序 数据可视化
智慧校园电子班牌管理系统源码 Java Android原生
家长通过家长小程序端随时了解孩子在校的情况,实时接收学生的出勤情况,学生到校、离校时间。随时了解学生在校的表现、学生成绩排名,及时与教师沟通,关注孩子的健康成长。
78 0
智慧校园电子班牌管理系统源码 Java Android原生
|
安全 Android开发 开发者
Android 原生 Picture in Picture 画中画功能避坑指南(下)
Android 原生 Picture in Picture 画中画功能避坑指南(下)
326 0
|
JavaScript Java Android开发
Cocos Creator Android 平台 Facebook 原生登录(二)
Cocos Creator Android 平台 Facebook 原生登录
228 0
|
开发工具 Android开发 数据安全/隐私保护
Cocos Creator Android 平台 Facebook 原生登录(一)
Cocos Creator Android 平台 Facebook 原生登录
553 0
|
4月前
|
Android开发
错误记录:调用原生TvSettings 的 com.android.tv.settings.device.storage.ResetActivity 无法启动
本文记录了一个Android TV设置中由于未设置`android:exported="true"`导致`com.android.tv.settings.device.storage.ResetActivity`无法被第三方app启动的错误,并通过添加该属性成功解决了问题。
69 1
|
7月前
|
API 开发工具 Android开发
调用Android原生@SystemApi、@Hide方法
调用Android原生@SystemApi、@Hide方法
634 1
|
7月前
|
安全 Java Shell
Android 权限管理
Android 权限管理
176 0
|
7月前
|
数据采集 小程序 数据可视化
Java Android原生智慧校园管理系统源码
对班牌的考试模式、班牌模式上课模式进行设置及管理,设置成功后,班牌端将同步应用。
78 0
|
前端开发 Android开发
前端项目实战壹-安卓4.4/6.0无法安装非原生项目无法渲染样式
前端项目实战壹-安卓4.4/6.0无法安装非原生项目无法渲染样式
65 0