How to check "Never ask again" permission scenario with the new ActivityResultContracts class?

Viewed 148

The new registerForActivityResult method makes it very simple to ask for permission, as follows:

registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted ->
    when {
        granted -> getUserLocation()
        else -> {
            //permission denied
        }
    }
}

However, how can I detect that the user has denied permission with the "never ask again" checkbox or in Android 11+ has denied permission permanently? In these scenarios, I want to redirect the user to the device's Settings screen?

2 Answers

Sadly, the Android APIs do not allow us to detect when the user has denied the permission via the "Never ask again" checkbox in older Android versions or denied the permission twice (and therefore permanently) in newer Android versions (i.e. Android 11+ devices).

Focusing on Android 11+, the reason why the above is not possible is because the Android APIs do not allow us to distinguish between the following two cases:

  1. The user has never denied the permission request.
  2. The user has denied the permission request twice.

In both cases, the shouldShowRequestPermissionRationale(permission:) method returns false and the checkSelfPermission(permission:) method returns PackageManager.PERMISSION_DENIED.

With a bit of ingenuity, we can work around the Android API limitations and allow ourselves to differentiate between the above two cases. See my answer here for an example of how to do so.

I would suggest treating the first deny as "Deny Forever" because the first deny can be checked by shouldShowRequestPermissionRationale(). After that you should show your own dialog and take the user to the permission page.

Related