Detecting wether a permission can be requested or

2019-02-25 08:22发布

问题:

Situation
One of my fragments accesses the camera. So of course i need to check the permission in my activity first, before i redirect to it. If the user denies the permission the Activity finishes and redirects him to the previous Activity he was in.
Additionally i would like to show a different fragment when the Activity starts and detects that the permission was permanently denied. (The little checkbox "Never ask again" on the android permission dialog)

Problem
I could not find a proper way of detecting, wether the permission was only denied once or if the "Never ask again" checkbox was checked last time and denied the permission permanently.
Keep in mind that i don't want to know that in the onRequestPermissionsResult callback. I need to know in the onCreate of my Activity if the permission currently is granted, denied or permanently denied.

What i tried
ActivityCompat#shouldShowRequestPermissionRationale seems to detect wether the permission has been denied in the past or not. It also returns true if it has been denied only once instead of permanently.

PermissionChecker#checkPermission() didn't seem to notice any difference between permanently and only once denied permission state.

Question
Is there any way of detecting, wether a permission is denied but can still be requested or if it is permanently denied?

回答1:

Is there any way of detecting, whether a permission is denied but can still be requested or if it is permanently denied?

Unfortunately there is no official API available to detect if permission is permanently denied when user selects "Never ask again"

There is one work around which uses shouldShowRequestPermissionRationale. Create a SharedPreference with default value false and store value returned by shouldShowRequestPermissionRationale in it. Before updating the value, check if the value set was true. If it was true then don't update it.

Whenever you want to check for permission, get the value from SharedPreference and current value returned by shouldShowRequestPermissionRationale. If shouldShowRequestPermissionRationale returns false but value from SharedPreference is true, you can deduce that Never ask again was selected by user.

You can refer to my blog where I have described this approach.



回答2:

You can check the permission by,

if (permissionStatus.getBoolean(Manifest.permission.CALL_PHONE, false)){}

Normally I check the permission using following,

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {

   if (ActivityCompat.shouldShowRequestPermissionRationale(TrackActivity.this, Manifest.permission.CALL_PHONE)) {
                ActivityCompat.requestPermissions(TrackActivity.this, new String[]{Manifest.permission.CALL_PHONE}, EXTERNAL_STORAGE_PERMISSION_CONSTANT);
       } else if (permissionStatus.getBoolean(Manifest.permission.CALL_PHONE, false)) {

       } else {
                ActivityCompat.requestPermissions(TrackActivity.this, new String[]{Manifest.permission.CALL_PHONE}, EXTERNAL_STORAGE_PERMISSION_CONSTANT);
       }
            SharedPreferences.Editor editor = permissionStatus.edit();
            editor.putBoolean(Manifest.permission.CALL_PHONE, true);
            editor.apply();
   }