如何在 Android 11 中检测权限的永久拒绝?

How to detect permission's permanent deny in Android 11?

在Android11中,当用户select对任何权限请求多次“拒绝”选项时,系统会将其标记为“永久拒绝”。一旦永久拒绝,用户已这次在 settings.From 启用 shouldShowRequestPermissionRationale() 开始到 return false

权限有三个选项window,“拒绝”,“所有时间都允许”,“只允许这一次”。但在设置“拒绝”、“始终允许”、“每次都询问”中存在。

如何从设置中找到用户 select 的“每次都询问我”,因为 checkSelfPermission() returns PackageManager.PERMISSION_DENIEDshouldShowRequestPermissionRationale() returnfalse。这次我想显示权限 window,而不是转到设置。 类似于google地图权限

使用新的 ActivityResultsContract,您可以按以下方式执行此操作


    private val requestPermissionLauncher =
        registerForActivityResult(
            ActivityResultContracts.RequestMultiplePermissions()
        ) { result: MutableMap<String, Boolean> ->
            val deniedList: List<String> = result.filter {
                !it.value
            }.map {
                it.key
            }

            when {
                deniedList.isNotEmpty() -> {
                    val map = deniedList.groupBy { permission ->
                        if (shouldShowRequestPermissionRationale(permission)) DENIED else EXPLAINED
                    }
                    map[DENIED]?.let {
                        // request denied , request again
                    }
                    map[EXPLAINED]?.let {
                        //request denied ,send to settings 

                    }

                }
                else -> {
                   //All request are permitted
                }
            }
        }

在 OnCreate()[确保您在 OnCreate 中请求许可,否则应用程序将崩溃],请求许可:

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        requestPermissionLauncher.launch(REQUIRED_PERMISSIONS)
    }

按以下方式询问所需的权限:

private val REQUIRED_PERMISSIONS = arrayOf(
    Manifest.permission.CAMERA,
    Manifest.permission.READ_EXTERNAL_STORAGE
)

其实还有一种情况: 如果用户让您请求权限但未选择任何选项并通过点击外部关闭对话框,则请求以拒绝和 shouldExplainPermissionRational() returns 错误结束。 这与用户选择不再询问时的行为完全相同。 请求一次权限,结果被拒绝,我们不应该给出解释。

因此我们必须跟踪 shouldExplainPermissionRational() 是否已返回 true 一次。如果它切换回 false,则它被永久拒绝。

在activity中使用下面的方法,本例使用相机权限

    private fun requestPermission() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
        if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
            //Permission is denied
        } else {
            //ask permission
            ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), REQUEST_CODE_CAMERA)
        }
    }
}