【原创】Android申请权限的套路代码存档 教你判断第一次拒绝第二次拒绝和永久拒绝

具体参考https://www.jianshu.com/p/88e0a371161c

模板代码

  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (checkSelfPermission("android.permission.READ_EXTERNAL_STORAGE") == PackageManager.PERMISSION_GRANTED) {
                return false;
            }
            if (shouldShowRequestPermissionRationale("android.permission.READ_EXTERNAL_STORAGE")) {
                Toast.makeText(this, "请一定要给与权限!再给你一次选择的机会", Toast.LENGTH_SHORT).show();
                requestPermissions(new String[]{"android.permission.READ_EXTERNAL_STORAGE"}, 2);
            } else {
                requestPermissions(new String[]{"android.permission.READ_EXTERNAL_STORAGE"}, 2);//首次申请
            }
            return true;
        }
        return true;

循环单个申请、以此弹出申请对话框。

这个逻辑推荐在进入app的时候弄,我发现很多app懒得麻烦,一次性申请完。

 private void initRequestPermissionListAndStartRequest() {
        if (!PermissionsUtils.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE)) {
            waitRequestPermissionGroup.add(Manifest.permission.READ_PHONE_STATE);
        }
        if (!PermissionsUtils.checkSelfPermission(this, Manifest.permission.CAMERA)) {
            waitRequestPermissionGroup.add(Manifest.permission.CAMERA);
        }
        if (!PermissionsUtils.checkSelfPermission(this, Manifest.permission.CALL_PHONE)) {
            waitRequestPermissionGroup.add(Manifest.permission.CALL_PHONE);
        }

        if (!PermissionsUtils.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            waitRequestPermissionGroup.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        }

        if (!PermissionsUtils.checkSelfPermission(this, Manifest.permission.READ_SMS)) {
            waitRequestPermissionGroup.add(Manifest.permission.READ_SMS);
        }

        if (!PermissionsUtils.checkSelfPermission(this, Manifest.permission.ACCESS_NETWORK_STATE)) {
            waitRequestPermissionGroup.add(Manifest.permission.ACCESS_NETWORK_STATE);
        }

        if (!PermissionsUtils.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
            waitRequestPermissionGroup.add(Manifest.permission.READ_EXTERNAL_STORAGE);
        }

        if (!PermissionsUtils.checkSelfPermission(this, Manifest.permission.MODIFY_AUDIO_SETTINGS)) {
            waitRequestPermissionGroup.add(Manifest.permission.MODIFY_AUDIO_SETTINGS);
        }


        if (!PermissionsUtils.checkSelfPermission(this, Manifest.permission.INSTALL_SHORTCUT)) {
            waitRequestPermissionGroup.add(Manifest.permission.INSTALL_SHORTCUT);
        }

        if (!PermissionsUtils.checkSelfPermission(this, Manifest.permission.UNINSTALL_SHORTCUT)) {
            waitRequestPermissionGroup.add(Manifest.permission.UNINSTALL_SHORTCUT);
        }


        if (!PermissionsUtils.checkSelfPermission(this, Manifest.permission.SEND_SMS)) {
            waitRequestPermissionGroup.add(Manifest.permission.SEND_SMS);
        }

        if (!PermissionsUtils.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)) {
            waitRequestPermissionGroup.add(Manifest.permission.ACCESS_COARSE_LOCATION);
        }

        if (!PermissionsUtils.checkSelfPermission(this, Manifest.permission.RECEIVE_SMS)) {
            waitRequestPermissionGroup.add(Manifest.permission.RECEIVE_SMS);
        }

        if (!PermissionsUtils.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
            waitRequestPermissionGroup.add(Manifest.permission.ACCESS_FINE_LOCATION);
        }

        if (!PermissionsUtils.checkSelfPermission(this, Manifest.permission.WAKE_LOCK)) {
            waitRequestPermissionGroup.add(Manifest.permission.WAKE_LOCK);
        }

        if (!PermissionsUtils.checkSelfPermission(this, Manifest.permission.WRITE_CALL_LOG)) {
            waitRequestPermissionGroup.add(Manifest.permission.WRITE_CALL_LOG);
        }

        if (!PermissionsUtils.checkSelfPermission(this, Manifest.permission.KILL_BACKGROUND_PROCESSES)) {
            waitRequestPermissionGroup.add(Manifest.permission.KILL_BACKGROUND_PROCESSES);
        }

        if (!PermissionsUtils.checkSelfPermission(this, Manifest.permission.GET_TASKS)) {
            waitRequestPermissionGroup.add(Manifest.permission.GET_TASKS);
        }

        if (!PermissionsUtils.checkSelfPermission(this, Manifest.permission.VIBRATE)) {
            waitRequestPermissionGroup.add(Manifest.permission.VIBRATE);
        }


        if (!PermissionsUtils.checkSelfPermission(this, Manifest.permission.ACCESS_WIFI_STATE)) {
            waitRequestPermissionGroup.add(Manifest.permission.ACCESS_WIFI_STATE);
        }

  /*      if (!PermissionsUtils.checkSelfPermission(this, Manifest.permission.BLUETOOTH)) {
            waitRequestPermissionGroup.add(Manifest.permission.BLUETOOTH);
        }

*/
        if (waitRequestPermissionGroup.size() > 0) {

            PermissionsUtils.requestPermission(this, waitRequestPermissionGroup.get(0), REQUEST_LOOP);
        }

    }


  @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] gradResults) {

        if (requestCode == REQUEST_LOOP) {
            Log.w(TAG, "获取" + permissions[0] + "结果是成功:" + (gradResults.length > 0 && gradResults[0] == PackageManager.PERMISSION_GRANTED) + ",列表中共有" + waitRequestPermissionGroup.size() + "个权限等待申请!");
            if (waitRequestPermissionGroup.size() > 0) {
                waitRequestPermissionGroup.remove(0);

            }

            if (waitRequestPermissionGroup.size() > 0) {

                String premissionStr = waitRequestPermissionGroup.get(0);
                Log.w(TAG, "开始申请" + premissionStr + "权限!");
                if (PermissionsUtils.requestPermission(this, premissionStr, requestCode)) {
                    onRequestPermissionsResult(REQUEST_LOOP, new String[]{premissionStr}, new int[]{});
                }
            } else {
                if (gradResults.length > 0 && gradResults[0] != PackageManager.PERMISSION_GRANTED) {
                    AppContext.showToast(permissions[0] + "权限请求失败");
                }else{
                    Log.w(TAG, "所有权限申请完毕!");
                }
            }

        } 

}

