1

I'm a little confused, what is the difference between checkSelfPermission() and shouldShowRequestPermissionRationale()

If I understand it right they both check if the application needs to ask the user for permissions, so why do I have to check this twice? Why can't it be as simple as this?

if (ShouldAskForPermission(WRITE_FILE) == true)
  ShowMessage("The application need permission for writing a file on your device, do you allow it?", YES_NO_BUTTONS);
  • _"they both check if the application need to ask the user for permissions"_. No, they check different things: `checkSelfPermission` is used to check whether or not your app currently has some permission. `shouldShowRequestPermissionRationale` is used to check whether you should show a custom message to the user explaining why your app wants the permission, which at least on recent Android versions will be true only if the user previously has denied your app that permission. – Michael Jul 12 '18 at 10:32
  • It's still not makes sense, why shouldShowRequestPermissionRationale() can't also check if there is a permission for the function that I want? (for example access to the device files) and if there is a permission then tell me that I don't have to show an explanation message? why can't it all be in one function? – StackOverflow User Jul 12 '18 at 11:19
  • Because the first time you request a permission, those two functions do not return the same thing. `shouldShowRequestPermissionRationale` basically keeps track of whether the user has ever declined your app the permission, so you don't have to do that yourself. `checkSelfPermission` just returns the current grant status. – Michael Jul 12 '18 at 11:25
  • Why can't there be a single function like ShouldTheAppAskForPermission(CAMERA_ACCESS) that returns 'true' only if 1. It's the first time the app is running, 2. We need permission in order to access the camera, 3. If the user declined permission to access the camera on the previous app running, but he didn't asked to not ask him again. Why such function is not enough? If the function returns 'true' then I will ask the user for permission with an explenation why, and if it returns 'false' then I will not ask for the user permission. – StackOverflow User Jul 12 '18 at 12:19
  • Because _"I will ask the user for permission with explenation why"_ is not how Google have designed things. The intended flow is that the extra dialog with the explanation only will be shown to the user before asking for a permission which the user has already denied at least once. The actual permission request dialog is a system dialog where you can't add any text of your own. – Michael Jul 12 '18 at 12:25
  • It looks to me like an unnecessary redundancy, if Google whould let me (as a programmer) add an explanation text to the system permission dialog then one function whould be enough. – StackOverflow User Jul 12 '18 at 12:58

2 Answers2

0

Because they do different things from each other. checkSelfPermission checks if you have the permission or not, shouldShowRequestPermissionRationale checks if you should show rationale for why you need the permission.

The flow should be:

  • Check if you have the permission already (checkSelfPermission)
    • If you do have the permission, you can just move ahead without doing any further checks
    • If you don't have the permission, check if you should show the rationale (shouldShowRequestPermissionRationale)
      • If you should show the rationale, show it, and then request permission
      • If you don't need to show the rationale, don't show it, just request permission

The reason why these are separate from each other is mainly for backwards compatibility I think. shouldShowRequestPermissionRationale was introduced much later than checkSelfPermission, so they didn't want to change the contract of checkSelfPermission as it would result in a lot of broken code. For example, if they split the return value of checkSelfPermission into PERMISSION_DENIED_AND_NEED_TO_SHOW_RATIONALE and PERMISSION_DENIED_AND_DO_NOT_NEED_TO_SHOW_RATIONALE, it would break any code with an if (returnValue == PackageManager.PERMISSION_DENIED) type branch.

Adam Burley
  • 5,551
  • 4
  • 51
  • 72
-1

After M Preview 1, if the dialog is displayed for the first time, there is no Never ask again checkbox.

If the user denies the permission request, there will be a Never ask again checkbox in the permission dialog the second time permission is requested.

So the logic should be like this:

Request permission:

if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(context, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE);
} else {
    //Do the stuff that requires permission...
}

Check if the permission was denied or granted in onRequestPermissionsResult. If the permission was denied previously, this time there will be a Never ask again checkbox in the permission dialog.

Call shouldShowRequestPermissionRationale to see if the user checked Never ask again. shouldShowRequestPermissionRationale method returns false only if the user selected Never ask again or device policy prohibits the app from having that permission:

if (grantResults.length > 0){
            if(grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                //Do the stuff that requires permission...
            }else if (grantResults[0] == PackageManager.PERMISSION_DENIED){
                // Should we show an explanation?
                if (ActivityCompat.shouldShowRequestPermissionRationale(context, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                    //Show permission explanation dialog...
                }else{
                    //Never ask again selected, or device policy prohibits the app from having that permission.
                    //So, disable that feature, or fall back to another situation...
                }
            }
        }

So, you won't have to track if a user checked Never ask again or not.

Kashif K.
  • 88
  • 1
  • 9
  • 1
    You can attach link of the original answer instead of duplicating it here. https://stackoverflow.com/questions/32347532/android-m-permissions-confused-on-the-usage-of-shouldshowrequestpermissionrati – Ondřej Z Oct 29 '18 at 17:33