美文网首页
关于动态权限申请遇到的坑

关于动态权限申请遇到的坑

作者: 三棵柚子 | 来源:发表于2017-11-28 17:44 被阅读0次

    前言


    众所周知,谷歌在Android 6.0提出了危险权限这个概念,让我们开发应用的时候,需要花一些时间去关注动态权限的处理.今天我就把在动态权限这块地方遇到的坑给大家说说.


    我们都知道,在安卓开发中,经常需要用到几个比较常见的权限,例如:

               Manifest.permission.READ_EXTERNAL_STORAGE,    //储存空间权限
                Manifest.permission.READ_PHONE_STATE,        //手机状态权限
                Manifest.permission.ACCESS_FINE_LOCATION,//位置访问权限
                Manifest.permission.CAMERA  //相机权限
                ```
    

    我们在做动态权限适配的时候一般都需要多个权限同时进行处理,
    ,刚刚开始接触动态权限的时候,感觉一个权限还比较好处理,逻辑是:

    第一,先判断是否获得权限
    第二,如果没有,就去申请权限,处理回调方法然后执行想要的逻辑

    但是多个权限,就没有我们想象的那么简单了,你需要关注到每个权限是否都已经有申请过,由于公司的APP的设计是在Splash界面需要同时获得多个权限,我必须要保证每个权限都要被获取,因此我刚刚开始的想法是这样的:

    第一步, 判断权限. 遍历所有权限进行判断权限是否都被获取,得到一个是否全部获得权限的标记,通过标记判断是否需要进行权限申请。

    第二步, 申请权限. 如果当中有没有获取权限的,那就需要申请权限, 在权限申请回调拿到结果, 判断没有被申请通过的权限, 存放在一个集合中, 然后再去进行单个权限申请,依然对返回值进行判断,如果不通过就成重新把未通过的权限进行申请,通过就进入程序.

    这种类似于循环式的做法,看起来可行,实则漏洞百出,我似乎忽略了一种情况,那就是当用户拒绝权限并禁止访问的时候,APP会进入假死状态,一直会卡在Splash界面,后来我也在网上找了一些资料,发现shouldShowRequestPermissionRationale(String permisssion) 这个方法可以帮我解决问题,于是我逻辑是这样写的!

    boolean flag=false;
    for (String permission : permissions) {
                if (!shouldShowRequestPermissionRationale(permission)) {
                    flag = true;
                    break;
                }
            }
    if(flag){
    //为true 就进入权限设置
    }else{
      //为false 表示没有被禁止询问 直接进行上述我写的逻辑(判断、申请权限等)
    }
    
    

    于是,我卸载重新安装应用,部署在模拟器上,一运行,出BUG了
    我发现,如果我是重新安装应用,程序直接引导我去设置界面设置权限,连申请权限都不走了!我心里一万只草泥马奔腾而过,这是什么鬼?难道这个shouldShowRequestPermissionRationale()的不是关心不再询问[checkbox]的结果么?

    于是我再新建一个应用进行测试,这次我转换了一下我的思路,我先用单个权限进行测试,步骤如下:

    if (checkSelfPermission(permission) == PackageManager.PERMISSION_DENIED) {  //先对权限进行判断
                if (shouldShowRequestPermissionRationale(permission)) {
                    LogUtils.d("方法返回值为true时");      //系统或人为关闭时,可以跳转到设置页面进行设置
                     new AlertDialog.Builder(this)
                            .setMessage("为了保证应用能够正常使用,请前往设置如下权限:" +
                                    "位置访问权限、相机权限、储存空间权限")
                            .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                    intent.setData(Uri.fromParts("package", getPackageName(), null));
                                    startActivityForResult(intent, REQUEST_PERMISSION_SETTING);
                                }
                            }).show();
                } else {
                    LogUtils.d("方法返回值为false时");
                    requestPermissions(new String[]{permission}, REQUEST_SINGLE_PERMISSION);
                }
            } else {
                //权限已经被申请
                LogUtils.d("权限被接受");
            }
    
    

    原来还是因为这个方法[shouldShowRequestPermissionRationale(xxx)]导致的,当为true的时候,是表示有人为选中拒绝(被禁止询问),或者是系统默认拒绝状态(一些厂商会将底层权限设置进行修改,比如小米等),而为false时 只是表示权限没有被通过的意思.我去 ,原来网上的文章也有时候会搞错,真心尴尬。


    最后,如果大家在开发中,遇到动态权限处理,最好还是用别人的框架吧,除非你时间充裕,并且想学习下动态权限其中的原理,否则 ,劝大家还是用框架,毕竟框架用起来方便,而且考虑比较全面.

    相关文章

      网友评论

          本文标题:关于动态权限申请遇到的坑

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