写的不太对,这是比亚迪的测试结果,比较有争议的就是shouldShowRequestPermissionRationale实际上我测试的结果如果是第一次或者被永久拒绝就返回false, 如果没有被拒绝,再次打开app申请就返回true,返回true一定可以申请弹出,返回false,则不一定,目前没有判断永久拒绝的方法。

/MY_PERMISSION   Manifest.permission.BYDAUTO_AC_COMMON
    public static void verify(Activity context) {
//        DeviceBaseInfoUtils.getBydVin(Activity activity)
        if (context.checkSelfPermission(MY_PERMISSION)//判断是否拥有这个方法,如果 拥有则不等于 PERMISSION_GRANTED
                != PERMISSION_GRANTED) {
            Log.w(TAG, "checkSelfPermission ==FALSE  上次是拒绝了此权限的");
            //如果应用之前请求过此权限但用户拒绝了请求,此方法将返回 true。

            if (context.shouldShowRequestPermissionRationale(MY_PERMISSION)) {//如果非第一次 拒绝但是还没有设置永久拒绝会走这个逻辑, 这个时候还是可以申请权限的。
                Log.w(TAG, "shouldShowRequestPermissionRationale true");
                Toast.makeText(context, "为了您的安全,请一定要同意权限申请!", Toast.LENGTH_SHORT).show();
                context.requestPermissions(new String[]{MY_PERMISSION}, REQUEST_CODE_VIN);
            } else {
                Log.w(TAG, "shouldShowRequestPermissionRationale false 第一次或者被永久拒绝"); //第一次 或者被永久拒绝走这个逻辑,
                Log.w(TAG, "requestPermissions");
                context.requestPermissions(new String[]{MY_PERMISSION}, REQUEST_CODE_VIN);//如果永久拒绝,
            }
        } else {
            // 拥有权限
            Log.w(TAG, "checkSelfPermission ==true");
            checkLogic(context);
        }


    }

    public static void onRequestPermissionsResult(Activity activity, int requestCode, String[] permissions, int[] grantResults) {
        if (REQUEST_CODE_VIN == requestCode) {
            Log.w(TAG, "onRequestPermissionsResult permissions:" + Arrays.toString(permissions) + ",grantResults:" + Arrays.toString(grantResults));
            if (permissions != null && permissions.length > 0 && permissions[0].equals(MY_PERMISSION)) {

                if (grantResults.length > 0 && grantResults[0] == PERMISSION_GRANTED) {
                    Log.w(TAG, "onRequestPermissionsResult 获取成功");
                    checkLogic(activity);
                } else {
                    Log.w(TAG, "onRequestPermissionsResult 获取失败!");
                    doFailLogic();
                }
            }
        }
    }

