6

My app asks the user for camera permission. If the user rejects the permission, he is asked for permission at the restart again. This time, "never ask again" checkbox is shown to the user. If the user selects the never ask again checkbox, the application can never ask for permission. It is OK. The problem is that my phone does never forget this selection, it remembers this selection. I removed the application, cleared all data but nothing works.

When I delete the application and reinstall it, the application can still never ask for permission. I opened Settings-> Application Settings -> Then I gave necessary permission to my application manually. It is ok. Then, I delete and reinstall it again. But the application can still never ask for permission. I do not want to give my app permission manually at each installation. How to reset the selection of "never ask again" checkbox.

if (Build.VERSION.SDK_INT >= 23)
{
    int hasPermission = ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA);

    if (hasPermission != PackageManager.PERMISSION_GRANTED)
    {
        if (shouldShowRequestPermissionRationale(Manifest.permission.CAMERA))
        { 
            getErrorDialog("You need to allow Camera permission." +
                    "\nIf you disable this permission, You will not able to add attachment.", MainActivity.this, true).show();
        }
        return;
    }
}

public AlertDialog.Builder getErrorDialog(String message, Context context, final boolean isFromCamera) {
   final AlertDialog.Builder alertDialog = new AlertDialog.Builder(context);
   alertDialog.setTitle(getString(R.string.app_name)).setMessage(message);
   alertDialog.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
       @Override
       public void onClick(DialogInterface dialog, int which) {

           dialog.dismiss();
           if (Build.VERSION.SDK_INT >= 23) {
               if(isFromCamera){
                   requestPermissions(new String[]{Manifest.permission.CAMERA},
                           REQUEST_CODE_ASK_PERMISSIONS_CAMERA);
               }else {
                   requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                           REQUEST_CODE_ASK_PERMISSIONS_EXTERNAL_STORAGE);
               }
           }
       }
   });
   return alertDialog;
}
Jaymin
  • 2,879
  • 3
  • 19
  • 35
metis
  • 1,024
  • 2
  • 10
  • 26
  • Use my library: https://github.com/nabinbhandari/Android-Permissions It also handles the "don't ask again" situation. – Nabin Bhandari Jan 17 '18 at 12:35
  • You have to handle permission with **shouldShowRequestPermissionRationale()** – Jaymin Jan 17 '18 at 12:37
  • 1
    *Use my library:(link removed for users sake)* @NabinBhandari it is terrible ... with code like `static PermissionHandler permissionHandler;` where `permissionHandler` keeps Activity reference we obviously have Activity leak ... **That's how bad apps are made** ... you should also test if it is working with "Don't keep activities" ... I bet that it will not – Selvin Jan 17 '18 at 12:43
  • "Then, I delete and reinstall it again" -- there had been a bug related to this with some of the Android 6.0 developer previews, but I recall that it was fixed. What device are you testing on, and what version of Android is on it? – CommonsWare Jan 17 '18 at 12:47
  • @CommonsWare , i add requestPermissions() method inside else statement and it worked as i want. When i delete and reinstall the app, the app now asks for request. – metis Jan 17 '18 at 12:57
  • @Selvin Thanks for reviewing my code. I know keeping activity reference in static field may cause memory leak if not properly taken care of. And I have nullified the static field before the callback is called. So there will be no chance of memory leak. You may be correct about the "Don't keep activities" case though. – Nabin Bhandari Jan 17 '18 at 13:45
  • @Selvin, I just tested using "don't keep activities", and it is working fine. – Nabin Bhandari Jan 17 '18 at 14:08
  • It works fine only if it is not asking for permission and there is no code which needs valid context in onGranted ... if it will be asking then: your PermissionsActivity will be created ... Activity which ask for permission will be killed so handler will point to non existing Activity ... so any code in onGranted which is needs valid Context (fx UI element) will be not valid and may cause an exception ... fx try to show DialogFragment there – Selvin Jan 17 '18 at 14:11
  • https://stackoverflow.com/a/61885714/12478830 – MMG May 19 '20 at 07:42

2 Answers2

10

You can't change this behaviour (from Mark Murphy's book):

If the user checks that and clicks the Deny button, not only will you not get the runtime permission now, but all future requests will immediately call onRequestPermissionsResult() indicating that your request for permission was denied. The only way the user can now grant you this permission is via the Settings app.

And what you can do in this situation is the following:

For permissions that, when denied, leave your app in a completely useless state, you may wind up just displaying a screen on app startup that says “sorry, but this app is useless to you”, with options for the user to uninstall the app or grant you the desired permissions. Note that shouldShowRequestPermissionRationale() returns false if the user declined the permission and checked the checkbox to ask you to stop pestering the user.

Hence, as Jaymin correctly noted, your best choice is to handle this with shouldShowRequestPermissionRationale().

Ksenia
  • 3,453
  • 7
  • 31
  • 63
  • I spent 2 days debugging Bluetooth permissions for Android 13 before I came across this - as @Ksenia says, no permissions dialog will be shown but onRequestPermissionsResult() will be called anyway. Madness. – Mitch Mar 14 '23 at 16:42
5

Adding the below else block solved my problem.

if (Build.VERSION.SDK_INT >= 23)
{
     int hasPermission = ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA);
     if (hasPermission != PackageManager.PERMISSION_GRANTED)
     {
         if (shouldShowRequestPermissionRationale(Manifest.permission.CAMERA))
         { 
             getErrorDialog("You need to allow Camera permission." +
                     "\nIf you disable this permission, You will not able to add attachment.", MainActivity.this, true).show();
         }
         else
         { 
             requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CODE_ASK_PERMISSIONS_CAMERA);

         }
         return;
     }
 }
metis
  • 1,024
  • 2
  • 10
  • 26
  • Where did you add this code please? I am having the same problem you initially described. I do not believe you gave any indication what file you added this code into to solve the issue...? I thank you in advance. – Pangit Oct 16 '22 at 02:18