I was going through the official doc about the new Permissions model in Android M. It talks about the shouldShowRequestPermissionRationale()
function which 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, this method returns false
.
But how can we differentiate between the following two cases?
Case 1: The app doesn't have a permission and the user has not been asked for the permission before. In this case, shouldShowRequestPermissionRationale() will return false because this is the first time we're asking the user.
Case 2: The user has denied the permission and selected "Don't ask again", in this case too shouldShowRequestPermissionRationale() will return false.
I would want to send the user to the App's settings page in Case 2. How do i go about differentiating these two cases?
I had the same problem and I figured it out. To make life much simpler, I wrote an util class to handle runtime permissions.
And the PreferenceUtil methods are as follows.
Now, all you need is to use the method checkPermission with proper arguments.
Here is an example,
You'll get callback on onPermissionAsk for case 1, and onPermissionDisabled for case 2.
Happy coding :)
We can do it by this way?
The way I understand it, shouldShowRequestPermissionRationale() runs a number of use cases under the hood, and notifies the app whether or not to show an explanation on the permissions being requested.
The idea behind the Run Time permissions is that most of the time, the user will say Yes to the permission request. That way the user will have to do only one click. Of course the request should be used in the correct context - i.e. asking for the Camera permission when the "Camera" button is pressed.
If the user denies the request, but after some time comes around and presses the "Camera" button again, shouldShowRequestPermissionRationale() will return true, so the app can show some meaningful explanation why the permission is requested, and why the app won't work properly without it. Normally you would show in that dialog window a button to deny again/decide later, and a button to grant the permissions. The grant permissions button in the rationale dialog, should start the permission request again. This time the user will also have a "Never show again" checkbox. Should he decide to select it, and deny the permission again, it would notify the Android system that the user and the app are not on the same page. That action would have two consequences - shouldShowRequestPermissionRationale() will always return false, and the requestPermissions() method will not show any dialog, but will directly return denied to the onRequestPermissionsResult callback.
But there is also another possible scenario where onRequestPermissionsResult could be used. For example some devices may have a device policy that disables the camera (working for CIA, DARPA, etc). On these devices, onRequestPermissionsResult will always return false, and the requestPermissions() method will silently deny the request.
That's what I gathered by listening to the podcast with Ben Poiesz - a product manager on the Android framework.
http://androidbackstage.blogspot.jp/2015/08/episode-33-permission-mission.html
shouldShowRequestPermissionRationale
for SPECIAL permission always return TRUE ONLY after user denied it without checkboxWe are interested in FALSE value
So there are 3 cases lost with false value:
1. there was no such action previously and now user decide to agree or deny.
Simply define a preference
ASKED_PERMISSION_*
which doesn't exist now and would be true inonRequestPermissionsResult
on it's start in any case of agree or denySo while this preference doesn't exist there is no reason to check
shouldShowRequestPermissionRationale
2. user clicked agree.
Simply do:
Which will return true and there is no reason to check
shouldShowRequestPermissionRationale
3. user clicked deny with checkbox (second or more time asked)
It's THE TIME to work with
shouldShowRequestPermissionRationale
which will return FALSE(preference exists and we don't have a permission)
UPDATE
I believe that CanC's answer below is the correct one that should be followed. The only way to know for sure is to verify this in the onRequestPermissionResult callback using shouldShowPermissionRationale.
==
My original answer:
The only way that I have found is to keep track on your own of whether this is the first time or not (e.g. using shared preferences). If it's not the first time, then use
shouldShowRequestPermissionRationale()
to differentiate.Also see: Android M - check runtime permission - how to determine if the user checked "Never ask again"?
Check this implementation. is working pretty good for me. basically you check the permissions in the checkPermissions() method passing a list of permissions. You check the result of the permission request on onRequestPermissionsResult(). The implementation lets u address both case when user selects "never ask again" or not. In this implementation, in case se selects "never ask again", the dialog has an option to take him to the App Settings Activity.
All this code is inside my fragment. I was thinking that would be better to create a specialised class to do this, like a PermissionManager, but i'm not sure about it.