Search code examples
androidandroid-permissionsandroid-11

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


In Android 11, when user select "deny" option for more than once for any permission request, then system will mark it as "Permanently denied".Once permanently denied, user has to enable in settings.From this time shouldShowRequestPermissionRationale() start's to return false

Three options are available for permission window , "Deny","Allow All time","Allow only this time". But in settings "Deny","Allow all the time","Ask every time" are present.

How to find when user selects "Ask me every time" from settings, because, checkSelfPermission() returns PackageManager.PERMISSION_DENIED,and shouldShowRequestPermissionRationale() return false. In this time I want to show permission window, instead of move to settings. Something similar to google map permission


Solution

  • Using the new ActivityResultsContract you can do this in the following manner

    
        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
                    }
                }
            }
    
    

    In OnCreate()[Make sure you ask permission in OnCreate , else application will crash] , ask the permission :

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

    Ask requiredPermissions in the following manner :

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