Android 6.0运行时权限用户选择“不在提示”的处理

2,054 阅读3分钟

Android 6.0需要对当前的权限进行适配了,并且一下跳了两个版本,直接兼容至7.0了。在进行6.0系统的适配时,权限部分是对用户使用体验影响最大的一个点了吧。

“不在提示”行为的监听 根据官方介绍,当发起首次权限请求时不会提供“不再提示”这一选择,但如果用户之前拒绝过权限请求并且再次发起权限请求时,权限请求对话框才会提供“不在提示”这一选项供用户选择,当用户选择了“不再提示”之后就不会再弹出权限请求对话框。各大手机厂商的定制系统对该逻辑进行了一定的改动,例如小米MIUI系统当用户首次选择拒绝权限时之后就会“不在提示”了,华为EMUI系统在首次弹出权限请求时就会提供“不在提示”的选项,三星系统始终不提供“不在提示”的选项。 当用户选择了“不在提示”时,开发者需要引导用户去设置页手动授权! 但是Android 6.0系统并未提供对“不在提示”这一选项的监听,那么开发者该如何判断用户是否选择了“不在提示”这一选项呢? 答案是通过shouldShowRequestPermissionRationale()这一方法。 这一方法的作用是判断是否需要向用户解释为何需要请求该权限。 当首次发起权限请求时该方法返回false。 当第二次权限请求时该方法返回true。 当发起第二次权限请求并且当用户选择了“不再提示”这一选项时该方法返回false。 通过这个逻辑我们可以反推出:当进行第二次权限请求被拒绝并且shouldShowRequestPermissionRationale()返回false时,那么该用户一定是选择了“不再提示”这一选项。直接看代码:

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

    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    boolean hasAllGranted = true;
    for (int i = 0; i < grantResults.length; ++i) {
        if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
            hasAllGranted = false;
            //在用户已经拒绝授权的情况下,如果shouldShowRequestPermissionRationale返回false则
            // 可以推断出用户选择了“不在提示”选项,在这种情况下需要引导用户至设置页手动授权
            if (!ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[i])) {
                //解释原因,并且引导用户至设置页手动授权
                new AlertDialog.Builder(this)
                        .setMessage("【用户选择了不在提示按钮,或者系统默认不在提示(如MIUI)。" +
                                "引导用户到应用设置页去手动授权,注意提示用户具体需要哪些权限】\r\n" +
                                "获取相关权限失败:xxxxxx,将导致部分功能无法正常使用,需要到设置页面手动授权")
                        .setPositiveButton("去授权", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                //引导用户至设置页手动授权
                                Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                Uri uri = Uri.fromParts("package", getApplicationContext().getPackageName(), null);
                                intent.setData(uri);
                                startActivity(intent);
                            }
                        })
                        .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                //引导用户手动授权,权限请求失败
                            }
                        }).setOnCancelListener(new DialogInterface.OnCancelListener() {
                    @Override
                    public void onCancel(DialogInterface dialog) {
                        //引导用户手动授权,权限请求失败
                    }
                }).show();
            } else {
                //权限请求失败,但未选中“不再提示”选项
            }
            break;
        }
    }
    if (hasAllGranted) {
        //权限请求成功
    }
}