Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

shouldShowRequestPermissionRationale not working as expected

I'm working on checking and getting permission from user with API level 23 and above. So here is a confusing thing for me, android.com says:

shouldShowRequestPermissionRationale() method returns true if the app has requested this permission previously and the user denied the request. 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

in other side it gives following code for checking permission and request permission if its neccessery

// 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 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, 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.
    }
}

else scope in above example runs if user doesn't allow permission and check Don't Ask Again, Right? So with this code user never being asked for permission at first time run. I tested that code and the result is what I expected. So How could I request permission for first time run and do something if user previously denied my request and do something if user deny my request and check Don't Ask Again?

like image 873
Artin GH Avatar asked Sep 04 '17 15:09

Artin GH


3 Answers

You can do the following.

  1. Ask permission every time by only checking that permission is not granted already. Don't handle the "Don't ask again" in this method. (if user checks "Don't ask again" the OS will automatically handle and will not ask for permission again and will give a call back of permission denied)
  2. Handle the ActivityCompat.shouldShowRequestPermissionRationale() in the call back method onRequestPermissionsResult().

Here is my code in which I am asking for permission everytime

public void checkAndAskCameraPermission() {
        if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {

            ActivityCompat.requestPermissions(context,
                    new String[]{Manifest.permission.CAMERA}, CAMERA_PERMISSION_REQUEST_ID);
        }
    }

This is how I handles the call back

@Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        switch (requestCode) {
            case CAMERA_PERMISSION_REQUEST_ID: {
                if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {

                  // Do something if permission is not granted and the user has also checked the **"Don't ask again"**
                } else if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_DENIED) {
                    // Do something if permission not granted
                }
            }
        }
    }
like image 149
Waleed Hassan Avatar answered Sep 22 '22 04:09

Waleed Hassan


first check if the permission is granted then do what you need else if permission is denied then check weather you should request the permission you need or not through shouldShowRequestPermissionRationale.
if shouldShowRequestPermissionRationale return false then you can just show a message to the user to told them to enable the permission manually.
other then if shouldShowRequestPermissionRationale return true then request the permission and get the result of granting permission in onRequestPermissionsResult

update , this is just a simple code to show the steps:

if (checkSelfPermission == granted){
 // do what you want 
 } else if (shouldShowRequestPermissionRationale == true) {
        // you can request the permission you want from the user, then check whether permission granted or not inside onRequestPermissionsResult method
 } else { 
        // here you know the permission is not granted , and also the user check on "Dont ask Again!" checkbox, so all you can to do is just tell the user to enable the permission manually from app permissions through Toast message or any thing else
        }
like image 23
salman Avatar answered Sep 20 '22 04:09

salman


 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

      //initilize your views


    if(iscontactsAllowed){

    // do your code here

    } else {

     requestcontactsPermission();

    }

}
private void requestcontactsPermission() {

        if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.READ_CONTACTS)) {
            //If the user has denied the permission previously your code will come to this block
            //Here you can explain why you need this permission
            //Explain here why you need this permission
            Log.d("scancode", "denied permission before");
        }

        Log.d("perm", "fourth");
        //And finally ask for the permission
        ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.READ_CONTACTS}, READ_CONTACTS_CODE /*can be any interge */);

    }

private boolean iscontactsAllowed() {
            //Getting the permission status
            int result = ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_CONTACTS);

            //If permission is granted returning true
            if (result == PackageManager.PERMISSION_GRANTED)

                return true;

            //If permission is not granted returning false
            return false;
        }


@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

        //Checking the request code of our request

        if(requestCode == READ_CONTACTS_CODE){

if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

// you have the permission call yur method here

} else {

// permission denied show user why you need it or ask again by calling reuestpermission if you need the permission
}

}
like image 26
Aman Verma Avatar answered Sep 20 '22 04:09

Aman Verma