那么永久拒绝的判断

根据执行时间就可以推测了。

 //MY_PERMISSION   Manifest.permission.BYDAUTO_AC_COMMON
    public static void verify(Activity context) {
//        DeviceBaseInfoUtils.getBydVin(Activity activity)
        if (context.checkSelfPermission(MY_PERMISSION)//判断是否拥有这个方法,如果 拥有则不等于 PERMISSION_GRANTED
                != PERMISSION_GRANTED) {
            Log.w(TAG, "checkSelfPermission ==FALSE  上次是拒绝了此权限的");
            //如果应用之前请求过此权限但用户拒绝了请求,此方法将返回 true。

            if (context.shouldShowRequestPermissionRationale(MY_PERMISSION)) {
                Log.w(TAG, "shouldShowRequestPermissionRationale true");
                Toast.makeText(context, "为了您的安全,请一定要同意权限申请!", Toast.LENGTH_SHORT).show();
                context.requestPermissions(new String[]{MY_PERMISSION}, REQUEST_CODE_VIN_SECOND);
//如果非第一次 拒绝但是还没有设置永久拒绝会走这个逻辑, 这个时候还是可以申请权限的。
            } else {
                Log.w(TAG, "shouldShowRequestPermissionRationale false 第一次或者被永久拒绝"); //第一次 或者被永久拒绝走这个逻辑,
                Log.w(TAG, "requestPermissions");
                sRequestTime = new Date().getTime();
                context.requestPermissions(new String[]{MY_PERMISSION}, REQUEST_CODE_VIN_FIRST_OR_LAST);//如果永久拒绝,
            }
        } else {
            // 拥有权限
            Log.w(TAG, "checkSelfPermission ==true");
            checkLogic(context);
        }


    }

    public static void onRequestPermissionsResult(Activity activity, int requestCode, String[] permissions, int[] grantResults) {
        if (REQUEST_CODE_VIN_SECOND == requestCode || requestCode == REQUEST_CODE_VIN_FIRST_OR_LAST) {
            Log.w(TAG, "onRequestPermissionsResult permissions:" + Arrays.toString(permissions) + ",grantResults:" + Arrays.toString(grantResults));
            if (permissions != null && permissions.length > 0 && permissions[0].equals(MY_PERMISSION)) {

                if (grantResults.length > 0 && grantResults[0] == PERMISSION_GRANTED) {
                    Log.w(TAG, "onRequestPermissionsResult 获取成功");

                    checkLogic(activity);
                } else {
                    long distance = new Date().getTime() - sRequestTime;
                    if (BuildConfig.DEBUG) {
                        Log.w(TAG, "执行回调间隔:" + distance);
                    }
                    if (distance < 800 && requestCode == REQUEST_CODE_VIN_FIRST_OR_LAST) {
                        Log.w(TAG, "onRequestPermissionsResult 获取失败 推测是永久拒绝!");

                    } else {
                        Log.w(TAG, "onRequestPermissionsResult 获取失败!");

                    }
                    doFailLogic();//拒绝了
                }
            }
        }
    }

至于为什么是原创,因为我发现网上似乎没有这样的方法,而且很多文章讲的乱七八糟,甚至比亚迪的sdk demo都写错了,认为第二次就应该卸载才行。。

第一 shouldShowRequestPermissionRationale为true,表示已经申请过了,但是没有永久拒绝,,永久拒绝和第一次都会返回false,

第二个requestPermissions只能调用一次,也就是说权限对话框弹出来的时候,如果方法继续执行又执行了requestPermissions那么会马上收到权限失败的回调,而且 回调中的权限数组和结果int数组 长度是0的.
偏门:在做自动化插入任何app的时候这种问题是无法避免的,无法智能

第三个/如果requestPermissions传递了多个参数,那么回一次请求权限弹出对话框,知道所有权限的一个接一个的弹出之后,才会进行回调,这个时候可能包含多个成功结果失败与否的数组。
第四个/如果弹出的时候finish或者请求之后马上finish,前者虽然能看到,但是finish了看不到任何回调,后者则看不到弹出权限对话框,也不会回调结果
偏门:这个做自动化才会感受到这些问题

你可能感兴趣的:(【原创】Android申请权限的套路代码存档 教你判断第一次拒绝第二次拒绝和永久拒绝)