Confusion about should show permission request rationale
Asked Answered
S

1

8

I am a little bit curious about the new permission model for android M and above especially about the method "shouldShowRequestPermissionRationale()". In the Documentation :

To help find situations where the user might need an explanation, Android provides a utiltity method, shouldShowRequestPermissionRationale(). This method returns true if the app has requested this permission previously and the user denied the request.

Note: If the user turned down the permission request in the past and chose the Don't ask again option in the permission request system dialog, this method returns false. The method also returns false if a device policy prohibits the app from having that permission.

Ok , user rejected permission definitely. Now in code snipet from the same page:

// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
                Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {
    // Should we show an explanation?
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            Manifest.permission.READ_CONTACTS)) {

        // Show an expanation to the user *asynchronously* -- don't block
        // this thread waiting for the user's response! After the user
        // sees the explanation, try again to request the permission.

    } else {

        // No explanation needed, we can request the permission.

        ActivityCompat.requestPermissions(thisActivity,
                new String[]{Manifest.permission.READ_CONTACTS},
                MY_PERMISSIONS_REQUEST_READ_CONTACTS);

        // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
        // app-defined int constant. The callback method gets the
        // result of the request.
    }
}

The confusion come from the else bloc, it returned false then user rejected that permission, this means we keep asking the user for the prrmission he rejected and this is contradictory with best practices

My question is ; how can we implement a good logique for dealing with all this ?

Sagerman answered 16/11, 2016 at 12:46 Comment(7)
"it returned false then user rejected that permission" -- or you have never asked for the permission before. "how can we implement a good logique for dealing with all this ?" -- keep track of whether you asked for the permission before. If you have, and shouldShowRequestPermissionRationale() returns false, then you know that the user has permanently rejected the permission. In that case, you can do something in your UI to reflect the fact that you cannot proceed further, plus perhaps give the user the option to visit Settings to manually grant the permission.Eighth
Not a direct answer but I did some work with this recently, you can find result here https://mcmap.net/q/1085549/-how-to-avoid-writing-duplicate-boilerplate-code-for-requesting-permissions. It may give some insightSoares
I was exactly looking for a way to send user to my app permissions screen, but people seem to state this is not possible, for now the best way to deal with this confusion is to keep truck of permission denial state in shared preferences , implementing a base activity to automate permissions request is very good idea too. To be honest as android user myself , i actually have to accept permissions 3 times , first at play store before downloading, second when installing and then a third or more times depending on the application i use, isnt this annoying android engineers ...Sagerman
shouldShowRequestPermissionRationale is currently broken in SDK 25.0.1. It will return false, even though it should return true.Sawtelle
@Eighth What do you mean by permanently rejected? This api just returns false if the user rejected the permission once. It doesn't denote permanently.Sawtelle
@IgorGanapolsky: Here, by "permanently", I mean from the standpoint of an app's runtime permission code -- no requestPermissions() call will grant you the permission. As I noted in the comment, the user can grant the permission through Settings.Eighth
#30719547 This will totally clear all your doubts.Lollard
A
5

For me it works like that:

if (cameraPermissionState.hasPermission) {
    // Camera permissions are given, may proceed

} else if (cameraPermissionState.shouldShowRationale.not()) {
    // We can ask user for permission

    cameraPermissionState.launchPermissionRequest()
 else {
    // We are unable to ask user anymore or he has declined the permission
    // Open app settings for user to get permission manually

    context.openAppSettings()
 }

And my openAppSettings extension looks like this, in case you need it:

fun Context.openAppSettings() {

    val intent = Intent(ACTION_APPLICATION_DETAILS_SETTINGS).apply {
        data = Uri.fromParts("package", packageName, null)
        addCategory(CATEGORY_DEFAULT)
        addFlags(FLAG_ACTIVITY_NEW_TASK)
        addFlags(FLAG_ACTIVITY_NO_HISTORY)
        addFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
    }

    startActivity(intent)
}
Astrolabe answered 7/7, 2023 at 1:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.