6

I want to request permissions on runtime.I checked out official android developer website and it says that shouldShowRequestPermissionRationale returns true if permission was previously denied and returns false if permission has been denied AND never ask again checkbox was selected. Then i saw this code in the site:

if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            Manifest.permission.READ_CONTACTS)) {
        // Show an explanation 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; 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.
    }

My 2 questions are:

1)What happens if the user wasn't asked permission previously??We need to ask him right??Where do you put that code??

2)The above code asks for permission even when the user checked the never ask again checkbox(when shouldShowRequestPermissionRationale returns false,I.e,in the else block).How can u ask for permission when the user has checked that option??

Marcin Orlowski
  • 72,056
  • 11
  • 123
  • 141
sumanth
  • 135
  • 1
  • 10
  • The first part of your question is a duplicate of https://stackoverflow.com/questions/32347532/android-m-permissions-confused-on-the-usage-of-shouldshowrequestpermissionrati and https://stackoverflow.com/questions/46040141/shouldshowrequestpermissionrationale-not-working-as-expected - as for second question, you can't ask for permission if that checkbox was checked, the `requestPermissions` call will just do nothing. the reason it is there is in the case where you have never asked for permission before, as you worked out, that branch will be reached – Adam Burley Jun 25 '21 at 16:48

1 Answers1

18

To answer both your questions:

You can first use checkSelfPermission() to see if the permission has already been granted. If it has not been granted then you should check if shouldShowRequestPermissionRationale() returns true or false.

shouldShowRequestPermissionRationale() will return true in the following case:

  • When the user has denied the permission previously but has not checked the "Never Ask Again" checkbox.

shouldShowRequestPermissionRationale() will return false in the following 2 cases:

  • When the user has denied the permission previously AND never ask again checkbox was selected.
  • When the user is requesting permission for the first time.

So, what you can do is, if shouldShowRequestPermissionRationale() returns false you can use a boolean preference value (default value as true) to check for

  • first time request of permission in the else case, if it is the first request, then trigger requestPermissions

  • else if it is not the first request and the user has previously denied the request and also has checked the "Never ask again" checkbox, you can show a simple toast with the reason for unavailability of the feature that requires the permission and also mention the steps to manually enable it via settings.

Something like this:

    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
                Manifest.permission.READ_CONTACTS)) {
            // Show an explanation 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 {
       if(isFirstTimeRequest){
            // No explanation needed; request the permission

            // RESET PREFERENCE FLAG

            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.
          } else {
            // User denied previously and has checked "Never ask again"
            // show a toast with steps to manually enable it via settings
          }
        }
raxerz
  • 516
  • 4
  • 10
  • Thanks for the quick reply.Your answer helps,but i have one last question.What if the user exits the app after checking the never ask again box.the boolean var will be set to true again when the app starts and it will be like the permission is being asked for the first time. – sumanth Jun 02 '19 at 07:00
  • @sumanth thanks for pointing that out, you just have to reset the preference flag after the first time request check. See my edit, I updated the answer. – raxerz Jun 02 '19 at 07:30
  • i don't get it .No matter what you do,the flag is gonna change after the user restarts the program,right? – sumanth Jun 02 '19 at 12:42
  • No it won't, a sharedpreference flag is written to a file in disk and will not be cleared until you do a clear data – raxerz Jun 02 '19 at 12:44
  • oh yea.I just checked it out...Thanks a lot :) – sumanth Jun 02 '19 at 13:10
  • @raxerz can u please elaborate , how you are going to handle the "boolean preference value " if Multiple permission are needed to be asked. – vinay shetty May 26 '22 at 13:18
  • @vinayshetty, I've just found this answer... For multiple un-related permissions (for example camera and readContacts) what I do is to chain the permission request, I mean, request one after the previous is granted or not. And have a boolean preference value for each. – sebasira Nov 01 '22 at 05:25