Android M - check runtime permission - how to determine if the user checked “Never ask again”?
According to this: http://developer.android.com/preview/features/runtime-permissions.html#coding an app can check for runtime permissions and request permissions if it hasn't been granted already. The following dialog will be displayed then:
In case the user declines an important permission, imo an app should display an explanation why the permission is needed and what impact declining has. That dialog has two options:
- re-try again (permission is requested again)
- deny (app will work without that permission).
If the user checks Never ask again
however, the second dialog with the explanation shouldn't be shown, especially if the user already declined once before.
Now the question is: how does my app know whether the user has checked the Never ask again
? IMO the onRequestPermissionsResult(int requestCode, String permissions, int grantResults)
doesn't give me that information.
A second question would be: does Google have plans to incorporate a custom message in the permission dialog that would explain why the app needs the permission? That way there would never be a second dialog which would certainly make for a better ux.
android android-permissions android-6.0-marshmallow
|
show 1 more comment
According to this: http://developer.android.com/preview/features/runtime-permissions.html#coding an app can check for runtime permissions and request permissions if it hasn't been granted already. The following dialog will be displayed then:
In case the user declines an important permission, imo an app should display an explanation why the permission is needed and what impact declining has. That dialog has two options:
- re-try again (permission is requested again)
- deny (app will work without that permission).
If the user checks Never ask again
however, the second dialog with the explanation shouldn't be shown, especially if the user already declined once before.
Now the question is: how does my app know whether the user has checked the Never ask again
? IMO the onRequestPermissionsResult(int requestCode, String permissions, int grantResults)
doesn't give me that information.
A second question would be: does Google have plans to incorporate a custom message in the permission dialog that would explain why the app needs the permission? That way there would never be a second dialog which would certainly make for a better ux.
android android-permissions android-6.0-marshmallow
7
"does Google have plans to incorporate a custom message in the permission dialog that would explain why the app needs the permission?" -- in the Google I|O presentation about the M permission system, I seem to recall somebody asked in the Q&A, and the answer was that they're thinking about it.
– CommonsWare
Jun 8 '15 at 21:19
1
Didn't test it myself, but documentation say about Activity.shouldShowRequestPermissionRationale(String) : This method returns true if the app has requested this permission previously and the user denied the request. That indicates that you should probably explain to the user why you need the permission. 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. The method also returns false if the device policy prohibits the app from having that permission.
– Fraid
Jul 17 '15 at 13:45
1
@Fraid: looks like they added this with preview #2 of Android M: developer.android.com/preview/support.html#preview2-notes and it's probably what I was looking for. I can't test it right now but will do so next week. If it does what I hope it does, you can post it as an answer and get some reputation. In the meantime this might help others: youtube.com/watch?v=f17qe9vZ8RM
– Emanuel Moecklin
Jul 21 '15 at 16:16
example of Dangerous Permissions and Special Permissions: github.com/henrychuangtw/AndroidRuntimePermission
– HenryChuang
May 25 '16 at 6:52
I don't like this whole permission thingy. Made it more confusing
– Alex
Jul 22 '16 at 20:10
|
show 1 more comment
According to this: http://developer.android.com/preview/features/runtime-permissions.html#coding an app can check for runtime permissions and request permissions if it hasn't been granted already. The following dialog will be displayed then:
In case the user declines an important permission, imo an app should display an explanation why the permission is needed and what impact declining has. That dialog has two options:
- re-try again (permission is requested again)
- deny (app will work without that permission).
If the user checks Never ask again
however, the second dialog with the explanation shouldn't be shown, especially if the user already declined once before.
Now the question is: how does my app know whether the user has checked the Never ask again
? IMO the onRequestPermissionsResult(int requestCode, String permissions, int grantResults)
doesn't give me that information.
A second question would be: does Google have plans to incorporate a custom message in the permission dialog that would explain why the app needs the permission? That way there would never be a second dialog which would certainly make for a better ux.
android android-permissions android-6.0-marshmallow
According to this: http://developer.android.com/preview/features/runtime-permissions.html#coding an app can check for runtime permissions and request permissions if it hasn't been granted already. The following dialog will be displayed then:
In case the user declines an important permission, imo an app should display an explanation why the permission is needed and what impact declining has. That dialog has two options:
- re-try again (permission is requested again)
- deny (app will work without that permission).
If the user checks Never ask again
however, the second dialog with the explanation shouldn't be shown, especially if the user already declined once before.
Now the question is: how does my app know whether the user has checked the Never ask again
? IMO the onRequestPermissionsResult(int requestCode, String permissions, int grantResults)
doesn't give me that information.
A second question would be: does Google have plans to incorporate a custom message in the permission dialog that would explain why the app needs the permission? That way there would never be a second dialog which would certainly make for a better ux.
android android-permissions android-6.0-marshmallow
android android-permissions android-6.0-marshmallow
edited May 6 '18 at 13:16
JJD
25.4k36153253
25.4k36153253
asked Jun 8 '15 at 21:03
Emanuel MoecklinEmanuel Moecklin
19.9k85671
19.9k85671
7
"does Google have plans to incorporate a custom message in the permission dialog that would explain why the app needs the permission?" -- in the Google I|O presentation about the M permission system, I seem to recall somebody asked in the Q&A, and the answer was that they're thinking about it.
– CommonsWare
Jun 8 '15 at 21:19
1
Didn't test it myself, but documentation say about Activity.shouldShowRequestPermissionRationale(String) : This method returns true if the app has requested this permission previously and the user denied the request. That indicates that you should probably explain to the user why you need the permission. 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. The method also returns false if the device policy prohibits the app from having that permission.
– Fraid
Jul 17 '15 at 13:45
1
@Fraid: looks like they added this with preview #2 of Android M: developer.android.com/preview/support.html#preview2-notes and it's probably what I was looking for. I can't test it right now but will do so next week. If it does what I hope it does, you can post it as an answer and get some reputation. In the meantime this might help others: youtube.com/watch?v=f17qe9vZ8RM
– Emanuel Moecklin
Jul 21 '15 at 16:16
example of Dangerous Permissions and Special Permissions: github.com/henrychuangtw/AndroidRuntimePermission
– HenryChuang
May 25 '16 at 6:52
I don't like this whole permission thingy. Made it more confusing
– Alex
Jul 22 '16 at 20:10
|
show 1 more comment
7
"does Google have plans to incorporate a custom message in the permission dialog that would explain why the app needs the permission?" -- in the Google I|O presentation about the M permission system, I seem to recall somebody asked in the Q&A, and the answer was that they're thinking about it.
– CommonsWare
Jun 8 '15 at 21:19
1
Didn't test it myself, but documentation say about Activity.shouldShowRequestPermissionRationale(String) : This method returns true if the app has requested this permission previously and the user denied the request. That indicates that you should probably explain to the user why you need the permission. 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. The method also returns false if the device policy prohibits the app from having that permission.
– Fraid
Jul 17 '15 at 13:45
1
@Fraid: looks like they added this with preview #2 of Android M: developer.android.com/preview/support.html#preview2-notes and it's probably what I was looking for. I can't test it right now but will do so next week. If it does what I hope it does, you can post it as an answer and get some reputation. In the meantime this might help others: youtube.com/watch?v=f17qe9vZ8RM
– Emanuel Moecklin
Jul 21 '15 at 16:16
example of Dangerous Permissions and Special Permissions: github.com/henrychuangtw/AndroidRuntimePermission
– HenryChuang
May 25 '16 at 6:52
I don't like this whole permission thingy. Made it more confusing
– Alex
Jul 22 '16 at 20:10
7
7
"does Google have plans to incorporate a custom message in the permission dialog that would explain why the app needs the permission?" -- in the Google I|O presentation about the M permission system, I seem to recall somebody asked in the Q&A, and the answer was that they're thinking about it.
– CommonsWare
Jun 8 '15 at 21:19
"does Google have plans to incorporate a custom message in the permission dialog that would explain why the app needs the permission?" -- in the Google I|O presentation about the M permission system, I seem to recall somebody asked in the Q&A, and the answer was that they're thinking about it.
– CommonsWare
Jun 8 '15 at 21:19
1
1
Didn't test it myself, but documentation say about Activity.shouldShowRequestPermissionRationale(String) : This method returns true if the app has requested this permission previously and the user denied the request. That indicates that you should probably explain to the user why you need the permission. 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. The method also returns false if the device policy prohibits the app from having that permission.
– Fraid
Jul 17 '15 at 13:45
Didn't test it myself, but documentation say about Activity.shouldShowRequestPermissionRationale(String) : This method returns true if the app has requested this permission previously and the user denied the request. That indicates that you should probably explain to the user why you need the permission. 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. The method also returns false if the device policy prohibits the app from having that permission.
– Fraid
Jul 17 '15 at 13:45
1
1
@Fraid: looks like they added this with preview #2 of Android M: developer.android.com/preview/support.html#preview2-notes and it's probably what I was looking for. I can't test it right now but will do so next week. If it does what I hope it does, you can post it as an answer and get some reputation. In the meantime this might help others: youtube.com/watch?v=f17qe9vZ8RM
– Emanuel Moecklin
Jul 21 '15 at 16:16
@Fraid: looks like they added this with preview #2 of Android M: developer.android.com/preview/support.html#preview2-notes and it's probably what I was looking for. I can't test it right now but will do so next week. If it does what I hope it does, you can post it as an answer and get some reputation. In the meantime this might help others: youtube.com/watch?v=f17qe9vZ8RM
– Emanuel Moecklin
Jul 21 '15 at 16:16
example of Dangerous Permissions and Special Permissions: github.com/henrychuangtw/AndroidRuntimePermission
– HenryChuang
May 25 '16 at 6:52
example of Dangerous Permissions and Special Permissions: github.com/henrychuangtw/AndroidRuntimePermission
– HenryChuang
May 25 '16 at 6:52
I don't like this whole permission thingy. Made it more confusing
– Alex
Jul 22 '16 at 20:10
I don't like this whole permission thingy. Made it more confusing
– Alex
Jul 22 '16 at 20:10
|
show 1 more comment
23 Answers
23
active
oldest
votes
Developer Preview 2 brings some changes to how permissions are requested by the app (see also http://developer.android.com/preview/support.html#preview2-notes).
The first dialog now looks like this:
There's no "Never show again" check-box (unlike developer preview 1). If the user denies the permission and if the permission is essential for the app it could present another dialog to explain the reason the app asks for that permission, e.g. like this:
If the user declines again the app should either shut down if it absolutely needs that permission or keep running with limited functionality. If the user reconsiders (and selects re-try), the permission is requested again. This time the prompt looks like this:
The second time the "Never ask again" check-box is shown. If the user denies again and the check-box is ticked nothing more should happen.
Whether or not the check-box is ticked can be determined by using Activity.shouldShowRequestPermissionRationale(String), e.g. like this:
if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_CONTACTS)) {...
That's what the Android documentation says (https://developer.android.com/training/permissions/requesting.html):
To help find the situations where you need to provide extra
explanation, the system provides the
Activity.shouldShowRequestPermissionRationale(String) method. This
method returns true if the app has requested this permission
previously and the user denied the request. That indicates that you
should probably explain to the user why you need the permission.
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. The method also returns false if the device
policy prohibits the app from having that permission.
To know if the user denied with "never ask again" you can check again the shouldShowRequestPermissionRationale method in your onRequestPermissionsResult when the user did not grant the permission.
@Override
public void onRequestPermissionsResult(int requestCode, String permissions, int grantResults) {
if (requestCode == REQUEST_PERMISSION) {
// for each permission check if the user granted/denied them
// you may want to group the rationale in a single dialog,
// this is just an example
for (int i = 0, len = permissions.length; i < len; i++) {
String permission = permissions[i];
if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
// user rejected the permission
boolean showRationale = shouldShowRequestPermissionRationale( permission );
if (! showRationale) {
// user also CHECKED "never ask again"
// you can either enable some fall back,
// disable features of your app
// or open another dialog explaining
// again the permission and directing to
// the app setting
} else if (Manifest.permission.WRITE_CONTACTS.equals(permission)) {
showRationale(permission, R.string.permission_denied_contacts);
// user did NOT check "never ask again"
// this is a good place to explain the user
// why you need the permission and ask if he wants
// to accept it (the rationale)
} else if ( /* possibly check more permissions...*/ ) {
}
}
}
}
}
You can open your app setting with this code:
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, REQUEST_PERMISSION_SETTING);
There is no way of sending the user directly to the Authorization page.
24
I verified return value of shouldShowRequestPermissionRationale() method to false for checking if user selected "Never ask again". But I am also getting its value as false for very first time when ask for permission. So I am not able to differentiate if user selected "Never ask again" checkbox or not. Please suggest??
– Sagar Trehan
Oct 5 '15 at 8:24
27
According to my understanding shouldShowRationalePermissionRationale() method returns false in three cases: 1. If we call this method very first time before asking permission. 2. If user selects "Don't ask again" and deny permission. 3. If the device policy prohibits the app from having that permission
– Sagar Trehan
Oct 7 '15 at 9:01
13
All good... but we, developers, really need to know if the user said "never ask again" or not. I have a nice button to access a feature. The first time the user click: should ask rationale? nope, ask permission. The user deny. User click again the button: rationale? yep! Show rationale, user say Ok, then deny and never ask again (ok he is an idiot, but users often are). Later user press again the button, rationale? nope, ask permission, nothing happens for the user. I really need a way, there, to tell the user: hey man if you want this feature now go to the app setting and give the permission.
– Daniele Segato
Oct 16 '15 at 14:19
3
Great @EmanuelMoecklin this is better then Google Documentation now :D
– Daniele Segato
Oct 17 '15 at 14:58
4
onRequestPermissionsResult won't be called unless you request the permission. Since there's no check-box "Never ask again" the first time the permission is requested, shouldShowRequestPermissionRationale will return True (permission requested but without never ask again). Consequently the rationale is always shown the first time the user rejects the permission but after that only if the check-box wasn't ticked.
– Emanuel Moecklin
Oct 19 '15 at 15:33
|
show 28 more comments
You can check shouldShowRequestPermissionRationale()
in your onRequestPermissionsResult()
.
https://youtu.be/C8lUdPVSzDk?t=2m23s
Check whether permission was granted or not in onRequestPermissionsResult()
. If not then check shouldShowRequestPermissionRationale()
.
- If this method returns
true
then show an explanation that why this particular permission is needed. Then depending on user's choice againrequestPermissions()
. - If it returns
false
then show an error message that permission was not granted and app cannot proceed further or a particular feature is disabled.
Below is sample code.
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case STORAGE_PERMISSION_REQUEST:
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted :)
downloadFile();
} else {
// permission was not granted
if (getActivity() == null) {
return;
}
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
showStoragePermissionRationale();
} else {
Snackbar snackbar = Snackbar.make(getView(), getResources().getString(R.string.message_no_storage_permission_snackbar), Snackbar.LENGTH_LONG);
snackbar.setAction(getResources().getString(R.string.settings), new View.OnClickListener() {
@Override
public void onClick(View v) {
if (getActivity() == null) {
return;
}
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getActivity().getPackageName(), null);
intent.setData(uri);
OrderDetailFragment.this.startActivity(intent);
}
});
snackbar.show();
}
}
break;
}
}
Apparently, google maps does exactly this for location permission.
Thank you for the picture and the Youtube link. It matches more or less my own answer. It has to be noted that the question was asked when only the developer preview 1 was available which didn't have the shouldShowRequestPermissionRationale method.
– Emanuel Moecklin
Nov 13 '15 at 17:22
i'm new in android and i want to over ride this onRequestPermissionsResult() method. but I'm getting error that it must implement a super type method. can you tell how to use this
– Andrain
Nov 18 '15 at 8:50
add a comment |
Here is a nice and easy method to check the current permission status:
@Retention(RetentionPolicy.SOURCE)
@IntDef({GRANTED, DENIED, BLOCKED_OR_NEVER_ASKED })
public @interface PermissionStatus {}
public static final int GRANTED = 0;
public static final int DENIED = 1;
public static final int BLOCKED_OR_NEVER_ASKED = 2;
@PermissionStatus
public static int getPermissionStatus(Activity activity, String androidPermissionName) {
if(ContextCompat.checkSelfPermission(activity, androidPermissionName) != PackageManager.PERMISSION_GRANTED) {
if(!ActivityCompat.shouldShowRequestPermissionRationale(activity, androidPermissionName)){
return BLOCKED_OR_NEVER_ASKED;
}
return DENIED;
}
return GRANTED;
}
Caveat: returns BLOCKED_OR_NEVER_ASKED the first app start, before the user accepted/denied the permission through the user prompt (on sdk 23+ devices)
Update:
The Android support library now also seems to have a very similar class android.support.v4.content.PermissionChecker
which contains a checkSelfPermission()
which returns:
public static final int PERMISSION_GRANTED = 0;
public static final int PERMISSION_DENIED = -1;
public static final int PERMISSION_DENIED_APP_OP = -2;
1
For the first launch, I am storing a boolean in shared preferences.
– Saeid Farivar
Jun 27 '16 at 21:42
Which permission will this code grant?
– buzzingsilently
Sep 8 '16 at 10:08
3
This always returnsBLOCKED_OR_NEVER_ASKED
if the permission has not been requested yet.
– Saket
Apr 4 '17 at 11:59
4
yes, that's the reason its called "BLOCKED_OR_NEVER_ASKED", also see the last sentence
– patrickf
Apr 4 '17 at 13:29
2
android.content.pm
already definesPERMISSION_GRANTED = 0
andPERMISSION_DENIED = -1
. Perhaps setBLOCKED_OR_NEVER_ASKED = PERMISSION_DENIED - 1
or something?
– samis
Jul 25 '17 at 16:01
|
show 1 more comment
May be useful for someone:--
What I have noticed is, if we check the shouldShowRequestPermissionRationale() flag in to onRequestPermissionsResult() callback method, it shows only two states.
State 1:-Return true:-- Any time user clicks Deny permissions (including the very first time).
State 2:-Returns false :- if user selects “never asks again".
Link of detailed working example
2
This is the correct way to detect if user has selected never ask again option.
– Muhammad Babar
May 24 '17 at 10:31
Ah, the key here is that you handle this in theonRequestPermissionsResult
, not when actually requesting the permission.
– Joshua Pinter
May 12 '18 at 15:27
add a comment |
You can determine it by checking if permission rationale is to be shown inside the onRequestPermissionsResult()
callback method. And if you find any permission set to never ask again, you can request users to grant permissions from the settings.
My full implementation would be like below. It works for both single or multiple permissions requests. Use the following or directly use my library.
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) {
if(permissions.length == 0){
return;
}
boolean allPermissionsGranted = true;
if(grantResults.length>0){
for(int grantResult: grantResults){
if(grantResult != PackageManager.PERMISSION_GRANTED){
allPermissionsGranted = false;
break;
}
}
}
if(!allPermissionsGranted){
boolean somePermissionsForeverDenied = false;
for(String permission: permissions){
if(ActivityCompat.shouldShowRequestPermissionRationale(this, permission)){
//denied
Log.e("denied", permission);
}else{
if(ActivityCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED){
//allowed
Log.e("allowed", permission);
} else{
//set to never ask again
Log.e("set to never ask again", permission);
somePermissionsForeverDenied = true;
}
}
}
if(somePermissionsForeverDenied){
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle("Permissions Required")
.setMessage("You have forcefully denied some of the required permissions " +
"for this action. Please open settings, go to permissions and allow them.")
.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", getPackageName(), null));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
})
.setCancelable(false)
.create()
.show();
}
} else {
switch (requestCode) {
//act according to the request code used while requesting the permission(s).
}
}
}
hii @nabin my requirement is when i click on download button(which download pdf file) that time have to check write permission is allow or denied so how to use this code! can you guide me plz
– Rucha Bhatt Joshi
Jun 16 '17 at 6:38
hello @RuchaBhatt Have a look at my library. github.com/nabinbhandari/Android-Permissions
– Nabin Bhandari
Jun 20 '17 at 17:12
add a comment |
Once the user has marked "Do not ask again," the question can not be displayed again.
But it can be explained to the user that he has previously denied the permission and must grant permission in the settings. And reference him to the settings, with the following code:
@Override
public void onRequestPermissionsResult(int permsRequestCode, String permissions, int grantResults) {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// now, you have permission go ahead
// TODO: something
} else {
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
Manifest.permission.READ_CALL_LOG)) {
// now, user has denied permission (but not permanently!)
} else {
// now, user has denied permission permanently!
Snackbar snackbar = Snackbar.make(findViewById(android.R.id.content), "You have previously declined this permission.n" +
"You must approve this permission in "Permissions" in the app settings on your device.", Snackbar.LENGTH_LONG).setAction("Settings", new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + BuildConfig.APPLICATION_ID)));
}
});
View snackbarView = snackbar.getView();
TextView textView = (TextView) snackbarView.findViewById(android.support.design.R.id.snackbar_text);
textView.setMaxLines(5); //Or as much as you need
snackbar.show();
}
}
return;
}
Perfect answer, thanks, +1!
– Antonio Vlasic
Sep 18 '18 at 8:44
add a comment |
If you want to detect all the "states" (first time denied, just been denied, just been denied with "Never Ask Again" or permanently denied) you can do the following:
Create 2 booleans
private boolean beforeClickPermissionRat;
private boolean afterClickPermissionRat;
Set the first one before asking for permission:
beforeClickPermissionRat = shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE);
Set the second one inside your onRequestPermissionsResult method:
afterClickPermissionRat = shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE);
Use the following "table" to do whatever you need in onRequestPermissionsResult() (after checking that you still don't have the permission):
// before after
// FALSE FALSE = Was denied permanently, still denied permanently --> App Settings
// FALSE TRUE = First time deny, not denied permanently yet --> Nothing
// TRUE FALSE = Just been permanently denied --> Changing my caption to "Go to app settings to edit permissions"
// TRUE TRUE = Wasn't denied permanently, still not denied permanently --> Nothing
There's no point in checking the shouldShowRequestPermissionRationale before calling requestPermissions unless you want to show the rationale before requesting the permission. Showing the rationale only after the user denied the permission seems to be how most apps handle it nowadays though.
– Emanuel Moecklin
Dec 23 '16 at 21:59
2
@EmanuelMoecklin, as far as I know it's the only way to check if it's already been denied (by checking it before and after, as explained in my truth table) or if it's a first time deny (in my case I redirect the user to the app settings if it's permanently denied)
– mVck
Jan 30 '17 at 18:03
// TRUE FALSE
also occurs when user allows a permission after previously denying it.
– samis
Jul 25 '17 at 17:48
add a comment |
I had the same problem and I figured it out. To make life much simpler, I wrote an util class to handle runtime permissions.
public class PermissionUtil {
/*
* Check if version is marshmallow and above.
* Used in deciding to ask runtime permission
* */
public static boolean shouldAskPermission() {
return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M);
}
private static boolean shouldAskPermission(Context context, String permission){
if (shouldAskPermission()) {
int permissionResult = ActivityCompat.checkSelfPermission(context, permission);
if (permissionResult != PackageManager.PERMISSION_GRANTED) {
return true;
}
}
return false;
}
public static void checkPermission(Context context, String permission, PermissionAskListener listener){
/*
* If permission is not granted
* */
if (shouldAskPermission(context, permission)){
/*
* If permission denied previously
* */
if (((Activity)context).shouldShowRequestPermissionRationale(permission)) {
listener.onPermissionPreviouslyDenied();
} else {
/*
* Permission denied or first time requested
* */
if (PreferencesUtil.isFirstTimeAskingPermission(context, permission)) {
PreferencesUtil.firstTimeAskingPermission(context, permission, false);
listener.onPermissionAsk();
} else {
/*
* Handle the feature without permission or ask user to manually allow permission
* */
listener.onPermissionDisabled();
}
}
} else {
listener.onPermissionGranted();
}
}
/*
* Callback on various cases on checking permission
*
* 1. Below M, runtime permission not needed. In that case onPermissionGranted() would be called.
* If permission is already granted, onPermissionGranted() would be called.
*
* 2. Above M, if the permission is being asked first time onPermissionAsk() would be called.
*
* 3. Above M, if the permission is previously asked but not granted, onPermissionPreviouslyDenied()
* would be called.
*
* 4. Above M, if the permission is disabled by device policy or the user checked "Never ask again"
* check box on previous request permission, onPermissionDisabled() would be called.
* */
public interface PermissionAskListener {
/*
* Callback to ask permission
* */
void onPermissionAsk();
/*
* Callback on permission denied
* */
void onPermissionPreviouslyDenied();
/*
* Callback on permission "Never show again" checked and denied
* */
void onPermissionDisabled();
/*
* Callback on permission granted
* */
void onPermissionGranted();
}
}
And the PreferenceUtil methods are as follows.
public static void firstTimeAskingPermission(Context context, String permission, boolean isFirstTime){
SharedPreferences sharedPreference = context.getSharedPreferences(PREFS_FILE_NAME, MODE_PRIVATE;
sharedPreference.edit().putBoolean(permission, isFirstTime).apply();
}
public static boolean isFirstTimeAskingPermission(Context context, String permission){
return context.getSharedPreferences(PREFS_FILE_NAME, MODE_PRIVATE).getBoolean(permission, true);
}
Now, all you need is to use the method * checkPermission* with proper arguments.
Here is an example,
PermissionUtil.checkPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE,
new PermissionUtil.PermissionAskListener() {
@Override
public void onPermissionAsk() {
ActivityCompat.requestPermissions(
thisActivity,
new String{Manifest.permission.READ_CONTACTS},
REQUEST_EXTERNAL_STORAGE
);
}
@Override
public void onPermissionPreviouslyDenied() {
//show a dialog explaining permission and then request permission
}
@Override
public void onPermissionDisabled() {
Toast.makeText(context, "Permission Disabled.", Toast.LENGTH_SHORT).show();
}
@Override
public void onPermissionGranted() {
readContacts();
}
});
how does my app know whether the user has checked the "Never ask again"?
If user checked Never ask again, you'll get callback on onPermissionDisabled.
Happy coding :)
shouldShowRequestPermissionRationale i got error here, can you plz help me.
– Rucha Bhatt Joshi
Jun 16 '17 at 7:17
@RuchaBhatt What error you got?
– muthuraj
Jun 16 '17 at 7:36
i cant find this method shouldShowRequestPermissionRationale may be i failed to get context.. but it's fine i found other alternate solution.. Thank you for help :)
– Rucha Bhatt Joshi
Jun 16 '17 at 8:50
1
My bad. shouldShowRequestPermissionRationale is available through Activity, not context. I updated my answer by casting the context to Activity before calling that method. Check it out :)
– muthuraj
Jun 16 '17 at 13:52
add a comment |
Complete explanation for every case of permission
/**
* Case 1: User doesn't have permission
* Case 2: User has permission
*
* Case 3: User has never seen the permission Dialog
* Case 4: User has denied permission once but he din't clicked on "Never Show again" check box
* Case 5: User denied the permission and also clicked on the "Never Show again" check box.
* Case 6: User has allowed the permission
*
*/
public void handlePermission() {
if (ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// This is Case 1. Now we need to check further if permission was shown before or not
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// This is Case 4.
} else {
// This is Case 3. Request for permission here
}
} else {
// This is Case 2. You have permission now you can do anything related to it
}
}
public void onRequestPermissionsResult(int requestCode, String permissions, int grantResults) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// This is Case 2 (Permission is now granted)
} else {
// This is Case 1 again as Permission is not granted by user
//Now further we check if used denied permanently or not
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// case 4 User has denied permission but not permanently
} else {
// case 5. Permission denied permanently.
// You can open Permission setting's page from here now.
}
}
}
add a comment |
I wrote a shorthand for permission request in Android M. This code also handles backwards compatibility to older Android versions.
All the ugly code is extracted into a Fragment which attaches and detaches itself to the Activity requesting the permissions.You can use PermissionRequestManager
as following:
new PermissionRequestManager()
// We need a AppCompatActivity here, if you are not using support libraries you will have to slightly change
// the PermissionReuqestManager class
.withActivity(this)
// List all permissions you need
.withPermissions(android.Manifest.permission.CALL_PHONE, android.Manifest.permission.READ_CALENDAR)
// This Runnable is called whenever the request was successfull
.withSuccessHandler(new Runnable() {
@Override
public void run() {
// Do something with your permissions!
// This is called after the user has granted all
// permissions, we are one a older platform where
// the user does not need to grant permissions
// manually, or all permissions are already granted
}
})
// Optional, called when the user did not grant all permissions
.withFailureHandler(new Runnable() {
@Override
public void run() {
// This is called if the user has rejected one or all of the requested permissions
L.e(this.getClass().getSimpleName(), "Unable to request permission");
}
})
// After calling this, the user is prompted to grant the rights
.request();
Take a look: https://gist.github.com/crysxd/385b57d74045a8bd67c4110c34ab74aa
add a comment |
The method shouldShowRequestPermissionRationale() can be user to check whether the user selected the 'never asked again' option and denied the permission.
There's plenty of code examples, so I would rather explain how to use it for such a purpose, because I think its name and its implementation makes this more complicated that it actually is.
As explained in Requesting Permissions at Run Time, that method returns true if the option 'never ask again' is visible, false otherwise; so it returns false the very first time a dialog is shown, then from the second time on it returns true, and only if the user deny the permission selecting the option, at that point it returns false again.
To detect such a case, either you can detect the sequence false-true-false, or (more simple) you can have a flag which keeps track of the initial time the dialog is shown. After that, that method returns either true or false, where the false will allow you to detect when the option is selected.
add a comment |
Try this simple permission library. It will handle all operations related to permission in 3 easy steps. It saved my time. You can finish all permission related work in 15 mins.
It can handle Deny, It can handle Never ask again, It can call app settings for permission, It can give a Rational message, It can give a Denial message, It can give a list of accepted permissions, It can give a list of denied permissions and etc.
https://github.com/ParkSangGwon/TedPermission
Step 1: add your dependency
dependencies {
compile 'gun0912.ted:tedpermission:2.1.1'
//check the above link for latest libraries
}
Step2: Ask permissions
TedPermission.with(this)
.setPermissionListener(permissionlistener)
.setDeniedMessage("If you reject permission,you can not use this servicennPlease turn on permissions at [Setting] > [Permission]")
.setPermissions(Manifest.permission.READ_CONTACTS, Manifest.permission.ACCESS_FINE_LOCATION)
.check();
Step 3: Handle permission response
PermissionListener permissionlistener = new PermissionListener() {
@Override
public void onPermissionGranted() {
Toast.makeText(MainActivity.this, "Permission Granted", Toast.LENGTH_SHORT).show();
}
@Override
public void onPermissionDenied(ArrayList<String> deniedPermissions) {
Toast.makeText(MainActivity.this, "Permission Deniedn" + deniedPermissions.toString(), Toast.LENGTH_SHORT).show();
}
};
Great. It saved my time
– Vigneswaran A
Apr 23 '18 at 7:44
Nice, easy to use
– Uray Febri
Aug 6 '18 at 7:21
add a comment |
A useful function to determine if an arbitrary permission has been blocked from requesting (in Kotlin):
private fun isPermissionBlockedFromAsking(activity: Activity, permission: String): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED
&& !activity.shouldShowRequestPermissionRationale(permission)
&& PreferenceManager.getDefaultSharedPreferences(activity).getBoolean(permission, false)
}
return false
}
Use of this requires setting a shared preference boolean with the name of your desired permission (e.g. android.Manifest.permission.READ_PHONE_STATE
) to true
when you first request a permission.
Explanation:
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
as some of the code may only be run on API level 23+.
ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED
to check we don't already have the permission.
!activity.shouldShowRequestPermissionRationale(permission)
to check whether the user has denied the app asking again. Due to quirks of this function, the following line is also required.
PreferenceManager.getDefaultSharedPreferences(activity).getBoolean(permission, false)
this is used (along with setting the value to true on first permission request) to distinguish between the "Never asked" and "Never ask again" states, as the previous line doesn't return this information.
add a comment |
Please don't throw stones at me for this solution.
This works but is a bit "hacky".
When you call requestPermissions
, register the current time.
mAskedPermissionTime = System.currentTimeMillis();
Then in onRequestPermissionsResult
if the result is not granted, check the time again.
if (System.currentTimeMillis() - mAskedPermissionTime < 100)
Since the user did cannot possibly click so fast on the deny button, we know that he selected "never ask again" because the callback is instant.
Use at your own risks.
what if we see that requested dialog for 5 minutes and then deny?
– saksham
May 11 '18 at 9:59
It relies on the user accepting fast, not slow
– Antzi
May 11 '18 at 15:41
Then what is the use of this if it can't fulfill the basic requirement. A code can be a hack as accepted if it clearly fulfills all the requirements in every case else not.
– saksham
May 13 '18 at 5:42
add a comment |
You can use
shouldShowRequestPermissionRationale()
inside
onRequestPermissionsResult()
See the example below:
Check if it has permission when the user clicks the button:
@Override
public void onClick(View v) {
if (v.getId() == R.id.appCompatBtn_changeProfileCoverPhoto) {
if (Build.VERSION.SDK_INT < 23) { // API < 23 don't need to ask permission
navigateTo(MainActivity.class); // Navigate to activity to change photos
} else {
if (ContextCompat.checkSelfPermission(SettingsActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted yet. Ask for permission...
requestWriteExternalPermission();
} else {
// Permission is already granted, good to go :)
navigateTo(MainActivity.class);
}
}
}
}
When the user answer the permission dialog box we will go to onRequestPermissionResult:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == WRITE_EXTERNAL_PERMISSION_REQUEST_CODE) {
// Case 1. Permission is granted.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(SettingsActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
// Before navigating, I still check one more time the permission for good practice.
navigateTo(MainActivity.class);
}
} else { // Case 2. Permission was refused
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// Case 2.1. shouldShowRequest... returns true because the
// permission was denied before. If it is the first time the app is running we will
// end up in this part of the code. Because he need to deny at least once to get
// to onRequestPermissionsResult.
Snackbar snackbar = Snackbar.make(findViewById(R.id.relLayout_container), R.string.you_must_verify_permissions_to_send_media, Snackbar.LENGTH_LONG);
snackbar.setAction("VERIFY", new View.OnClickListener() {
@Override
public void onClick(View v) {
ActivityCompat.requestPermissions(SettingsActivity.this
, new String{Manifest.permission.WRITE_EXTERNAL_STORAGE}
, WRITE_EXTERNAL_PERMISSION_REQUEST_CODE);
}
});
snackbar.show();
} else {
// Case 2.2. Permission was already denied and the user checked "Never ask again".
// Navigate user to settings if he choose to allow this time.
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.instructions_to_turn_on_storage_permission)
.setPositiveButton(getString(R.string.settings), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent settingsIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
settingsIntent.setData(uri);
startActivityForResult(settingsIntent, 7);
}
})
.setNegativeButton(getString(R.string.not_now), null);
Dialog dialog = builder.create();
dialog.show();
}
}
}
}
add a comment |
you can listener pretty.
Listener
interface PermissionListener {
fun onNeedPermission()
fun onPermissionPreviouslyDenied(numberDenyPermission: Int)
fun onPermissionDisabledPermanently(numberDenyPermission: Int)
fun onPermissionGranted()
}
MainClass for permission
class PermissionUtil {
private val PREFS_FILENAME = "permission"
private val TAG = "PermissionUtil"
private fun shouldAskPermission(context: Context, permission: String): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val permissionResult = ActivityCompat.checkSelfPermission(context, permission)
if (permissionResult != PackageManager.PERMISSION_GRANTED) {
return true
}
}
return false
}
fun checkPermission(context: Context, permission: String, listener: PermissionListener) {
Log.i(TAG, "CheckPermission for $permission")
if (shouldAskPermission(context, permission)) {
// Load history permission
val sharedPreference = context.getSharedPreferences(PREFS_FILENAME, 0)
val numberShowPermissionDialog = sharedPreference.getInt(permission, 0)
if (numberShowPermissionDialog == 0) {
(context as? Activity)?.let {
if (ActivityCompat.shouldShowRequestPermissionRationale(it, permission)) {
Log.e(TAG, "User has denied permission but not permanently")
listener.onPermissionPreviouslyDenied(numberShowPermissionDialog)
} else {
Log.e(TAG, "Permission denied permanently.")
listener.onPermissionDisabledPermanently(numberShowPermissionDialog)
}
} ?: kotlin.run {
listener.onNeedPermission()
}
} else {
// Is FirstTime
listener.onNeedPermission()
}
// Save history permission
sharedPreference.edit().putInt(permission, numberShowPermissionDialog + 1).apply()
} else {
listener.onPermissionGranted()
}
}
}
Used by this way
PermissionUtil().checkPermission(this, Manifest.permission.ACCESS_FINE_LOCATION,
object : PermissionListener {
override fun onNeedPermission() {
log("---------------------->onNeedPermission")
// ActivityCompat.requestPermissions(this@SplashActivity,
// Array(1) { Manifest.permission.ACCESS_FINE_LOCATION },
// 118)
}
override fun onPermissionPreviouslyDenied(numberDenyPermission: Int) {
log("---------------------->onPermissionPreviouslyDenied")
}
override fun onPermissionDisabledPermanently(numberDenyPermission: Int) {
log("---------------------->onPermissionDisabled")
}
override fun onPermissionGranted() {
log("---------------------->onPermissionGranted")
}
})
override onRequestPermissionsResult in activity or fragmnet
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
if (requestCode == 118) {
if (permissions[0] == Manifest.permission.ACCESS_FINE_LOCATION && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
getLastLocationInMap()
}
}
}
add a comment |
I would also like to obtain the information whether or not the user has selected "never ask again". I have achieved a 'almost solution' with an ugly looking flag, but before I tell you how, I will tell you about my motivation:
I would like to offer the permission referring functionality initially. If the user uses it and has no rights, he/she gets the either the 1th dialog from above or both the 2nd and 3rd. When the user has chosen 'Never ask again' I would like to disable the functionality and to display it differently. - My action is triggered by a spinner text entry, I would also like to add '(Permission revoked)' to the label text displayed. This shows to the user: 'There is functionality but I cannot use it, due to my permission settings.' However, this does not seem to be possible, as I cannot check whether or not 'Never ask again' has been chosen.
I came to a solution I can live with by having my functionality always enabled with an active permission check. I am showing a Toast message in onRequestPermissionsResult() in case of a negative response but only if I have not shown my custom rationale popup. So if the user has chosen 'Never ask again' he gets a toast message only. If the user is reluctant to chose 'never ask again' he gets only the custom rationale and the permission request popup by the operation system but not toast, as three notifications in a row would be too much pain.
add a comment |
Instead you will receive callback on onRequestPermissionsResult()
as PERMISSION_DENIED when you request permission again while falling in false condition of shouldShowRequestPermissionRationale()
From Android doc:
When the system asks the user to grant a permission, the user has the option of telling the system not to ask for that permission again. In that case, any time an app uses requestPermissions()
to ask for that permission again, the system immediately denies the request. The system calls your onRequestPermissionsResult()
callback method and passes PERMISSION_DENIED
, the same way it would if the user had explicitly rejected your request again. This means that when you call requestPermissions()
, you cannot assume that any direct interaction with the user has taken place.
add a comment |
I have to implement dynamic permission for camera. Where 3 possible cases occurs: 1. Allow, 2. Denied, 3. Don't ask again.
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) {
for (String permission : permissions) {
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), permission)) {
//denied
Log.e("denied", permission);
} else {
if (ActivityCompat.checkSelfPermission(getActivity(), permission) == PackageManager.PERMISSION_GRANTED) {
//allowed
Log.e("allowed", permission);
} else {
//set to never ask again
Log.e("set to never ask again", permission);
//do something here.
}
}
}
if (requestCode != MaterialBarcodeScanner.RC_HANDLE_CAMERA_PERM) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
return;
}
if (grantResults.length != 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mScannerView.setResultHandler(this);
mScannerView.startCamera(mCameraId);
mScannerView.setFlash(mFlash);
mScannerView.setAutoFocus(mAutoFocus);
return;
} else {
//set to never ask again
Log.e("set to never ask again", permissions[0]);
}
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Error")
.setMessage(R.string.no_camera_permission)
.setPositiveButton(android.R.string.ok, listener)
.show();
}
private void insertDummyContactWrapper() {
int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.CAMERA);
if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String{Manifest.permission.CAMERA},
REQUEST_CODE_ASK_PERMISSIONS);
return;
}
mScannerView.setResultHandler(this);
mScannerView.startCamera(mCameraId);
mScannerView.setFlash(mFlash);
mScannerView.setAutoFocus(mAutoFocus);
}
private int checkSelfPermission(String camera) {
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
return REQUEST_CODE_ASK_PERMISSIONS;
} else {
return REQUEST_NOT_CODE_ASK_PERMISSIONS;
}
}
add a comment |
You can use if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)
method to detect whether never ask is checked or not.
For more reference : Check this
To check for multiple permissions use:
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)
|| ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|| ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)
|| ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) {
showDialogOK("Service Permissions are required for this app",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
checkAndRequestPermissions();
break;
case DialogInterface.BUTTON_NEGATIVE:
// proceed with logic by disabling the related features or quit the app.
finish();
break;
}
}
});
}
//permission is denied (and never ask again is checked)
//shouldShowRequestPermissionRationale will return false
else {
explain("You need to give some mandatory permissions to continue. Do you want to go to app settings?");
// //proceed with logic by disabling the related features or quit the app.
}
explain() method
private void explain(String msg){
final android.support.v7.app.AlertDialog.Builder dialog = new android.support.v7.app.AlertDialog.Builder(this);
dialog.setMessage(msg)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
// permissionsclass.requestPermission(type,code);
startActivity(new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:com.exampledemo.parsaniahardik.marshmallowpermission")));
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
finish();
}
});
dialog.show();
}
Above code will also show dialog, which will redirect user to app settings screen from where he can give permission if had checked never ask again button.
add a comment |
Expanding on mVck's answer above, the following logic determines whether "Never ask again" has been checked for a given Permission Request:
bool bStorage = grantResults[0] == Permission.Granted;
bool bNeverAskForStorage =
!bStorage && (
_bStorageRationaleBefore == true && _bStorageRationaleAfter == false ||
_bStorageRationaleBefore == false && _bStorageRationaleAfter == false
);
which is excerpted from below (for the full example see this answer)
private bool _bStorageRationaleBefore;
private bool _bStorageRationaleAfter;
private const int ANDROID_PERMISSION_REQUEST_CODE__SDCARD = 2;
//private const int ANDROID_PERMISSION_REQUEST_CODE__CAMERA = 1;
private const int ANDROID_PERMISSION_REQUEST_CODE__NONE = 0;
public override void OnRequestPermissionsResult(int requestCode, string permissions, [GeneratedEnum] Permission grantResults)
{
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode)
{
case ANDROID_PERMISSION_REQUEST_CODE__SDCARD:
_bStorageRationaleAfter = ShouldShowRequestPermissionRationale(Android.Manifest.Permission.WriteExternalStorage);
bool bStorage = grantResults[0] == Permission.Granted;
bool bNeverAskForStorage =
!bStorage && (
_bStorageRationaleBefore == true && _bStorageRationaleAfter == false ||
_bStorageRationaleBefore == false && _bStorageRationaleAfter == false
);
break;
}
}
private List<string> GetRequiredPermissions(out int requestCode)
{
// Android v6 requires explicit permission granting from user at runtime for security reasons
requestCode = ANDROID_PERMISSION_REQUEST_CODE__NONE; // 0
List<string> requiredPermissions = new List<string>();
_bStorageRationaleBefore = ShouldShowRequestPermissionRationale(Android.Manifest.Permission.WriteExternalStorage);
Permission writeExternalStoragePerm = ApplicationContext.CheckSelfPermission(Android.Manifest.Permission.WriteExternalStorage);
//if(extStoragePerm == Permission.Denied)
if (writeExternalStoragePerm != Permission.Granted)
{
requestCode |= ANDROID_PERMISSION_REQUEST_CODE__SDCARD;
requiredPermissions.Add(Android.Manifest.Permission.WriteExternalStorage);
}
return requiredPermissions;
}
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Android v6 requires explicit permission granting from user at runtime for security reasons
int requestCode;
List<string> requiredPermissions = GetRequiredPermissions(out requestCode);
if (requiredPermissions != null && requiredPermissions.Count > 0)
{
if (requestCode >= ANDROID_PERMISSION_REQUEST_CODE__SDCARD)
{
_savedInstanceState = savedInstanceState;
RequestPermissions(requiredPermissions.ToArray(), requestCode);
return;
}
}
}
OnCreate2(savedInstanceState);
}
add a comment |
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) {
switch (requestCode) {
case PERMISSIONS_REQUEST_EXTERNAL_STORAGE: {
if (grantResults.length > 0) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// Denied
} else {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
// To what you want
} else {
// Bob never checked click
}
}
}
}
}
}
add a comment |
you can read android official document
Request App Permissions
or you can find many popular android permission libraries on Github
- PermissionsDispatcher
- RxPermissions
- easypermissions
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f30719047%2fandroid-m-check-runtime-permission-how-to-determine-if-the-user-checked-nev%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
23 Answers
23
active
oldest
votes
23 Answers
23
active
oldest
votes
active
oldest
votes
active
oldest
votes
Developer Preview 2 brings some changes to how permissions are requested by the app (see also http://developer.android.com/preview/support.html#preview2-notes).
The first dialog now looks like this:
There's no "Never show again" check-box (unlike developer preview 1). If the user denies the permission and if the permission is essential for the app it could present another dialog to explain the reason the app asks for that permission, e.g. like this:
If the user declines again the app should either shut down if it absolutely needs that permission or keep running with limited functionality. If the user reconsiders (and selects re-try), the permission is requested again. This time the prompt looks like this:
The second time the "Never ask again" check-box is shown. If the user denies again and the check-box is ticked nothing more should happen.
Whether or not the check-box is ticked can be determined by using Activity.shouldShowRequestPermissionRationale(String), e.g. like this:
if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_CONTACTS)) {...
That's what the Android documentation says (https://developer.android.com/training/permissions/requesting.html):
To help find the situations where you need to provide extra
explanation, the system provides the
Activity.shouldShowRequestPermissionRationale(String) method. This
method returns true if the app has requested this permission
previously and the user denied the request. That indicates that you
should probably explain to the user why you need the permission.
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. The method also returns false if the device
policy prohibits the app from having that permission.
To know if the user denied with "never ask again" you can check again the shouldShowRequestPermissionRationale method in your onRequestPermissionsResult when the user did not grant the permission.
@Override
public void onRequestPermissionsResult(int requestCode, String permissions, int grantResults) {
if (requestCode == REQUEST_PERMISSION) {
// for each permission check if the user granted/denied them
// you may want to group the rationale in a single dialog,
// this is just an example
for (int i = 0, len = permissions.length; i < len; i++) {
String permission = permissions[i];
if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
// user rejected the permission
boolean showRationale = shouldShowRequestPermissionRationale( permission );
if (! showRationale) {
// user also CHECKED "never ask again"
// you can either enable some fall back,
// disable features of your app
// or open another dialog explaining
// again the permission and directing to
// the app setting
} else if (Manifest.permission.WRITE_CONTACTS.equals(permission)) {
showRationale(permission, R.string.permission_denied_contacts);
// user did NOT check "never ask again"
// this is a good place to explain the user
// why you need the permission and ask if he wants
// to accept it (the rationale)
} else if ( /* possibly check more permissions...*/ ) {
}
}
}
}
}
You can open your app setting with this code:
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, REQUEST_PERMISSION_SETTING);
There is no way of sending the user directly to the Authorization page.
24
I verified return value of shouldShowRequestPermissionRationale() method to false for checking if user selected "Never ask again". But I am also getting its value as false for very first time when ask for permission. So I am not able to differentiate if user selected "Never ask again" checkbox or not. Please suggest??
– Sagar Trehan
Oct 5 '15 at 8:24
27
According to my understanding shouldShowRationalePermissionRationale() method returns false in three cases: 1. If we call this method very first time before asking permission. 2. If user selects "Don't ask again" and deny permission. 3. If the device policy prohibits the app from having that permission
– Sagar Trehan
Oct 7 '15 at 9:01
13
All good... but we, developers, really need to know if the user said "never ask again" or not. I have a nice button to access a feature. The first time the user click: should ask rationale? nope, ask permission. The user deny. User click again the button: rationale? yep! Show rationale, user say Ok, then deny and never ask again (ok he is an idiot, but users often are). Later user press again the button, rationale? nope, ask permission, nothing happens for the user. I really need a way, there, to tell the user: hey man if you want this feature now go to the app setting and give the permission.
– Daniele Segato
Oct 16 '15 at 14:19
3
Great @EmanuelMoecklin this is better then Google Documentation now :D
– Daniele Segato
Oct 17 '15 at 14:58
4
onRequestPermissionsResult won't be called unless you request the permission. Since there's no check-box "Never ask again" the first time the permission is requested, shouldShowRequestPermissionRationale will return True (permission requested but without never ask again). Consequently the rationale is always shown the first time the user rejects the permission but after that only if the check-box wasn't ticked.
– Emanuel Moecklin
Oct 19 '15 at 15:33
|
show 28 more comments
Developer Preview 2 brings some changes to how permissions are requested by the app (see also http://developer.android.com/preview/support.html#preview2-notes).
The first dialog now looks like this:
There's no "Never show again" check-box (unlike developer preview 1). If the user denies the permission and if the permission is essential for the app it could present another dialog to explain the reason the app asks for that permission, e.g. like this:
If the user declines again the app should either shut down if it absolutely needs that permission or keep running with limited functionality. If the user reconsiders (and selects re-try), the permission is requested again. This time the prompt looks like this:
The second time the "Never ask again" check-box is shown. If the user denies again and the check-box is ticked nothing more should happen.
Whether or not the check-box is ticked can be determined by using Activity.shouldShowRequestPermissionRationale(String), e.g. like this:
if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_CONTACTS)) {...
That's what the Android documentation says (https://developer.android.com/training/permissions/requesting.html):
To help find the situations where you need to provide extra
explanation, the system provides the
Activity.shouldShowRequestPermissionRationale(String) method. This
method returns true if the app has requested this permission
previously and the user denied the request. That indicates that you
should probably explain to the user why you need the permission.
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. The method also returns false if the device
policy prohibits the app from having that permission.
To know if the user denied with "never ask again" you can check again the shouldShowRequestPermissionRationale method in your onRequestPermissionsResult when the user did not grant the permission.
@Override
public void onRequestPermissionsResult(int requestCode, String permissions, int grantResults) {
if (requestCode == REQUEST_PERMISSION) {
// for each permission check if the user granted/denied them
// you may want to group the rationale in a single dialog,
// this is just an example
for (int i = 0, len = permissions.length; i < len; i++) {
String permission = permissions[i];
if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
// user rejected the permission
boolean showRationale = shouldShowRequestPermissionRationale( permission );
if (! showRationale) {
// user also CHECKED "never ask again"
// you can either enable some fall back,
// disable features of your app
// or open another dialog explaining
// again the permission and directing to
// the app setting
} else if (Manifest.permission.WRITE_CONTACTS.equals(permission)) {
showRationale(permission, R.string.permission_denied_contacts);
// user did NOT check "never ask again"
// this is a good place to explain the user
// why you need the permission and ask if he wants
// to accept it (the rationale)
} else if ( /* possibly check more permissions...*/ ) {
}
}
}
}
}
You can open your app setting with this code:
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, REQUEST_PERMISSION_SETTING);
There is no way of sending the user directly to the Authorization page.
24
I verified return value of shouldShowRequestPermissionRationale() method to false for checking if user selected "Never ask again". But I am also getting its value as false for very first time when ask for permission. So I am not able to differentiate if user selected "Never ask again" checkbox or not. Please suggest??
– Sagar Trehan
Oct 5 '15 at 8:24
27
According to my understanding shouldShowRationalePermissionRationale() method returns false in three cases: 1. If we call this method very first time before asking permission. 2. If user selects "Don't ask again" and deny permission. 3. If the device policy prohibits the app from having that permission
– Sagar Trehan
Oct 7 '15 at 9:01
13
All good... but we, developers, really need to know if the user said "never ask again" or not. I have a nice button to access a feature. The first time the user click: should ask rationale? nope, ask permission. The user deny. User click again the button: rationale? yep! Show rationale, user say Ok, then deny and never ask again (ok he is an idiot, but users often are). Later user press again the button, rationale? nope, ask permission, nothing happens for the user. I really need a way, there, to tell the user: hey man if you want this feature now go to the app setting and give the permission.
– Daniele Segato
Oct 16 '15 at 14:19
3
Great @EmanuelMoecklin this is better then Google Documentation now :D
– Daniele Segato
Oct 17 '15 at 14:58
4
onRequestPermissionsResult won't be called unless you request the permission. Since there's no check-box "Never ask again" the first time the permission is requested, shouldShowRequestPermissionRationale will return True (permission requested but without never ask again). Consequently the rationale is always shown the first time the user rejects the permission but after that only if the check-box wasn't ticked.
– Emanuel Moecklin
Oct 19 '15 at 15:33
|
show 28 more comments
Developer Preview 2 brings some changes to how permissions are requested by the app (see also http://developer.android.com/preview/support.html#preview2-notes).
The first dialog now looks like this:
There's no "Never show again" check-box (unlike developer preview 1). If the user denies the permission and if the permission is essential for the app it could present another dialog to explain the reason the app asks for that permission, e.g. like this:
If the user declines again the app should either shut down if it absolutely needs that permission or keep running with limited functionality. If the user reconsiders (and selects re-try), the permission is requested again. This time the prompt looks like this:
The second time the "Never ask again" check-box is shown. If the user denies again and the check-box is ticked nothing more should happen.
Whether or not the check-box is ticked can be determined by using Activity.shouldShowRequestPermissionRationale(String), e.g. like this:
if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_CONTACTS)) {...
That's what the Android documentation says (https://developer.android.com/training/permissions/requesting.html):
To help find the situations where you need to provide extra
explanation, the system provides the
Activity.shouldShowRequestPermissionRationale(String) method. This
method returns true if the app has requested this permission
previously and the user denied the request. That indicates that you
should probably explain to the user why you need the permission.
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. The method also returns false if the device
policy prohibits the app from having that permission.
To know if the user denied with "never ask again" you can check again the shouldShowRequestPermissionRationale method in your onRequestPermissionsResult when the user did not grant the permission.
@Override
public void onRequestPermissionsResult(int requestCode, String permissions, int grantResults) {
if (requestCode == REQUEST_PERMISSION) {
// for each permission check if the user granted/denied them
// you may want to group the rationale in a single dialog,
// this is just an example
for (int i = 0, len = permissions.length; i < len; i++) {
String permission = permissions[i];
if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
// user rejected the permission
boolean showRationale = shouldShowRequestPermissionRationale( permission );
if (! showRationale) {
// user also CHECKED "never ask again"
// you can either enable some fall back,
// disable features of your app
// or open another dialog explaining
// again the permission and directing to
// the app setting
} else if (Manifest.permission.WRITE_CONTACTS.equals(permission)) {
showRationale(permission, R.string.permission_denied_contacts);
// user did NOT check "never ask again"
// this is a good place to explain the user
// why you need the permission and ask if he wants
// to accept it (the rationale)
} else if ( /* possibly check more permissions...*/ ) {
}
}
}
}
}
You can open your app setting with this code:
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, REQUEST_PERMISSION_SETTING);
There is no way of sending the user directly to the Authorization page.
Developer Preview 2 brings some changes to how permissions are requested by the app (see also http://developer.android.com/preview/support.html#preview2-notes).
The first dialog now looks like this:
There's no "Never show again" check-box (unlike developer preview 1). If the user denies the permission and if the permission is essential for the app it could present another dialog to explain the reason the app asks for that permission, e.g. like this:
If the user declines again the app should either shut down if it absolutely needs that permission or keep running with limited functionality. If the user reconsiders (and selects re-try), the permission is requested again. This time the prompt looks like this:
The second time the "Never ask again" check-box is shown. If the user denies again and the check-box is ticked nothing more should happen.
Whether or not the check-box is ticked can be determined by using Activity.shouldShowRequestPermissionRationale(String), e.g. like this:
if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_CONTACTS)) {...
That's what the Android documentation says (https://developer.android.com/training/permissions/requesting.html):
To help find the situations where you need to provide extra
explanation, the system provides the
Activity.shouldShowRequestPermissionRationale(String) method. This
method returns true if the app has requested this permission
previously and the user denied the request. That indicates that you
should probably explain to the user why you need the permission.
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. The method also returns false if the device
policy prohibits the app from having that permission.
To know if the user denied with "never ask again" you can check again the shouldShowRequestPermissionRationale method in your onRequestPermissionsResult when the user did not grant the permission.
@Override
public void onRequestPermissionsResult(int requestCode, String permissions, int grantResults) {
if (requestCode == REQUEST_PERMISSION) {
// for each permission check if the user granted/denied them
// you may want to group the rationale in a single dialog,
// this is just an example
for (int i = 0, len = permissions.length; i < len; i++) {
String permission = permissions[i];
if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
// user rejected the permission
boolean showRationale = shouldShowRequestPermissionRationale( permission );
if (! showRationale) {
// user also CHECKED "never ask again"
// you can either enable some fall back,
// disable features of your app
// or open another dialog explaining
// again the permission and directing to
// the app setting
} else if (Manifest.permission.WRITE_CONTACTS.equals(permission)) {
showRationale(permission, R.string.permission_denied_contacts);
// user did NOT check "never ask again"
// this is a good place to explain the user
// why you need the permission and ask if he wants
// to accept it (the rationale)
} else if ( /* possibly check more permissions...*/ ) {
}
}
}
}
}
You can open your app setting with this code:
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, REQUEST_PERMISSION_SETTING);
There is no way of sending the user directly to the Authorization page.
edited Dec 23 '16 at 21:48
answered Aug 10 '15 at 17:33
Emanuel MoecklinEmanuel Moecklin
19.9k85671
19.9k85671
24
I verified return value of shouldShowRequestPermissionRationale() method to false for checking if user selected "Never ask again". But I am also getting its value as false for very first time when ask for permission. So I am not able to differentiate if user selected "Never ask again" checkbox or not. Please suggest??
– Sagar Trehan
Oct 5 '15 at 8:24
27
According to my understanding shouldShowRationalePermissionRationale() method returns false in three cases: 1. If we call this method very first time before asking permission. 2. If user selects "Don't ask again" and deny permission. 3. If the device policy prohibits the app from having that permission
– Sagar Trehan
Oct 7 '15 at 9:01
13
All good... but we, developers, really need to know if the user said "never ask again" or not. I have a nice button to access a feature. The first time the user click: should ask rationale? nope, ask permission. The user deny. User click again the button: rationale? yep! Show rationale, user say Ok, then deny and never ask again (ok he is an idiot, but users often are). Later user press again the button, rationale? nope, ask permission, nothing happens for the user. I really need a way, there, to tell the user: hey man if you want this feature now go to the app setting and give the permission.
– Daniele Segato
Oct 16 '15 at 14:19
3
Great @EmanuelMoecklin this is better then Google Documentation now :D
– Daniele Segato
Oct 17 '15 at 14:58
4
onRequestPermissionsResult won't be called unless you request the permission. Since there's no check-box "Never ask again" the first time the permission is requested, shouldShowRequestPermissionRationale will return True (permission requested but without never ask again). Consequently the rationale is always shown the first time the user rejects the permission but after that only if the check-box wasn't ticked.
– Emanuel Moecklin
Oct 19 '15 at 15:33
|
show 28 more comments
24
I verified return value of shouldShowRequestPermissionRationale() method to false for checking if user selected "Never ask again". But I am also getting its value as false for very first time when ask for permission. So I am not able to differentiate if user selected "Never ask again" checkbox or not. Please suggest??
– Sagar Trehan
Oct 5 '15 at 8:24
27
According to my understanding shouldShowRationalePermissionRationale() method returns false in three cases: 1. If we call this method very first time before asking permission. 2. If user selects "Don't ask again" and deny permission. 3. If the device policy prohibits the app from having that permission
– Sagar Trehan
Oct 7 '15 at 9:01
13
All good... but we, developers, really need to know if the user said "never ask again" or not. I have a nice button to access a feature. The first time the user click: should ask rationale? nope, ask permission. The user deny. User click again the button: rationale? yep! Show rationale, user say Ok, then deny and never ask again (ok he is an idiot, but users often are). Later user press again the button, rationale? nope, ask permission, nothing happens for the user. I really need a way, there, to tell the user: hey man if you want this feature now go to the app setting and give the permission.
– Daniele Segato
Oct 16 '15 at 14:19
3
Great @EmanuelMoecklin this is better then Google Documentation now :D
– Daniele Segato
Oct 17 '15 at 14:58
4
onRequestPermissionsResult won't be called unless you request the permission. Since there's no check-box "Never ask again" the first time the permission is requested, shouldShowRequestPermissionRationale will return True (permission requested but without never ask again). Consequently the rationale is always shown the first time the user rejects the permission but after that only if the check-box wasn't ticked.
– Emanuel Moecklin
Oct 19 '15 at 15:33
24
24
I verified return value of shouldShowRequestPermissionRationale() method to false for checking if user selected "Never ask again". But I am also getting its value as false for very first time when ask for permission. So I am not able to differentiate if user selected "Never ask again" checkbox or not. Please suggest??
– Sagar Trehan
Oct 5 '15 at 8:24
I verified return value of shouldShowRequestPermissionRationale() method to false for checking if user selected "Never ask again". But I am also getting its value as false for very first time when ask for permission. So I am not able to differentiate if user selected "Never ask again" checkbox or not. Please suggest??
– Sagar Trehan
Oct 5 '15 at 8:24
27
27
According to my understanding shouldShowRationalePermissionRationale() method returns false in three cases: 1. If we call this method very first time before asking permission. 2. If user selects "Don't ask again" and deny permission. 3. If the device policy prohibits the app from having that permission
– Sagar Trehan
Oct 7 '15 at 9:01
According to my understanding shouldShowRationalePermissionRationale() method returns false in three cases: 1. If we call this method very first time before asking permission. 2. If user selects "Don't ask again" and deny permission. 3. If the device policy prohibits the app from having that permission
– Sagar Trehan
Oct 7 '15 at 9:01
13
13
All good... but we, developers, really need to know if the user said "never ask again" or not. I have a nice button to access a feature. The first time the user click: should ask rationale? nope, ask permission. The user deny. User click again the button: rationale? yep! Show rationale, user say Ok, then deny and never ask again (ok he is an idiot, but users often are). Later user press again the button, rationale? nope, ask permission, nothing happens for the user. I really need a way, there, to tell the user: hey man if you want this feature now go to the app setting and give the permission.
– Daniele Segato
Oct 16 '15 at 14:19
All good... but we, developers, really need to know if the user said "never ask again" or not. I have a nice button to access a feature. The first time the user click: should ask rationale? nope, ask permission. The user deny. User click again the button: rationale? yep! Show rationale, user say Ok, then deny and never ask again (ok he is an idiot, but users often are). Later user press again the button, rationale? nope, ask permission, nothing happens for the user. I really need a way, there, to tell the user: hey man if you want this feature now go to the app setting and give the permission.
– Daniele Segato
Oct 16 '15 at 14:19
3
3
Great @EmanuelMoecklin this is better then Google Documentation now :D
– Daniele Segato
Oct 17 '15 at 14:58
Great @EmanuelMoecklin this is better then Google Documentation now :D
– Daniele Segato
Oct 17 '15 at 14:58
4
4
onRequestPermissionsResult won't be called unless you request the permission. Since there's no check-box "Never ask again" the first time the permission is requested, shouldShowRequestPermissionRationale will return True (permission requested but without never ask again). Consequently the rationale is always shown the first time the user rejects the permission but after that only if the check-box wasn't ticked.
– Emanuel Moecklin
Oct 19 '15 at 15:33
onRequestPermissionsResult won't be called unless you request the permission. Since there's no check-box "Never ask again" the first time the permission is requested, shouldShowRequestPermissionRationale will return True (permission requested but without never ask again). Consequently the rationale is always shown the first time the user rejects the permission but after that only if the check-box wasn't ticked.
– Emanuel Moecklin
Oct 19 '15 at 15:33
|
show 28 more comments
You can check shouldShowRequestPermissionRationale()
in your onRequestPermissionsResult()
.
https://youtu.be/C8lUdPVSzDk?t=2m23s
Check whether permission was granted or not in onRequestPermissionsResult()
. If not then check shouldShowRequestPermissionRationale()
.
- If this method returns
true
then show an explanation that why this particular permission is needed. Then depending on user's choice againrequestPermissions()
. - If it returns
false
then show an error message that permission was not granted and app cannot proceed further or a particular feature is disabled.
Below is sample code.
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case STORAGE_PERMISSION_REQUEST:
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted :)
downloadFile();
} else {
// permission was not granted
if (getActivity() == null) {
return;
}
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
showStoragePermissionRationale();
} else {
Snackbar snackbar = Snackbar.make(getView(), getResources().getString(R.string.message_no_storage_permission_snackbar), Snackbar.LENGTH_LONG);
snackbar.setAction(getResources().getString(R.string.settings), new View.OnClickListener() {
@Override
public void onClick(View v) {
if (getActivity() == null) {
return;
}
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getActivity().getPackageName(), null);
intent.setData(uri);
OrderDetailFragment.this.startActivity(intent);
}
});
snackbar.show();
}
}
break;
}
}
Apparently, google maps does exactly this for location permission.
Thank you for the picture and the Youtube link. It matches more or less my own answer. It has to be noted that the question was asked when only the developer preview 1 was available which didn't have the shouldShowRequestPermissionRationale method.
– Emanuel Moecklin
Nov 13 '15 at 17:22
i'm new in android and i want to over ride this onRequestPermissionsResult() method. but I'm getting error that it must implement a super type method. can you tell how to use this
– Andrain
Nov 18 '15 at 8:50
add a comment |
You can check shouldShowRequestPermissionRationale()
in your onRequestPermissionsResult()
.
https://youtu.be/C8lUdPVSzDk?t=2m23s
Check whether permission was granted or not in onRequestPermissionsResult()
. If not then check shouldShowRequestPermissionRationale()
.
- If this method returns
true
then show an explanation that why this particular permission is needed. Then depending on user's choice againrequestPermissions()
. - If it returns
false
then show an error message that permission was not granted and app cannot proceed further or a particular feature is disabled.
Below is sample code.
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case STORAGE_PERMISSION_REQUEST:
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted :)
downloadFile();
} else {
// permission was not granted
if (getActivity() == null) {
return;
}
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
showStoragePermissionRationale();
} else {
Snackbar snackbar = Snackbar.make(getView(), getResources().getString(R.string.message_no_storage_permission_snackbar), Snackbar.LENGTH_LONG);
snackbar.setAction(getResources().getString(R.string.settings), new View.OnClickListener() {
@Override
public void onClick(View v) {
if (getActivity() == null) {
return;
}
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getActivity().getPackageName(), null);
intent.setData(uri);
OrderDetailFragment.this.startActivity(intent);
}
});
snackbar.show();
}
}
break;
}
}
Apparently, google maps does exactly this for location permission.
Thank you for the picture and the Youtube link. It matches more or less my own answer. It has to be noted that the question was asked when only the developer preview 1 was available which didn't have the shouldShowRequestPermissionRationale method.
– Emanuel Moecklin
Nov 13 '15 at 17:22
i'm new in android and i want to over ride this onRequestPermissionsResult() method. but I'm getting error that it must implement a super type method. can you tell how to use this
– Andrain
Nov 18 '15 at 8:50
add a comment |
You can check shouldShowRequestPermissionRationale()
in your onRequestPermissionsResult()
.
https://youtu.be/C8lUdPVSzDk?t=2m23s
Check whether permission was granted or not in onRequestPermissionsResult()
. If not then check shouldShowRequestPermissionRationale()
.
- If this method returns
true
then show an explanation that why this particular permission is needed. Then depending on user's choice againrequestPermissions()
. - If it returns
false
then show an error message that permission was not granted and app cannot proceed further or a particular feature is disabled.
Below is sample code.
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case STORAGE_PERMISSION_REQUEST:
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted :)
downloadFile();
} else {
// permission was not granted
if (getActivity() == null) {
return;
}
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
showStoragePermissionRationale();
} else {
Snackbar snackbar = Snackbar.make(getView(), getResources().getString(R.string.message_no_storage_permission_snackbar), Snackbar.LENGTH_LONG);
snackbar.setAction(getResources().getString(R.string.settings), new View.OnClickListener() {
@Override
public void onClick(View v) {
if (getActivity() == null) {
return;
}
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getActivity().getPackageName(), null);
intent.setData(uri);
OrderDetailFragment.this.startActivity(intent);
}
});
snackbar.show();
}
}
break;
}
}
Apparently, google maps does exactly this for location permission.
You can check shouldShowRequestPermissionRationale()
in your onRequestPermissionsResult()
.
https://youtu.be/C8lUdPVSzDk?t=2m23s
Check whether permission was granted or not in onRequestPermissionsResult()
. If not then check shouldShowRequestPermissionRationale()
.
- If this method returns
true
then show an explanation that why this particular permission is needed. Then depending on user's choice againrequestPermissions()
. - If it returns
false
then show an error message that permission was not granted and app cannot proceed further or a particular feature is disabled.
Below is sample code.
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case STORAGE_PERMISSION_REQUEST:
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted :)
downloadFile();
} else {
// permission was not granted
if (getActivity() == null) {
return;
}
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
showStoragePermissionRationale();
} else {
Snackbar snackbar = Snackbar.make(getView(), getResources().getString(R.string.message_no_storage_permission_snackbar), Snackbar.LENGTH_LONG);
snackbar.setAction(getResources().getString(R.string.settings), new View.OnClickListener() {
@Override
public void onClick(View v) {
if (getActivity() == null) {
return;
}
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getActivity().getPackageName(), null);
intent.setData(uri);
OrderDetailFragment.this.startActivity(intent);
}
});
snackbar.show();
}
}
break;
}
}
Apparently, google maps does exactly this for location permission.
answered Nov 4 '15 at 5:41
Abhinav ChauhanAbhinav Chauhan
1,2131015
1,2131015
Thank you for the picture and the Youtube link. It matches more or less my own answer. It has to be noted that the question was asked when only the developer preview 1 was available which didn't have the shouldShowRequestPermissionRationale method.
– Emanuel Moecklin
Nov 13 '15 at 17:22
i'm new in android and i want to over ride this onRequestPermissionsResult() method. but I'm getting error that it must implement a super type method. can you tell how to use this
– Andrain
Nov 18 '15 at 8:50
add a comment |
Thank you for the picture and the Youtube link. It matches more or less my own answer. It has to be noted that the question was asked when only the developer preview 1 was available which didn't have the shouldShowRequestPermissionRationale method.
– Emanuel Moecklin
Nov 13 '15 at 17:22
i'm new in android and i want to over ride this onRequestPermissionsResult() method. but I'm getting error that it must implement a super type method. can you tell how to use this
– Andrain
Nov 18 '15 at 8:50
Thank you for the picture and the Youtube link. It matches more or less my own answer. It has to be noted that the question was asked when only the developer preview 1 was available which didn't have the shouldShowRequestPermissionRationale method.
– Emanuel Moecklin
Nov 13 '15 at 17:22
Thank you for the picture and the Youtube link. It matches more or less my own answer. It has to be noted that the question was asked when only the developer preview 1 was available which didn't have the shouldShowRequestPermissionRationale method.
– Emanuel Moecklin
Nov 13 '15 at 17:22
i'm new in android and i want to over ride this onRequestPermissionsResult() method. but I'm getting error that it must implement a super type method. can you tell how to use this
– Andrain
Nov 18 '15 at 8:50
i'm new in android and i want to over ride this onRequestPermissionsResult() method. but I'm getting error that it must implement a super type method. can you tell how to use this
– Andrain
Nov 18 '15 at 8:50
add a comment |
Here is a nice and easy method to check the current permission status:
@Retention(RetentionPolicy.SOURCE)
@IntDef({GRANTED, DENIED, BLOCKED_OR_NEVER_ASKED })
public @interface PermissionStatus {}
public static final int GRANTED = 0;
public static final int DENIED = 1;
public static final int BLOCKED_OR_NEVER_ASKED = 2;
@PermissionStatus
public static int getPermissionStatus(Activity activity, String androidPermissionName) {
if(ContextCompat.checkSelfPermission(activity, androidPermissionName) != PackageManager.PERMISSION_GRANTED) {
if(!ActivityCompat.shouldShowRequestPermissionRationale(activity, androidPermissionName)){
return BLOCKED_OR_NEVER_ASKED;
}
return DENIED;
}
return GRANTED;
}
Caveat: returns BLOCKED_OR_NEVER_ASKED the first app start, before the user accepted/denied the permission through the user prompt (on sdk 23+ devices)
Update:
The Android support library now also seems to have a very similar class android.support.v4.content.PermissionChecker
which contains a checkSelfPermission()
which returns:
public static final int PERMISSION_GRANTED = 0;
public static final int PERMISSION_DENIED = -1;
public static final int PERMISSION_DENIED_APP_OP = -2;
1
For the first launch, I am storing a boolean in shared preferences.
– Saeid Farivar
Jun 27 '16 at 21:42
Which permission will this code grant?
– buzzingsilently
Sep 8 '16 at 10:08
3
This always returnsBLOCKED_OR_NEVER_ASKED
if the permission has not been requested yet.
– Saket
Apr 4 '17 at 11:59
4
yes, that's the reason its called "BLOCKED_OR_NEVER_ASKED", also see the last sentence
– patrickf
Apr 4 '17 at 13:29
2
android.content.pm
already definesPERMISSION_GRANTED = 0
andPERMISSION_DENIED = -1
. Perhaps setBLOCKED_OR_NEVER_ASKED = PERMISSION_DENIED - 1
or something?
– samis
Jul 25 '17 at 16:01
|
show 1 more comment
Here is a nice and easy method to check the current permission status:
@Retention(RetentionPolicy.SOURCE)
@IntDef({GRANTED, DENIED, BLOCKED_OR_NEVER_ASKED })
public @interface PermissionStatus {}
public static final int GRANTED = 0;
public static final int DENIED = 1;
public static final int BLOCKED_OR_NEVER_ASKED = 2;
@PermissionStatus
public static int getPermissionStatus(Activity activity, String androidPermissionName) {
if(ContextCompat.checkSelfPermission(activity, androidPermissionName) != PackageManager.PERMISSION_GRANTED) {
if(!ActivityCompat.shouldShowRequestPermissionRationale(activity, androidPermissionName)){
return BLOCKED_OR_NEVER_ASKED;
}
return DENIED;
}
return GRANTED;
}
Caveat: returns BLOCKED_OR_NEVER_ASKED the first app start, before the user accepted/denied the permission through the user prompt (on sdk 23+ devices)
Update:
The Android support library now also seems to have a very similar class android.support.v4.content.PermissionChecker
which contains a checkSelfPermission()
which returns:
public static final int PERMISSION_GRANTED = 0;
public static final int PERMISSION_DENIED = -1;
public static final int PERMISSION_DENIED_APP_OP = -2;
1
For the first launch, I am storing a boolean in shared preferences.
– Saeid Farivar
Jun 27 '16 at 21:42
Which permission will this code grant?
– buzzingsilently
Sep 8 '16 at 10:08
3
This always returnsBLOCKED_OR_NEVER_ASKED
if the permission has not been requested yet.
– Saket
Apr 4 '17 at 11:59
4
yes, that's the reason its called "BLOCKED_OR_NEVER_ASKED", also see the last sentence
– patrickf
Apr 4 '17 at 13:29
2
android.content.pm
already definesPERMISSION_GRANTED = 0
andPERMISSION_DENIED = -1
. Perhaps setBLOCKED_OR_NEVER_ASKED = PERMISSION_DENIED - 1
or something?
– samis
Jul 25 '17 at 16:01
|
show 1 more comment
Here is a nice and easy method to check the current permission status:
@Retention(RetentionPolicy.SOURCE)
@IntDef({GRANTED, DENIED, BLOCKED_OR_NEVER_ASKED })
public @interface PermissionStatus {}
public static final int GRANTED = 0;
public static final int DENIED = 1;
public static final int BLOCKED_OR_NEVER_ASKED = 2;
@PermissionStatus
public static int getPermissionStatus(Activity activity, String androidPermissionName) {
if(ContextCompat.checkSelfPermission(activity, androidPermissionName) != PackageManager.PERMISSION_GRANTED) {
if(!ActivityCompat.shouldShowRequestPermissionRationale(activity, androidPermissionName)){
return BLOCKED_OR_NEVER_ASKED;
}
return DENIED;
}
return GRANTED;
}
Caveat: returns BLOCKED_OR_NEVER_ASKED the first app start, before the user accepted/denied the permission through the user prompt (on sdk 23+ devices)
Update:
The Android support library now also seems to have a very similar class android.support.v4.content.PermissionChecker
which contains a checkSelfPermission()
which returns:
public static final int PERMISSION_GRANTED = 0;
public static final int PERMISSION_DENIED = -1;
public static final int PERMISSION_DENIED_APP_OP = -2;
Here is a nice and easy method to check the current permission status:
@Retention(RetentionPolicy.SOURCE)
@IntDef({GRANTED, DENIED, BLOCKED_OR_NEVER_ASKED })
public @interface PermissionStatus {}
public static final int GRANTED = 0;
public static final int DENIED = 1;
public static final int BLOCKED_OR_NEVER_ASKED = 2;
@PermissionStatus
public static int getPermissionStatus(Activity activity, String androidPermissionName) {
if(ContextCompat.checkSelfPermission(activity, androidPermissionName) != PackageManager.PERMISSION_GRANTED) {
if(!ActivityCompat.shouldShowRequestPermissionRationale(activity, androidPermissionName)){
return BLOCKED_OR_NEVER_ASKED;
}
return DENIED;
}
return GRANTED;
}
Caveat: returns BLOCKED_OR_NEVER_ASKED the first app start, before the user accepted/denied the permission through the user prompt (on sdk 23+ devices)
Update:
The Android support library now also seems to have a very similar class android.support.v4.content.PermissionChecker
which contains a checkSelfPermission()
which returns:
public static final int PERMISSION_GRANTED = 0;
public static final int PERMISSION_DENIED = -1;
public static final int PERMISSION_DENIED_APP_OP = -2;
edited Aug 2 '17 at 15:07
answered Jan 26 '16 at 11:46
patrickfpatrickf
22.1k66995
22.1k66995
1
For the first launch, I am storing a boolean in shared preferences.
– Saeid Farivar
Jun 27 '16 at 21:42
Which permission will this code grant?
– buzzingsilently
Sep 8 '16 at 10:08
3
This always returnsBLOCKED_OR_NEVER_ASKED
if the permission has not been requested yet.
– Saket
Apr 4 '17 at 11:59
4
yes, that's the reason its called "BLOCKED_OR_NEVER_ASKED", also see the last sentence
– patrickf
Apr 4 '17 at 13:29
2
android.content.pm
already definesPERMISSION_GRANTED = 0
andPERMISSION_DENIED = -1
. Perhaps setBLOCKED_OR_NEVER_ASKED = PERMISSION_DENIED - 1
or something?
– samis
Jul 25 '17 at 16:01
|
show 1 more comment
1
For the first launch, I am storing a boolean in shared preferences.
– Saeid Farivar
Jun 27 '16 at 21:42
Which permission will this code grant?
– buzzingsilently
Sep 8 '16 at 10:08
3
This always returnsBLOCKED_OR_NEVER_ASKED
if the permission has not been requested yet.
– Saket
Apr 4 '17 at 11:59
4
yes, that's the reason its called "BLOCKED_OR_NEVER_ASKED", also see the last sentence
– patrickf
Apr 4 '17 at 13:29
2
android.content.pm
already definesPERMISSION_GRANTED = 0
andPERMISSION_DENIED = -1
. Perhaps setBLOCKED_OR_NEVER_ASKED = PERMISSION_DENIED - 1
or something?
– samis
Jul 25 '17 at 16:01
1
1
For the first launch, I am storing a boolean in shared preferences.
– Saeid Farivar
Jun 27 '16 at 21:42
For the first launch, I am storing a boolean in shared preferences.
– Saeid Farivar
Jun 27 '16 at 21:42
Which permission will this code grant?
– buzzingsilently
Sep 8 '16 at 10:08
Which permission will this code grant?
– buzzingsilently
Sep 8 '16 at 10:08
3
3
This always returns
BLOCKED_OR_NEVER_ASKED
if the permission has not been requested yet.– Saket
Apr 4 '17 at 11:59
This always returns
BLOCKED_OR_NEVER_ASKED
if the permission has not been requested yet.– Saket
Apr 4 '17 at 11:59
4
4
yes, that's the reason its called "BLOCKED_OR_NEVER_ASKED", also see the last sentence
– patrickf
Apr 4 '17 at 13:29
yes, that's the reason its called "BLOCKED_OR_NEVER_ASKED", also see the last sentence
– patrickf
Apr 4 '17 at 13:29
2
2
android.content.pm
already defines PERMISSION_GRANTED = 0
and PERMISSION_DENIED = -1
. Perhaps set BLOCKED_OR_NEVER_ASKED = PERMISSION_DENIED - 1
or something?– samis
Jul 25 '17 at 16:01
android.content.pm
already defines PERMISSION_GRANTED = 0
and PERMISSION_DENIED = -1
. Perhaps set BLOCKED_OR_NEVER_ASKED = PERMISSION_DENIED - 1
or something?– samis
Jul 25 '17 at 16:01
|
show 1 more comment
May be useful for someone:--
What I have noticed is, if we check the shouldShowRequestPermissionRationale() flag in to onRequestPermissionsResult() callback method, it shows only two states.
State 1:-Return true:-- Any time user clicks Deny permissions (including the very first time).
State 2:-Returns false :- if user selects “never asks again".
Link of detailed working example
2
This is the correct way to detect if user has selected never ask again option.
– Muhammad Babar
May 24 '17 at 10:31
Ah, the key here is that you handle this in theonRequestPermissionsResult
, not when actually requesting the permission.
– Joshua Pinter
May 12 '18 at 15:27
add a comment |
May be useful for someone:--
What I have noticed is, if we check the shouldShowRequestPermissionRationale() flag in to onRequestPermissionsResult() callback method, it shows only two states.
State 1:-Return true:-- Any time user clicks Deny permissions (including the very first time).
State 2:-Returns false :- if user selects “never asks again".
Link of detailed working example
2
This is the correct way to detect if user has selected never ask again option.
– Muhammad Babar
May 24 '17 at 10:31
Ah, the key here is that you handle this in theonRequestPermissionsResult
, not when actually requesting the permission.
– Joshua Pinter
May 12 '18 at 15:27
add a comment |
May be useful for someone:--
What I have noticed is, if we check the shouldShowRequestPermissionRationale() flag in to onRequestPermissionsResult() callback method, it shows only two states.
State 1:-Return true:-- Any time user clicks Deny permissions (including the very first time).
State 2:-Returns false :- if user selects “never asks again".
Link of detailed working example
May be useful for someone:--
What I have noticed is, if we check the shouldShowRequestPermissionRationale() flag in to onRequestPermissionsResult() callback method, it shows only two states.
State 1:-Return true:-- Any time user clicks Deny permissions (including the very first time).
State 2:-Returns false :- if user selects “never asks again".
Link of detailed working example
edited May 23 '17 at 12:18
Community♦
11
11
answered Feb 19 '16 at 1:47
NicksNicks
10.9k44759
10.9k44759
2
This is the correct way to detect if user has selected never ask again option.
– Muhammad Babar
May 24 '17 at 10:31
Ah, the key here is that you handle this in theonRequestPermissionsResult
, not when actually requesting the permission.
– Joshua Pinter
May 12 '18 at 15:27
add a comment |
2
This is the correct way to detect if user has selected never ask again option.
– Muhammad Babar
May 24 '17 at 10:31
Ah, the key here is that you handle this in theonRequestPermissionsResult
, not when actually requesting the permission.
– Joshua Pinter
May 12 '18 at 15:27
2
2
This is the correct way to detect if user has selected never ask again option.
– Muhammad Babar
May 24 '17 at 10:31
This is the correct way to detect if user has selected never ask again option.
– Muhammad Babar
May 24 '17 at 10:31
Ah, the key here is that you handle this in the
onRequestPermissionsResult
, not when actually requesting the permission.– Joshua Pinter
May 12 '18 at 15:27
Ah, the key here is that you handle this in the
onRequestPermissionsResult
, not when actually requesting the permission.– Joshua Pinter
May 12 '18 at 15:27
add a comment |
You can determine it by checking if permission rationale is to be shown inside the onRequestPermissionsResult()
callback method. And if you find any permission set to never ask again, you can request users to grant permissions from the settings.
My full implementation would be like below. It works for both single or multiple permissions requests. Use the following or directly use my library.
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) {
if(permissions.length == 0){
return;
}
boolean allPermissionsGranted = true;
if(grantResults.length>0){
for(int grantResult: grantResults){
if(grantResult != PackageManager.PERMISSION_GRANTED){
allPermissionsGranted = false;
break;
}
}
}
if(!allPermissionsGranted){
boolean somePermissionsForeverDenied = false;
for(String permission: permissions){
if(ActivityCompat.shouldShowRequestPermissionRationale(this, permission)){
//denied
Log.e("denied", permission);
}else{
if(ActivityCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED){
//allowed
Log.e("allowed", permission);
} else{
//set to never ask again
Log.e("set to never ask again", permission);
somePermissionsForeverDenied = true;
}
}
}
if(somePermissionsForeverDenied){
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle("Permissions Required")
.setMessage("You have forcefully denied some of the required permissions " +
"for this action. Please open settings, go to permissions and allow them.")
.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", getPackageName(), null));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
})
.setCancelable(false)
.create()
.show();
}
} else {
switch (requestCode) {
//act according to the request code used while requesting the permission(s).
}
}
}
hii @nabin my requirement is when i click on download button(which download pdf file) that time have to check write permission is allow or denied so how to use this code! can you guide me plz
– Rucha Bhatt Joshi
Jun 16 '17 at 6:38
hello @RuchaBhatt Have a look at my library. github.com/nabinbhandari/Android-Permissions
– Nabin Bhandari
Jun 20 '17 at 17:12
add a comment |
You can determine it by checking if permission rationale is to be shown inside the onRequestPermissionsResult()
callback method. And if you find any permission set to never ask again, you can request users to grant permissions from the settings.
My full implementation would be like below. It works for both single or multiple permissions requests. Use the following or directly use my library.
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) {
if(permissions.length == 0){
return;
}
boolean allPermissionsGranted = true;
if(grantResults.length>0){
for(int grantResult: grantResults){
if(grantResult != PackageManager.PERMISSION_GRANTED){
allPermissionsGranted = false;
break;
}
}
}
if(!allPermissionsGranted){
boolean somePermissionsForeverDenied = false;
for(String permission: permissions){
if(ActivityCompat.shouldShowRequestPermissionRationale(this, permission)){
//denied
Log.e("denied", permission);
}else{
if(ActivityCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED){
//allowed
Log.e("allowed", permission);
} else{
//set to never ask again
Log.e("set to never ask again", permission);
somePermissionsForeverDenied = true;
}
}
}
if(somePermissionsForeverDenied){
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle("Permissions Required")
.setMessage("You have forcefully denied some of the required permissions " +
"for this action. Please open settings, go to permissions and allow them.")
.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", getPackageName(), null));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
})
.setCancelable(false)
.create()
.show();
}
} else {
switch (requestCode) {
//act according to the request code used while requesting the permission(s).
}
}
}
hii @nabin my requirement is when i click on download button(which download pdf file) that time have to check write permission is allow or denied so how to use this code! can you guide me plz
– Rucha Bhatt Joshi
Jun 16 '17 at 6:38
hello @RuchaBhatt Have a look at my library. github.com/nabinbhandari/Android-Permissions
– Nabin Bhandari
Jun 20 '17 at 17:12
add a comment |
You can determine it by checking if permission rationale is to be shown inside the onRequestPermissionsResult()
callback method. And if you find any permission set to never ask again, you can request users to grant permissions from the settings.
My full implementation would be like below. It works for both single or multiple permissions requests. Use the following or directly use my library.
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) {
if(permissions.length == 0){
return;
}
boolean allPermissionsGranted = true;
if(grantResults.length>0){
for(int grantResult: grantResults){
if(grantResult != PackageManager.PERMISSION_GRANTED){
allPermissionsGranted = false;
break;
}
}
}
if(!allPermissionsGranted){
boolean somePermissionsForeverDenied = false;
for(String permission: permissions){
if(ActivityCompat.shouldShowRequestPermissionRationale(this, permission)){
//denied
Log.e("denied", permission);
}else{
if(ActivityCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED){
//allowed
Log.e("allowed", permission);
} else{
//set to never ask again
Log.e("set to never ask again", permission);
somePermissionsForeverDenied = true;
}
}
}
if(somePermissionsForeverDenied){
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle("Permissions Required")
.setMessage("You have forcefully denied some of the required permissions " +
"for this action. Please open settings, go to permissions and allow them.")
.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", getPackageName(), null));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
})
.setCancelable(false)
.create()
.show();
}
} else {
switch (requestCode) {
//act according to the request code used while requesting the permission(s).
}
}
}
You can determine it by checking if permission rationale is to be shown inside the onRequestPermissionsResult()
callback method. And if you find any permission set to never ask again, you can request users to grant permissions from the settings.
My full implementation would be like below. It works for both single or multiple permissions requests. Use the following or directly use my library.
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) {
if(permissions.length == 0){
return;
}
boolean allPermissionsGranted = true;
if(grantResults.length>0){
for(int grantResult: grantResults){
if(grantResult != PackageManager.PERMISSION_GRANTED){
allPermissionsGranted = false;
break;
}
}
}
if(!allPermissionsGranted){
boolean somePermissionsForeverDenied = false;
for(String permission: permissions){
if(ActivityCompat.shouldShowRequestPermissionRationale(this, permission)){
//denied
Log.e("denied", permission);
}else{
if(ActivityCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED){
//allowed
Log.e("allowed", permission);
} else{
//set to never ask again
Log.e("set to never ask again", permission);
somePermissionsForeverDenied = true;
}
}
}
if(somePermissionsForeverDenied){
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle("Permissions Required")
.setMessage("You have forcefully denied some of the required permissions " +
"for this action. Please open settings, go to permissions and allow them.")
.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", getPackageName(), null));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
})
.setCancelable(false)
.create()
.show();
}
} else {
switch (requestCode) {
//act according to the request code used while requesting the permission(s).
}
}
}
edited Oct 12 '17 at 12:22
answered Dec 22 '16 at 17:02
Nabin BhandariNabin Bhandari
9,36531736
9,36531736
hii @nabin my requirement is when i click on download button(which download pdf file) that time have to check write permission is allow or denied so how to use this code! can you guide me plz
– Rucha Bhatt Joshi
Jun 16 '17 at 6:38
hello @RuchaBhatt Have a look at my library. github.com/nabinbhandari/Android-Permissions
– Nabin Bhandari
Jun 20 '17 at 17:12
add a comment |
hii @nabin my requirement is when i click on download button(which download pdf file) that time have to check write permission is allow or denied so how to use this code! can you guide me plz
– Rucha Bhatt Joshi
Jun 16 '17 at 6:38
hello @RuchaBhatt Have a look at my library. github.com/nabinbhandari/Android-Permissions
– Nabin Bhandari
Jun 20 '17 at 17:12
hii @nabin my requirement is when i click on download button(which download pdf file) that time have to check write permission is allow or denied so how to use this code! can you guide me plz
– Rucha Bhatt Joshi
Jun 16 '17 at 6:38
hii @nabin my requirement is when i click on download button(which download pdf file) that time have to check write permission is allow or denied so how to use this code! can you guide me plz
– Rucha Bhatt Joshi
Jun 16 '17 at 6:38
hello @RuchaBhatt Have a look at my library. github.com/nabinbhandari/Android-Permissions
– Nabin Bhandari
Jun 20 '17 at 17:12
hello @RuchaBhatt Have a look at my library. github.com/nabinbhandari/Android-Permissions
– Nabin Bhandari
Jun 20 '17 at 17:12
add a comment |
Once the user has marked "Do not ask again," the question can not be displayed again.
But it can be explained to the user that he has previously denied the permission and must grant permission in the settings. And reference him to the settings, with the following code:
@Override
public void onRequestPermissionsResult(int permsRequestCode, String permissions, int grantResults) {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// now, you have permission go ahead
// TODO: something
} else {
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
Manifest.permission.READ_CALL_LOG)) {
// now, user has denied permission (but not permanently!)
} else {
// now, user has denied permission permanently!
Snackbar snackbar = Snackbar.make(findViewById(android.R.id.content), "You have previously declined this permission.n" +
"You must approve this permission in "Permissions" in the app settings on your device.", Snackbar.LENGTH_LONG).setAction("Settings", new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + BuildConfig.APPLICATION_ID)));
}
});
View snackbarView = snackbar.getView();
TextView textView = (TextView) snackbarView.findViewById(android.support.design.R.id.snackbar_text);
textView.setMaxLines(5); //Or as much as you need
snackbar.show();
}
}
return;
}
Perfect answer, thanks, +1!
– Antonio Vlasic
Sep 18 '18 at 8:44
add a comment |
Once the user has marked "Do not ask again," the question can not be displayed again.
But it can be explained to the user that he has previously denied the permission and must grant permission in the settings. And reference him to the settings, with the following code:
@Override
public void onRequestPermissionsResult(int permsRequestCode, String permissions, int grantResults) {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// now, you have permission go ahead
// TODO: something
} else {
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
Manifest.permission.READ_CALL_LOG)) {
// now, user has denied permission (but not permanently!)
} else {
// now, user has denied permission permanently!
Snackbar snackbar = Snackbar.make(findViewById(android.R.id.content), "You have previously declined this permission.n" +
"You must approve this permission in "Permissions" in the app settings on your device.", Snackbar.LENGTH_LONG).setAction("Settings", new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + BuildConfig.APPLICATION_ID)));
}
});
View snackbarView = snackbar.getView();
TextView textView = (TextView) snackbarView.findViewById(android.support.design.R.id.snackbar_text);
textView.setMaxLines(5); //Or as much as you need
snackbar.show();
}
}
return;
}
Perfect answer, thanks, +1!
– Antonio Vlasic
Sep 18 '18 at 8:44
add a comment |
Once the user has marked "Do not ask again," the question can not be displayed again.
But it can be explained to the user that he has previously denied the permission and must grant permission in the settings. And reference him to the settings, with the following code:
@Override
public void onRequestPermissionsResult(int permsRequestCode, String permissions, int grantResults) {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// now, you have permission go ahead
// TODO: something
} else {
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
Manifest.permission.READ_CALL_LOG)) {
// now, user has denied permission (but not permanently!)
} else {
// now, user has denied permission permanently!
Snackbar snackbar = Snackbar.make(findViewById(android.R.id.content), "You have previously declined this permission.n" +
"You must approve this permission in "Permissions" in the app settings on your device.", Snackbar.LENGTH_LONG).setAction("Settings", new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + BuildConfig.APPLICATION_ID)));
}
});
View snackbarView = snackbar.getView();
TextView textView = (TextView) snackbarView.findViewById(android.support.design.R.id.snackbar_text);
textView.setMaxLines(5); //Or as much as you need
snackbar.show();
}
}
return;
}
Once the user has marked "Do not ask again," the question can not be displayed again.
But it can be explained to the user that he has previously denied the permission and must grant permission in the settings. And reference him to the settings, with the following code:
@Override
public void onRequestPermissionsResult(int permsRequestCode, String permissions, int grantResults) {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// now, you have permission go ahead
// TODO: something
} else {
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
Manifest.permission.READ_CALL_LOG)) {
// now, user has denied permission (but not permanently!)
} else {
// now, user has denied permission permanently!
Snackbar snackbar = Snackbar.make(findViewById(android.R.id.content), "You have previously declined this permission.n" +
"You must approve this permission in "Permissions" in the app settings on your device.", Snackbar.LENGTH_LONG).setAction("Settings", new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + BuildConfig.APPLICATION_ID)));
}
});
View snackbarView = snackbar.getView();
TextView textView = (TextView) snackbarView.findViewById(android.support.design.R.id.snackbar_text);
textView.setMaxLines(5); //Or as much as you need
snackbar.show();
}
}
return;
}
edited Jul 25 '18 at 9:54
answered Jul 25 '18 at 8:53
רותם ריכטררותם ריכטר
13914
13914
Perfect answer, thanks, +1!
– Antonio Vlasic
Sep 18 '18 at 8:44
add a comment |
Perfect answer, thanks, +1!
– Antonio Vlasic
Sep 18 '18 at 8:44
Perfect answer, thanks, +1!
– Antonio Vlasic
Sep 18 '18 at 8:44
Perfect answer, thanks, +1!
– Antonio Vlasic
Sep 18 '18 at 8:44
add a comment |
If you want to detect all the "states" (first time denied, just been denied, just been denied with "Never Ask Again" or permanently denied) you can do the following:
Create 2 booleans
private boolean beforeClickPermissionRat;
private boolean afterClickPermissionRat;
Set the first one before asking for permission:
beforeClickPermissionRat = shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE);
Set the second one inside your onRequestPermissionsResult method:
afterClickPermissionRat = shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE);
Use the following "table" to do whatever you need in onRequestPermissionsResult() (after checking that you still don't have the permission):
// before after
// FALSE FALSE = Was denied permanently, still denied permanently --> App Settings
// FALSE TRUE = First time deny, not denied permanently yet --> Nothing
// TRUE FALSE = Just been permanently denied --> Changing my caption to "Go to app settings to edit permissions"
// TRUE TRUE = Wasn't denied permanently, still not denied permanently --> Nothing
There's no point in checking the shouldShowRequestPermissionRationale before calling requestPermissions unless you want to show the rationale before requesting the permission. Showing the rationale only after the user denied the permission seems to be how most apps handle it nowadays though.
– Emanuel Moecklin
Dec 23 '16 at 21:59
2
@EmanuelMoecklin, as far as I know it's the only way to check if it's already been denied (by checking it before and after, as explained in my truth table) or if it's a first time deny (in my case I redirect the user to the app settings if it's permanently denied)
– mVck
Jan 30 '17 at 18:03
// TRUE FALSE
also occurs when user allows a permission after previously denying it.
– samis
Jul 25 '17 at 17:48
add a comment |
If you want to detect all the "states" (first time denied, just been denied, just been denied with "Never Ask Again" or permanently denied) you can do the following:
Create 2 booleans
private boolean beforeClickPermissionRat;
private boolean afterClickPermissionRat;
Set the first one before asking for permission:
beforeClickPermissionRat = shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE);
Set the second one inside your onRequestPermissionsResult method:
afterClickPermissionRat = shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE);
Use the following "table" to do whatever you need in onRequestPermissionsResult() (after checking that you still don't have the permission):
// before after
// FALSE FALSE = Was denied permanently, still denied permanently --> App Settings
// FALSE TRUE = First time deny, not denied permanently yet --> Nothing
// TRUE FALSE = Just been permanently denied --> Changing my caption to "Go to app settings to edit permissions"
// TRUE TRUE = Wasn't denied permanently, still not denied permanently --> Nothing
There's no point in checking the shouldShowRequestPermissionRationale before calling requestPermissions unless you want to show the rationale before requesting the permission. Showing the rationale only after the user denied the permission seems to be how most apps handle it nowadays though.
– Emanuel Moecklin
Dec 23 '16 at 21:59
2
@EmanuelMoecklin, as far as I know it's the only way to check if it's already been denied (by checking it before and after, as explained in my truth table) or if it's a first time deny (in my case I redirect the user to the app settings if it's permanently denied)
– mVck
Jan 30 '17 at 18:03
// TRUE FALSE
also occurs when user allows a permission after previously denying it.
– samis
Jul 25 '17 at 17:48
add a comment |
If you want to detect all the "states" (first time denied, just been denied, just been denied with "Never Ask Again" or permanently denied) you can do the following:
Create 2 booleans
private boolean beforeClickPermissionRat;
private boolean afterClickPermissionRat;
Set the first one before asking for permission:
beforeClickPermissionRat = shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE);
Set the second one inside your onRequestPermissionsResult method:
afterClickPermissionRat = shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE);
Use the following "table" to do whatever you need in onRequestPermissionsResult() (after checking that you still don't have the permission):
// before after
// FALSE FALSE = Was denied permanently, still denied permanently --> App Settings
// FALSE TRUE = First time deny, not denied permanently yet --> Nothing
// TRUE FALSE = Just been permanently denied --> Changing my caption to "Go to app settings to edit permissions"
// TRUE TRUE = Wasn't denied permanently, still not denied permanently --> Nothing
If you want to detect all the "states" (first time denied, just been denied, just been denied with "Never Ask Again" or permanently denied) you can do the following:
Create 2 booleans
private boolean beforeClickPermissionRat;
private boolean afterClickPermissionRat;
Set the first one before asking for permission:
beforeClickPermissionRat = shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE);
Set the second one inside your onRequestPermissionsResult method:
afterClickPermissionRat = shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE);
Use the following "table" to do whatever you need in onRequestPermissionsResult() (after checking that you still don't have the permission):
// before after
// FALSE FALSE = Was denied permanently, still denied permanently --> App Settings
// FALSE TRUE = First time deny, not denied permanently yet --> Nothing
// TRUE FALSE = Just been permanently denied --> Changing my caption to "Go to app settings to edit permissions"
// TRUE TRUE = Wasn't denied permanently, still not denied permanently --> Nothing
edited Dec 23 '16 at 16:34
answered Dec 23 '16 at 16:18
mVckmVck
1,6711017
1,6711017
There's no point in checking the shouldShowRequestPermissionRationale before calling requestPermissions unless you want to show the rationale before requesting the permission. Showing the rationale only after the user denied the permission seems to be how most apps handle it nowadays though.
– Emanuel Moecklin
Dec 23 '16 at 21:59
2
@EmanuelMoecklin, as far as I know it's the only way to check if it's already been denied (by checking it before and after, as explained in my truth table) or if it's a first time deny (in my case I redirect the user to the app settings if it's permanently denied)
– mVck
Jan 30 '17 at 18:03
// TRUE FALSE
also occurs when user allows a permission after previously denying it.
– samis
Jul 25 '17 at 17:48
add a comment |
There's no point in checking the shouldShowRequestPermissionRationale before calling requestPermissions unless you want to show the rationale before requesting the permission. Showing the rationale only after the user denied the permission seems to be how most apps handle it nowadays though.
– Emanuel Moecklin
Dec 23 '16 at 21:59
2
@EmanuelMoecklin, as far as I know it's the only way to check if it's already been denied (by checking it before and after, as explained in my truth table) or if it's a first time deny (in my case I redirect the user to the app settings if it's permanently denied)
– mVck
Jan 30 '17 at 18:03
// TRUE FALSE
also occurs when user allows a permission after previously denying it.
– samis
Jul 25 '17 at 17:48
There's no point in checking the shouldShowRequestPermissionRationale before calling requestPermissions unless you want to show the rationale before requesting the permission. Showing the rationale only after the user denied the permission seems to be how most apps handle it nowadays though.
– Emanuel Moecklin
Dec 23 '16 at 21:59
There's no point in checking the shouldShowRequestPermissionRationale before calling requestPermissions unless you want to show the rationale before requesting the permission. Showing the rationale only after the user denied the permission seems to be how most apps handle it nowadays though.
– Emanuel Moecklin
Dec 23 '16 at 21:59
2
2
@EmanuelMoecklin, as far as I know it's the only way to check if it's already been denied (by checking it before and after, as explained in my truth table) or if it's a first time deny (in my case I redirect the user to the app settings if it's permanently denied)
– mVck
Jan 30 '17 at 18:03
@EmanuelMoecklin, as far as I know it's the only way to check if it's already been denied (by checking it before and after, as explained in my truth table) or if it's a first time deny (in my case I redirect the user to the app settings if it's permanently denied)
– mVck
Jan 30 '17 at 18:03
// TRUE FALSE
also occurs when user allows a permission after previously denying it.– samis
Jul 25 '17 at 17:48
// TRUE FALSE
also occurs when user allows a permission after previously denying it.– samis
Jul 25 '17 at 17:48
add a comment |
I had the same problem and I figured it out. To make life much simpler, I wrote an util class to handle runtime permissions.
public class PermissionUtil {
/*
* Check if version is marshmallow and above.
* Used in deciding to ask runtime permission
* */
public static boolean shouldAskPermission() {
return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M);
}
private static boolean shouldAskPermission(Context context, String permission){
if (shouldAskPermission()) {
int permissionResult = ActivityCompat.checkSelfPermission(context, permission);
if (permissionResult != PackageManager.PERMISSION_GRANTED) {
return true;
}
}
return false;
}
public static void checkPermission(Context context, String permission, PermissionAskListener listener){
/*
* If permission is not granted
* */
if (shouldAskPermission(context, permission)){
/*
* If permission denied previously
* */
if (((Activity)context).shouldShowRequestPermissionRationale(permission)) {
listener.onPermissionPreviouslyDenied();
} else {
/*
* Permission denied or first time requested
* */
if (PreferencesUtil.isFirstTimeAskingPermission(context, permission)) {
PreferencesUtil.firstTimeAskingPermission(context, permission, false);
listener.onPermissionAsk();
} else {
/*
* Handle the feature without permission or ask user to manually allow permission
* */
listener.onPermissionDisabled();
}
}
} else {
listener.onPermissionGranted();
}
}
/*
* Callback on various cases on checking permission
*
* 1. Below M, runtime permission not needed. In that case onPermissionGranted() would be called.
* If permission is already granted, onPermissionGranted() would be called.
*
* 2. Above M, if the permission is being asked first time onPermissionAsk() would be called.
*
* 3. Above M, if the permission is previously asked but not granted, onPermissionPreviouslyDenied()
* would be called.
*
* 4. Above M, if the permission is disabled by device policy or the user checked "Never ask again"
* check box on previous request permission, onPermissionDisabled() would be called.
* */
public interface PermissionAskListener {
/*
* Callback to ask permission
* */
void onPermissionAsk();
/*
* Callback on permission denied
* */
void onPermissionPreviouslyDenied();
/*
* Callback on permission "Never show again" checked and denied
* */
void onPermissionDisabled();
/*
* Callback on permission granted
* */
void onPermissionGranted();
}
}
And the PreferenceUtil methods are as follows.
public static void firstTimeAskingPermission(Context context, String permission, boolean isFirstTime){
SharedPreferences sharedPreference = context.getSharedPreferences(PREFS_FILE_NAME, MODE_PRIVATE;
sharedPreference.edit().putBoolean(permission, isFirstTime).apply();
}
public static boolean isFirstTimeAskingPermission(Context context, String permission){
return context.getSharedPreferences(PREFS_FILE_NAME, MODE_PRIVATE).getBoolean(permission, true);
}
Now, all you need is to use the method * checkPermission* with proper arguments.
Here is an example,
PermissionUtil.checkPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE,
new PermissionUtil.PermissionAskListener() {
@Override
public void onPermissionAsk() {
ActivityCompat.requestPermissions(
thisActivity,
new String{Manifest.permission.READ_CONTACTS},
REQUEST_EXTERNAL_STORAGE
);
}
@Override
public void onPermissionPreviouslyDenied() {
//show a dialog explaining permission and then request permission
}
@Override
public void onPermissionDisabled() {
Toast.makeText(context, "Permission Disabled.", Toast.LENGTH_SHORT).show();
}
@Override
public void onPermissionGranted() {
readContacts();
}
});
how does my app know whether the user has checked the "Never ask again"?
If user checked Never ask again, you'll get callback on onPermissionDisabled.
Happy coding :)
shouldShowRequestPermissionRationale i got error here, can you plz help me.
– Rucha Bhatt Joshi
Jun 16 '17 at 7:17
@RuchaBhatt What error you got?
– muthuraj
Jun 16 '17 at 7:36
i cant find this method shouldShowRequestPermissionRationale may be i failed to get context.. but it's fine i found other alternate solution.. Thank you for help :)
– Rucha Bhatt Joshi
Jun 16 '17 at 8:50
1
My bad. shouldShowRequestPermissionRationale is available through Activity, not context. I updated my answer by casting the context to Activity before calling that method. Check it out :)
– muthuraj
Jun 16 '17 at 13:52
add a comment |
I had the same problem and I figured it out. To make life much simpler, I wrote an util class to handle runtime permissions.
public class PermissionUtil {
/*
* Check if version is marshmallow and above.
* Used in deciding to ask runtime permission
* */
public static boolean shouldAskPermission() {
return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M);
}
private static boolean shouldAskPermission(Context context, String permission){
if (shouldAskPermission()) {
int permissionResult = ActivityCompat.checkSelfPermission(context, permission);
if (permissionResult != PackageManager.PERMISSION_GRANTED) {
return true;
}
}
return false;
}
public static void checkPermission(Context context, String permission, PermissionAskListener listener){
/*
* If permission is not granted
* */
if (shouldAskPermission(context, permission)){
/*
* If permission denied previously
* */
if (((Activity)context).shouldShowRequestPermissionRationale(permission)) {
listener.onPermissionPreviouslyDenied();
} else {
/*
* Permission denied or first time requested
* */
if (PreferencesUtil.isFirstTimeAskingPermission(context, permission)) {
PreferencesUtil.firstTimeAskingPermission(context, permission, false);
listener.onPermissionAsk();
} else {
/*
* Handle the feature without permission or ask user to manually allow permission
* */
listener.onPermissionDisabled();
}
}
} else {
listener.onPermissionGranted();
}
}
/*
* Callback on various cases on checking permission
*
* 1. Below M, runtime permission not needed. In that case onPermissionGranted() would be called.
* If permission is already granted, onPermissionGranted() would be called.
*
* 2. Above M, if the permission is being asked first time onPermissionAsk() would be called.
*
* 3. Above M, if the permission is previously asked but not granted, onPermissionPreviouslyDenied()
* would be called.
*
* 4. Above M, if the permission is disabled by device policy or the user checked "Never ask again"
* check box on previous request permission, onPermissionDisabled() would be called.
* */
public interface PermissionAskListener {
/*
* Callback to ask permission
* */
void onPermissionAsk();
/*
* Callback on permission denied
* */
void onPermissionPreviouslyDenied();
/*
* Callback on permission "Never show again" checked and denied
* */
void onPermissionDisabled();
/*
* Callback on permission granted
* */
void onPermissionGranted();
}
}
And the PreferenceUtil methods are as follows.
public static void firstTimeAskingPermission(Context context, String permission, boolean isFirstTime){
SharedPreferences sharedPreference = context.getSharedPreferences(PREFS_FILE_NAME, MODE_PRIVATE;
sharedPreference.edit().putBoolean(permission, isFirstTime).apply();
}
public static boolean isFirstTimeAskingPermission(Context context, String permission){
return context.getSharedPreferences(PREFS_FILE_NAME, MODE_PRIVATE).getBoolean(permission, true);
}
Now, all you need is to use the method * checkPermission* with proper arguments.
Here is an example,
PermissionUtil.checkPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE,
new PermissionUtil.PermissionAskListener() {
@Override
public void onPermissionAsk() {
ActivityCompat.requestPermissions(
thisActivity,
new String{Manifest.permission.READ_CONTACTS},
REQUEST_EXTERNAL_STORAGE
);
}
@Override
public void onPermissionPreviouslyDenied() {
//show a dialog explaining permission and then request permission
}
@Override
public void onPermissionDisabled() {
Toast.makeText(context, "Permission Disabled.", Toast.LENGTH_SHORT).show();
}
@Override
public void onPermissionGranted() {
readContacts();
}
});
how does my app know whether the user has checked the "Never ask again"?
If user checked Never ask again, you'll get callback on onPermissionDisabled.
Happy coding :)
shouldShowRequestPermissionRationale i got error here, can you plz help me.
– Rucha Bhatt Joshi
Jun 16 '17 at 7:17
@RuchaBhatt What error you got?
– muthuraj
Jun 16 '17 at 7:36
i cant find this method shouldShowRequestPermissionRationale may be i failed to get context.. but it's fine i found other alternate solution.. Thank you for help :)
– Rucha Bhatt Joshi
Jun 16 '17 at 8:50
1
My bad. shouldShowRequestPermissionRationale is available through Activity, not context. I updated my answer by casting the context to Activity before calling that method. Check it out :)
– muthuraj
Jun 16 '17 at 13:52
add a comment |
I had the same problem and I figured it out. To make life much simpler, I wrote an util class to handle runtime permissions.
public class PermissionUtil {
/*
* Check if version is marshmallow and above.
* Used in deciding to ask runtime permission
* */
public static boolean shouldAskPermission() {
return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M);
}
private static boolean shouldAskPermission(Context context, String permission){
if (shouldAskPermission()) {
int permissionResult = ActivityCompat.checkSelfPermission(context, permission);
if (permissionResult != PackageManager.PERMISSION_GRANTED) {
return true;
}
}
return false;
}
public static void checkPermission(Context context, String permission, PermissionAskListener listener){
/*
* If permission is not granted
* */
if (shouldAskPermission(context, permission)){
/*
* If permission denied previously
* */
if (((Activity)context).shouldShowRequestPermissionRationale(permission)) {
listener.onPermissionPreviouslyDenied();
} else {
/*
* Permission denied or first time requested
* */
if (PreferencesUtil.isFirstTimeAskingPermission(context, permission)) {
PreferencesUtil.firstTimeAskingPermission(context, permission, false);
listener.onPermissionAsk();
} else {
/*
* Handle the feature without permission or ask user to manually allow permission
* */
listener.onPermissionDisabled();
}
}
} else {
listener.onPermissionGranted();
}
}
/*
* Callback on various cases on checking permission
*
* 1. Below M, runtime permission not needed. In that case onPermissionGranted() would be called.
* If permission is already granted, onPermissionGranted() would be called.
*
* 2. Above M, if the permission is being asked first time onPermissionAsk() would be called.
*
* 3. Above M, if the permission is previously asked but not granted, onPermissionPreviouslyDenied()
* would be called.
*
* 4. Above M, if the permission is disabled by device policy or the user checked "Never ask again"
* check box on previous request permission, onPermissionDisabled() would be called.
* */
public interface PermissionAskListener {
/*
* Callback to ask permission
* */
void onPermissionAsk();
/*
* Callback on permission denied
* */
void onPermissionPreviouslyDenied();
/*
* Callback on permission "Never show again" checked and denied
* */
void onPermissionDisabled();
/*
* Callback on permission granted
* */
void onPermissionGranted();
}
}
And the PreferenceUtil methods are as follows.
public static void firstTimeAskingPermission(Context context, String permission, boolean isFirstTime){
SharedPreferences sharedPreference = context.getSharedPreferences(PREFS_FILE_NAME, MODE_PRIVATE;
sharedPreference.edit().putBoolean(permission, isFirstTime).apply();
}
public static boolean isFirstTimeAskingPermission(Context context, String permission){
return context.getSharedPreferences(PREFS_FILE_NAME, MODE_PRIVATE).getBoolean(permission, true);
}
Now, all you need is to use the method * checkPermission* with proper arguments.
Here is an example,
PermissionUtil.checkPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE,
new PermissionUtil.PermissionAskListener() {
@Override
public void onPermissionAsk() {
ActivityCompat.requestPermissions(
thisActivity,
new String{Manifest.permission.READ_CONTACTS},
REQUEST_EXTERNAL_STORAGE
);
}
@Override
public void onPermissionPreviouslyDenied() {
//show a dialog explaining permission and then request permission
}
@Override
public void onPermissionDisabled() {
Toast.makeText(context, "Permission Disabled.", Toast.LENGTH_SHORT).show();
}
@Override
public void onPermissionGranted() {
readContacts();
}
});
how does my app know whether the user has checked the "Never ask again"?
If user checked Never ask again, you'll get callback on onPermissionDisabled.
Happy coding :)
I had the same problem and I figured it out. To make life much simpler, I wrote an util class to handle runtime permissions.
public class PermissionUtil {
/*
* Check if version is marshmallow and above.
* Used in deciding to ask runtime permission
* */
public static boolean shouldAskPermission() {
return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M);
}
private static boolean shouldAskPermission(Context context, String permission){
if (shouldAskPermission()) {
int permissionResult = ActivityCompat.checkSelfPermission(context, permission);
if (permissionResult != PackageManager.PERMISSION_GRANTED) {
return true;
}
}
return false;
}
public static void checkPermission(Context context, String permission, PermissionAskListener listener){
/*
* If permission is not granted
* */
if (shouldAskPermission(context, permission)){
/*
* If permission denied previously
* */
if (((Activity)context).shouldShowRequestPermissionRationale(permission)) {
listener.onPermissionPreviouslyDenied();
} else {
/*
* Permission denied or first time requested
* */
if (PreferencesUtil.isFirstTimeAskingPermission(context, permission)) {
PreferencesUtil.firstTimeAskingPermission(context, permission, false);
listener.onPermissionAsk();
} else {
/*
* Handle the feature without permission or ask user to manually allow permission
* */
listener.onPermissionDisabled();
}
}
} else {
listener.onPermissionGranted();
}
}
/*
* Callback on various cases on checking permission
*
* 1. Below M, runtime permission not needed. In that case onPermissionGranted() would be called.
* If permission is already granted, onPermissionGranted() would be called.
*
* 2. Above M, if the permission is being asked first time onPermissionAsk() would be called.
*
* 3. Above M, if the permission is previously asked but not granted, onPermissionPreviouslyDenied()
* would be called.
*
* 4. Above M, if the permission is disabled by device policy or the user checked "Never ask again"
* check box on previous request permission, onPermissionDisabled() would be called.
* */
public interface PermissionAskListener {
/*
* Callback to ask permission
* */
void onPermissionAsk();
/*
* Callback on permission denied
* */
void onPermissionPreviouslyDenied();
/*
* Callback on permission "Never show again" checked and denied
* */
void onPermissionDisabled();
/*
* Callback on permission granted
* */
void onPermissionGranted();
}
}
And the PreferenceUtil methods are as follows.
public static void firstTimeAskingPermission(Context context, String permission, boolean isFirstTime){
SharedPreferences sharedPreference = context.getSharedPreferences(PREFS_FILE_NAME, MODE_PRIVATE;
sharedPreference.edit().putBoolean(permission, isFirstTime).apply();
}
public static boolean isFirstTimeAskingPermission(Context context, String permission){
return context.getSharedPreferences(PREFS_FILE_NAME, MODE_PRIVATE).getBoolean(permission, true);
}
Now, all you need is to use the method * checkPermission* with proper arguments.
Here is an example,
PermissionUtil.checkPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE,
new PermissionUtil.PermissionAskListener() {
@Override
public void onPermissionAsk() {
ActivityCompat.requestPermissions(
thisActivity,
new String{Manifest.permission.READ_CONTACTS},
REQUEST_EXTERNAL_STORAGE
);
}
@Override
public void onPermissionPreviouslyDenied() {
//show a dialog explaining permission and then request permission
}
@Override
public void onPermissionDisabled() {
Toast.makeText(context, "Permission Disabled.", Toast.LENGTH_SHORT).show();
}
@Override
public void onPermissionGranted() {
readContacts();
}
});
how does my app know whether the user has checked the "Never ask again"?
If user checked Never ask again, you'll get callback on onPermissionDisabled.
Happy coding :)
edited Jun 16 '17 at 13:51
answered Nov 16 '16 at 18:10
muthurajmuthuraj
6591115
6591115
shouldShowRequestPermissionRationale i got error here, can you plz help me.
– Rucha Bhatt Joshi
Jun 16 '17 at 7:17
@RuchaBhatt What error you got?
– muthuraj
Jun 16 '17 at 7:36
i cant find this method shouldShowRequestPermissionRationale may be i failed to get context.. but it's fine i found other alternate solution.. Thank you for help :)
– Rucha Bhatt Joshi
Jun 16 '17 at 8:50
1
My bad. shouldShowRequestPermissionRationale is available through Activity, not context. I updated my answer by casting the context to Activity before calling that method. Check it out :)
– muthuraj
Jun 16 '17 at 13:52
add a comment |
shouldShowRequestPermissionRationale i got error here, can you plz help me.
– Rucha Bhatt Joshi
Jun 16 '17 at 7:17
@RuchaBhatt What error you got?
– muthuraj
Jun 16 '17 at 7:36
i cant find this method shouldShowRequestPermissionRationale may be i failed to get context.. but it's fine i found other alternate solution.. Thank you for help :)
– Rucha Bhatt Joshi
Jun 16 '17 at 8:50
1
My bad. shouldShowRequestPermissionRationale is available through Activity, not context. I updated my answer by casting the context to Activity before calling that method. Check it out :)
– muthuraj
Jun 16 '17 at 13:52
shouldShowRequestPermissionRationale i got error here, can you plz help me.
– Rucha Bhatt Joshi
Jun 16 '17 at 7:17
shouldShowRequestPermissionRationale i got error here, can you plz help me.
– Rucha Bhatt Joshi
Jun 16 '17 at 7:17
@RuchaBhatt What error you got?
– muthuraj
Jun 16 '17 at 7:36
@RuchaBhatt What error you got?
– muthuraj
Jun 16 '17 at 7:36
i cant find this method shouldShowRequestPermissionRationale may be i failed to get context.. but it's fine i found other alternate solution.. Thank you for help :)
– Rucha Bhatt Joshi
Jun 16 '17 at 8:50
i cant find this method shouldShowRequestPermissionRationale may be i failed to get context.. but it's fine i found other alternate solution.. Thank you for help :)
– Rucha Bhatt Joshi
Jun 16 '17 at 8:50
1
1
My bad. shouldShowRequestPermissionRationale is available through Activity, not context. I updated my answer by casting the context to Activity before calling that method. Check it out :)
– muthuraj
Jun 16 '17 at 13:52
My bad. shouldShowRequestPermissionRationale is available through Activity, not context. I updated my answer by casting the context to Activity before calling that method. Check it out :)
– muthuraj
Jun 16 '17 at 13:52
add a comment |
Complete explanation for every case of permission
/**
* Case 1: User doesn't have permission
* Case 2: User has permission
*
* Case 3: User has never seen the permission Dialog
* Case 4: User has denied permission once but he din't clicked on "Never Show again" check box
* Case 5: User denied the permission and also clicked on the "Never Show again" check box.
* Case 6: User has allowed the permission
*
*/
public void handlePermission() {
if (ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// This is Case 1. Now we need to check further if permission was shown before or not
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// This is Case 4.
} else {
// This is Case 3. Request for permission here
}
} else {
// This is Case 2. You have permission now you can do anything related to it
}
}
public void onRequestPermissionsResult(int requestCode, String permissions, int grantResults) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// This is Case 2 (Permission is now granted)
} else {
// This is Case 1 again as Permission is not granted by user
//Now further we check if used denied permanently or not
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// case 4 User has denied permission but not permanently
} else {
// case 5. Permission denied permanently.
// You can open Permission setting's page from here now.
}
}
}
add a comment |
Complete explanation for every case of permission
/**
* Case 1: User doesn't have permission
* Case 2: User has permission
*
* Case 3: User has never seen the permission Dialog
* Case 4: User has denied permission once but he din't clicked on "Never Show again" check box
* Case 5: User denied the permission and also clicked on the "Never Show again" check box.
* Case 6: User has allowed the permission
*
*/
public void handlePermission() {
if (ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// This is Case 1. Now we need to check further if permission was shown before or not
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// This is Case 4.
} else {
// This is Case 3. Request for permission here
}
} else {
// This is Case 2. You have permission now you can do anything related to it
}
}
public void onRequestPermissionsResult(int requestCode, String permissions, int grantResults) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// This is Case 2 (Permission is now granted)
} else {
// This is Case 1 again as Permission is not granted by user
//Now further we check if used denied permanently or not
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// case 4 User has denied permission but not permanently
} else {
// case 5. Permission denied permanently.
// You can open Permission setting's page from here now.
}
}
}
add a comment |
Complete explanation for every case of permission
/**
* Case 1: User doesn't have permission
* Case 2: User has permission
*
* Case 3: User has never seen the permission Dialog
* Case 4: User has denied permission once but he din't clicked on "Never Show again" check box
* Case 5: User denied the permission and also clicked on the "Never Show again" check box.
* Case 6: User has allowed the permission
*
*/
public void handlePermission() {
if (ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// This is Case 1. Now we need to check further if permission was shown before or not
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// This is Case 4.
} else {
// This is Case 3. Request for permission here
}
} else {
// This is Case 2. You have permission now you can do anything related to it
}
}
public void onRequestPermissionsResult(int requestCode, String permissions, int grantResults) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// This is Case 2 (Permission is now granted)
} else {
// This is Case 1 again as Permission is not granted by user
//Now further we check if used denied permanently or not
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// case 4 User has denied permission but not permanently
} else {
// case 5. Permission denied permanently.
// You can open Permission setting's page from here now.
}
}
}
Complete explanation for every case of permission
/**
* Case 1: User doesn't have permission
* Case 2: User has permission
*
* Case 3: User has never seen the permission Dialog
* Case 4: User has denied permission once but he din't clicked on "Never Show again" check box
* Case 5: User denied the permission and also clicked on the "Never Show again" check box.
* Case 6: User has allowed the permission
*
*/
public void handlePermission() {
if (ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// This is Case 1. Now we need to check further if permission was shown before or not
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// This is Case 4.
} else {
// This is Case 3. Request for permission here
}
} else {
// This is Case 2. You have permission now you can do anything related to it
}
}
public void onRequestPermissionsResult(int requestCode, String permissions, int grantResults) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// This is Case 2 (Permission is now granted)
} else {
// This is Case 1 again as Permission is not granted by user
//Now further we check if used denied permanently or not
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// case 4 User has denied permission but not permanently
} else {
// case 5. Permission denied permanently.
// You can open Permission setting's page from here now.
}
}
}
answered Apr 27 '18 at 8:17
sakshamsaksham
904914
904914
add a comment |
add a comment |
I wrote a shorthand for permission request in Android M. This code also handles backwards compatibility to older Android versions.
All the ugly code is extracted into a Fragment which attaches and detaches itself to the Activity requesting the permissions.You can use PermissionRequestManager
as following:
new PermissionRequestManager()
// We need a AppCompatActivity here, if you are not using support libraries you will have to slightly change
// the PermissionReuqestManager class
.withActivity(this)
// List all permissions you need
.withPermissions(android.Manifest.permission.CALL_PHONE, android.Manifest.permission.READ_CALENDAR)
// This Runnable is called whenever the request was successfull
.withSuccessHandler(new Runnable() {
@Override
public void run() {
// Do something with your permissions!
// This is called after the user has granted all
// permissions, we are one a older platform where
// the user does not need to grant permissions
// manually, or all permissions are already granted
}
})
// Optional, called when the user did not grant all permissions
.withFailureHandler(new Runnable() {
@Override
public void run() {
// This is called if the user has rejected one or all of the requested permissions
L.e(this.getClass().getSimpleName(), "Unable to request permission");
}
})
// After calling this, the user is prompted to grant the rights
.request();
Take a look: https://gist.github.com/crysxd/385b57d74045a8bd67c4110c34ab74aa
add a comment |
I wrote a shorthand for permission request in Android M. This code also handles backwards compatibility to older Android versions.
All the ugly code is extracted into a Fragment which attaches and detaches itself to the Activity requesting the permissions.You can use PermissionRequestManager
as following:
new PermissionRequestManager()
// We need a AppCompatActivity here, if you are not using support libraries you will have to slightly change
// the PermissionReuqestManager class
.withActivity(this)
// List all permissions you need
.withPermissions(android.Manifest.permission.CALL_PHONE, android.Manifest.permission.READ_CALENDAR)
// This Runnable is called whenever the request was successfull
.withSuccessHandler(new Runnable() {
@Override
public void run() {
// Do something with your permissions!
// This is called after the user has granted all
// permissions, we are one a older platform where
// the user does not need to grant permissions
// manually, or all permissions are already granted
}
})
// Optional, called when the user did not grant all permissions
.withFailureHandler(new Runnable() {
@Override
public void run() {
// This is called if the user has rejected one or all of the requested permissions
L.e(this.getClass().getSimpleName(), "Unable to request permission");
}
})
// After calling this, the user is prompted to grant the rights
.request();
Take a look: https://gist.github.com/crysxd/385b57d74045a8bd67c4110c34ab74aa
add a comment |
I wrote a shorthand for permission request in Android M. This code also handles backwards compatibility to older Android versions.
All the ugly code is extracted into a Fragment which attaches and detaches itself to the Activity requesting the permissions.You can use PermissionRequestManager
as following:
new PermissionRequestManager()
// We need a AppCompatActivity here, if you are not using support libraries you will have to slightly change
// the PermissionReuqestManager class
.withActivity(this)
// List all permissions you need
.withPermissions(android.Manifest.permission.CALL_PHONE, android.Manifest.permission.READ_CALENDAR)
// This Runnable is called whenever the request was successfull
.withSuccessHandler(new Runnable() {
@Override
public void run() {
// Do something with your permissions!
// This is called after the user has granted all
// permissions, we are one a older platform where
// the user does not need to grant permissions
// manually, or all permissions are already granted
}
})
// Optional, called when the user did not grant all permissions
.withFailureHandler(new Runnable() {
@Override
public void run() {
// This is called if the user has rejected one or all of the requested permissions
L.e(this.getClass().getSimpleName(), "Unable to request permission");
}
})
// After calling this, the user is prompted to grant the rights
.request();
Take a look: https://gist.github.com/crysxd/385b57d74045a8bd67c4110c34ab74aa
I wrote a shorthand for permission request in Android M. This code also handles backwards compatibility to older Android versions.
All the ugly code is extracted into a Fragment which attaches and detaches itself to the Activity requesting the permissions.You can use PermissionRequestManager
as following:
new PermissionRequestManager()
// We need a AppCompatActivity here, if you are not using support libraries you will have to slightly change
// the PermissionReuqestManager class
.withActivity(this)
// List all permissions you need
.withPermissions(android.Manifest.permission.CALL_PHONE, android.Manifest.permission.READ_CALENDAR)
// This Runnable is called whenever the request was successfull
.withSuccessHandler(new Runnable() {
@Override
public void run() {
// Do something with your permissions!
// This is called after the user has granted all
// permissions, we are one a older platform where
// the user does not need to grant permissions
// manually, or all permissions are already granted
}
})
// Optional, called when the user did not grant all permissions
.withFailureHandler(new Runnable() {
@Override
public void run() {
// This is called if the user has rejected one or all of the requested permissions
L.e(this.getClass().getSimpleName(), "Unable to request permission");
}
})
// After calling this, the user is prompted to grant the rights
.request();
Take a look: https://gist.github.com/crysxd/385b57d74045a8bd67c4110c34ab74aa
edited Jul 24 '16 at 16:47
answered Jul 24 '16 at 12:08
crysxdcrysxd
802714
802714
add a comment |
add a comment |
The method shouldShowRequestPermissionRationale() can be user to check whether the user selected the 'never asked again' option and denied the permission.
There's plenty of code examples, so I would rather explain how to use it for such a purpose, because I think its name and its implementation makes this more complicated that it actually is.
As explained in Requesting Permissions at Run Time, that method returns true if the option 'never ask again' is visible, false otherwise; so it returns false the very first time a dialog is shown, then from the second time on it returns true, and only if the user deny the permission selecting the option, at that point it returns false again.
To detect such a case, either you can detect the sequence false-true-false, or (more simple) you can have a flag which keeps track of the initial time the dialog is shown. After that, that method returns either true or false, where the false will allow you to detect when the option is selected.
add a comment |
The method shouldShowRequestPermissionRationale() can be user to check whether the user selected the 'never asked again' option and denied the permission.
There's plenty of code examples, so I would rather explain how to use it for such a purpose, because I think its name and its implementation makes this more complicated that it actually is.
As explained in Requesting Permissions at Run Time, that method returns true if the option 'never ask again' is visible, false otherwise; so it returns false the very first time a dialog is shown, then from the second time on it returns true, and only if the user deny the permission selecting the option, at that point it returns false again.
To detect such a case, either you can detect the sequence false-true-false, or (more simple) you can have a flag which keeps track of the initial time the dialog is shown. After that, that method returns either true or false, where the false will allow you to detect when the option is selected.
add a comment |
The method shouldShowRequestPermissionRationale() can be user to check whether the user selected the 'never asked again' option and denied the permission.
There's plenty of code examples, so I would rather explain how to use it for such a purpose, because I think its name and its implementation makes this more complicated that it actually is.
As explained in Requesting Permissions at Run Time, that method returns true if the option 'never ask again' is visible, false otherwise; so it returns false the very first time a dialog is shown, then from the second time on it returns true, and only if the user deny the permission selecting the option, at that point it returns false again.
To detect such a case, either you can detect the sequence false-true-false, or (more simple) you can have a flag which keeps track of the initial time the dialog is shown. After that, that method returns either true or false, where the false will allow you to detect when the option is selected.
The method shouldShowRequestPermissionRationale() can be user to check whether the user selected the 'never asked again' option and denied the permission.
There's plenty of code examples, so I would rather explain how to use it for such a purpose, because I think its name and its implementation makes this more complicated that it actually is.
As explained in Requesting Permissions at Run Time, that method returns true if the option 'never ask again' is visible, false otherwise; so it returns false the very first time a dialog is shown, then from the second time on it returns true, and only if the user deny the permission selecting the option, at that point it returns false again.
To detect such a case, either you can detect the sequence false-true-false, or (more simple) you can have a flag which keeps track of the initial time the dialog is shown. After that, that method returns either true or false, where the false will allow you to detect when the option is selected.
answered Jun 7 '17 at 7:16
AlessioAlessio
2,021913
2,021913
add a comment |
add a comment |
Try this simple permission library. It will handle all operations related to permission in 3 easy steps. It saved my time. You can finish all permission related work in 15 mins.
It can handle Deny, It can handle Never ask again, It can call app settings for permission, It can give a Rational message, It can give a Denial message, It can give a list of accepted permissions, It can give a list of denied permissions and etc.
https://github.com/ParkSangGwon/TedPermission
Step 1: add your dependency
dependencies {
compile 'gun0912.ted:tedpermission:2.1.1'
//check the above link for latest libraries
}
Step2: Ask permissions
TedPermission.with(this)
.setPermissionListener(permissionlistener)
.setDeniedMessage("If you reject permission,you can not use this servicennPlease turn on permissions at [Setting] > [Permission]")
.setPermissions(Manifest.permission.READ_CONTACTS, Manifest.permission.ACCESS_FINE_LOCATION)
.check();
Step 3: Handle permission response
PermissionListener permissionlistener = new PermissionListener() {
@Override
public void onPermissionGranted() {
Toast.makeText(MainActivity.this, "Permission Granted", Toast.LENGTH_SHORT).show();
}
@Override
public void onPermissionDenied(ArrayList<String> deniedPermissions) {
Toast.makeText(MainActivity.this, "Permission Deniedn" + deniedPermissions.toString(), Toast.LENGTH_SHORT).show();
}
};
Great. It saved my time
– Vigneswaran A
Apr 23 '18 at 7:44
Nice, easy to use
– Uray Febri
Aug 6 '18 at 7:21
add a comment |
Try this simple permission library. It will handle all operations related to permission in 3 easy steps. It saved my time. You can finish all permission related work in 15 mins.
It can handle Deny, It can handle Never ask again, It can call app settings for permission, It can give a Rational message, It can give a Denial message, It can give a list of accepted permissions, It can give a list of denied permissions and etc.
https://github.com/ParkSangGwon/TedPermission
Step 1: add your dependency
dependencies {
compile 'gun0912.ted:tedpermission:2.1.1'
//check the above link for latest libraries
}
Step2: Ask permissions
TedPermission.with(this)
.setPermissionListener(permissionlistener)
.setDeniedMessage("If you reject permission,you can not use this servicennPlease turn on permissions at [Setting] > [Permission]")
.setPermissions(Manifest.permission.READ_CONTACTS, Manifest.permission.ACCESS_FINE_LOCATION)
.check();
Step 3: Handle permission response
PermissionListener permissionlistener = new PermissionListener() {
@Override
public void onPermissionGranted() {
Toast.makeText(MainActivity.this, "Permission Granted", Toast.LENGTH_SHORT).show();
}
@Override
public void onPermissionDenied(ArrayList<String> deniedPermissions) {
Toast.makeText(MainActivity.this, "Permission Deniedn" + deniedPermissions.toString(), Toast.LENGTH_SHORT).show();
}
};
Great. It saved my time
– Vigneswaran A
Apr 23 '18 at 7:44
Nice, easy to use
– Uray Febri
Aug 6 '18 at 7:21
add a comment |
Try this simple permission library. It will handle all operations related to permission in 3 easy steps. It saved my time. You can finish all permission related work in 15 mins.
It can handle Deny, It can handle Never ask again, It can call app settings for permission, It can give a Rational message, It can give a Denial message, It can give a list of accepted permissions, It can give a list of denied permissions and etc.
https://github.com/ParkSangGwon/TedPermission
Step 1: add your dependency
dependencies {
compile 'gun0912.ted:tedpermission:2.1.1'
//check the above link for latest libraries
}
Step2: Ask permissions
TedPermission.with(this)
.setPermissionListener(permissionlistener)
.setDeniedMessage("If you reject permission,you can not use this servicennPlease turn on permissions at [Setting] > [Permission]")
.setPermissions(Manifest.permission.READ_CONTACTS, Manifest.permission.ACCESS_FINE_LOCATION)
.check();
Step 3: Handle permission response
PermissionListener permissionlistener = new PermissionListener() {
@Override
public void onPermissionGranted() {
Toast.makeText(MainActivity.this, "Permission Granted", Toast.LENGTH_SHORT).show();
}
@Override
public void onPermissionDenied(ArrayList<String> deniedPermissions) {
Toast.makeText(MainActivity.this, "Permission Deniedn" + deniedPermissions.toString(), Toast.LENGTH_SHORT).show();
}
};
Try this simple permission library. It will handle all operations related to permission in 3 easy steps. It saved my time. You can finish all permission related work in 15 mins.
It can handle Deny, It can handle Never ask again, It can call app settings for permission, It can give a Rational message, It can give a Denial message, It can give a list of accepted permissions, It can give a list of denied permissions and etc.
https://github.com/ParkSangGwon/TedPermission
Step 1: add your dependency
dependencies {
compile 'gun0912.ted:tedpermission:2.1.1'
//check the above link for latest libraries
}
Step2: Ask permissions
TedPermission.with(this)
.setPermissionListener(permissionlistener)
.setDeniedMessage("If you reject permission,you can not use this servicennPlease turn on permissions at [Setting] > [Permission]")
.setPermissions(Manifest.permission.READ_CONTACTS, Manifest.permission.ACCESS_FINE_LOCATION)
.check();
Step 3: Handle permission response
PermissionListener permissionlistener = new PermissionListener() {
@Override
public void onPermissionGranted() {
Toast.makeText(MainActivity.this, "Permission Granted", Toast.LENGTH_SHORT).show();
}
@Override
public void onPermissionDenied(ArrayList<String> deniedPermissions) {
Toast.makeText(MainActivity.this, "Permission Deniedn" + deniedPermissions.toString(), Toast.LENGTH_SHORT).show();
}
};
edited Apr 23 '18 at 7:41
answered Apr 23 '18 at 7:24
VignesVignes
14117
14117
Great. It saved my time
– Vigneswaran A
Apr 23 '18 at 7:44
Nice, easy to use
– Uray Febri
Aug 6 '18 at 7:21
add a comment |
Great. It saved my time
– Vigneswaran A
Apr 23 '18 at 7:44
Nice, easy to use
– Uray Febri
Aug 6 '18 at 7:21
Great. It saved my time
– Vigneswaran A
Apr 23 '18 at 7:44
Great. It saved my time
– Vigneswaran A
Apr 23 '18 at 7:44
Nice, easy to use
– Uray Febri
Aug 6 '18 at 7:21
Nice, easy to use
– Uray Febri
Aug 6 '18 at 7:21
add a comment |
A useful function to determine if an arbitrary permission has been blocked from requesting (in Kotlin):
private fun isPermissionBlockedFromAsking(activity: Activity, permission: String): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED
&& !activity.shouldShowRequestPermissionRationale(permission)
&& PreferenceManager.getDefaultSharedPreferences(activity).getBoolean(permission, false)
}
return false
}
Use of this requires setting a shared preference boolean with the name of your desired permission (e.g. android.Manifest.permission.READ_PHONE_STATE
) to true
when you first request a permission.
Explanation:
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
as some of the code may only be run on API level 23+.
ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED
to check we don't already have the permission.
!activity.shouldShowRequestPermissionRationale(permission)
to check whether the user has denied the app asking again. Due to quirks of this function, the following line is also required.
PreferenceManager.getDefaultSharedPreferences(activity).getBoolean(permission, false)
this is used (along with setting the value to true on first permission request) to distinguish between the "Never asked" and "Never ask again" states, as the previous line doesn't return this information.
add a comment |
A useful function to determine if an arbitrary permission has been blocked from requesting (in Kotlin):
private fun isPermissionBlockedFromAsking(activity: Activity, permission: String): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED
&& !activity.shouldShowRequestPermissionRationale(permission)
&& PreferenceManager.getDefaultSharedPreferences(activity).getBoolean(permission, false)
}
return false
}
Use of this requires setting a shared preference boolean with the name of your desired permission (e.g. android.Manifest.permission.READ_PHONE_STATE
) to true
when you first request a permission.
Explanation:
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
as some of the code may only be run on API level 23+.
ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED
to check we don't already have the permission.
!activity.shouldShowRequestPermissionRationale(permission)
to check whether the user has denied the app asking again. Due to quirks of this function, the following line is also required.
PreferenceManager.getDefaultSharedPreferences(activity).getBoolean(permission, false)
this is used (along with setting the value to true on first permission request) to distinguish between the "Never asked" and "Never ask again" states, as the previous line doesn't return this information.
add a comment |
A useful function to determine if an arbitrary permission has been blocked from requesting (in Kotlin):
private fun isPermissionBlockedFromAsking(activity: Activity, permission: String): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED
&& !activity.shouldShowRequestPermissionRationale(permission)
&& PreferenceManager.getDefaultSharedPreferences(activity).getBoolean(permission, false)
}
return false
}
Use of this requires setting a shared preference boolean with the name of your desired permission (e.g. android.Manifest.permission.READ_PHONE_STATE
) to true
when you first request a permission.
Explanation:
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
as some of the code may only be run on API level 23+.
ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED
to check we don't already have the permission.
!activity.shouldShowRequestPermissionRationale(permission)
to check whether the user has denied the app asking again. Due to quirks of this function, the following line is also required.
PreferenceManager.getDefaultSharedPreferences(activity).getBoolean(permission, false)
this is used (along with setting the value to true on first permission request) to distinguish between the "Never asked" and "Never ask again" states, as the previous line doesn't return this information.
A useful function to determine if an arbitrary permission has been blocked from requesting (in Kotlin):
private fun isPermissionBlockedFromAsking(activity: Activity, permission: String): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED
&& !activity.shouldShowRequestPermissionRationale(permission)
&& PreferenceManager.getDefaultSharedPreferences(activity).getBoolean(permission, false)
}
return false
}
Use of this requires setting a shared preference boolean with the name of your desired permission (e.g. android.Manifest.permission.READ_PHONE_STATE
) to true
when you first request a permission.
Explanation:
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
as some of the code may only be run on API level 23+.
ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED
to check we don't already have the permission.
!activity.shouldShowRequestPermissionRationale(permission)
to check whether the user has denied the app asking again. Due to quirks of this function, the following line is also required.
PreferenceManager.getDefaultSharedPreferences(activity).getBoolean(permission, false)
this is used (along with setting the value to true on first permission request) to distinguish between the "Never asked" and "Never ask again" states, as the previous line doesn't return this information.
answered Jul 5 '18 at 11:20
JakeSteamJakeSteam
2,12052336
2,12052336
add a comment |
add a comment |
Please don't throw stones at me for this solution.
This works but is a bit "hacky".
When you call requestPermissions
, register the current time.
mAskedPermissionTime = System.currentTimeMillis();
Then in onRequestPermissionsResult
if the result is not granted, check the time again.
if (System.currentTimeMillis() - mAskedPermissionTime < 100)
Since the user did cannot possibly click so fast on the deny button, we know that he selected "never ask again" because the callback is instant.
Use at your own risks.
what if we see that requested dialog for 5 minutes and then deny?
– saksham
May 11 '18 at 9:59
It relies on the user accepting fast, not slow
– Antzi
May 11 '18 at 15:41
Then what is the use of this if it can't fulfill the basic requirement. A code can be a hack as accepted if it clearly fulfills all the requirements in every case else not.
– saksham
May 13 '18 at 5:42
add a comment |
Please don't throw stones at me for this solution.
This works but is a bit "hacky".
When you call requestPermissions
, register the current time.
mAskedPermissionTime = System.currentTimeMillis();
Then in onRequestPermissionsResult
if the result is not granted, check the time again.
if (System.currentTimeMillis() - mAskedPermissionTime < 100)
Since the user did cannot possibly click so fast on the deny button, we know that he selected "never ask again" because the callback is instant.
Use at your own risks.
what if we see that requested dialog for 5 minutes and then deny?
– saksham
May 11 '18 at 9:59
It relies on the user accepting fast, not slow
– Antzi
May 11 '18 at 15:41
Then what is the use of this if it can't fulfill the basic requirement. A code can be a hack as accepted if it clearly fulfills all the requirements in every case else not.
– saksham
May 13 '18 at 5:42
add a comment |
Please don't throw stones at me for this solution.
This works but is a bit "hacky".
When you call requestPermissions
, register the current time.
mAskedPermissionTime = System.currentTimeMillis();
Then in onRequestPermissionsResult
if the result is not granted, check the time again.
if (System.currentTimeMillis() - mAskedPermissionTime < 100)
Since the user did cannot possibly click so fast on the deny button, we know that he selected "never ask again" because the callback is instant.
Use at your own risks.
Please don't throw stones at me for this solution.
This works but is a bit "hacky".
When you call requestPermissions
, register the current time.
mAskedPermissionTime = System.currentTimeMillis();
Then in onRequestPermissionsResult
if the result is not granted, check the time again.
if (System.currentTimeMillis() - mAskedPermissionTime < 100)
Since the user did cannot possibly click so fast on the deny button, we know that he selected "never ask again" because the callback is instant.
Use at your own risks.
answered Mar 14 '17 at 4:46
AntziAntzi
7,86352959
7,86352959
what if we see that requested dialog for 5 minutes and then deny?
– saksham
May 11 '18 at 9:59
It relies on the user accepting fast, not slow
– Antzi
May 11 '18 at 15:41
Then what is the use of this if it can't fulfill the basic requirement. A code can be a hack as accepted if it clearly fulfills all the requirements in every case else not.
– saksham
May 13 '18 at 5:42
add a comment |
what if we see that requested dialog for 5 minutes and then deny?
– saksham
May 11 '18 at 9:59
It relies on the user accepting fast, not slow
– Antzi
May 11 '18 at 15:41
Then what is the use of this if it can't fulfill the basic requirement. A code can be a hack as accepted if it clearly fulfills all the requirements in every case else not.
– saksham
May 13 '18 at 5:42
what if we see that requested dialog for 5 minutes and then deny?
– saksham
May 11 '18 at 9:59
what if we see that requested dialog for 5 minutes and then deny?
– saksham
May 11 '18 at 9:59
It relies on the user accepting fast, not slow
– Antzi
May 11 '18 at 15:41
It relies on the user accepting fast, not slow
– Antzi
May 11 '18 at 15:41
Then what is the use of this if it can't fulfill the basic requirement. A code can be a hack as accepted if it clearly fulfills all the requirements in every case else not.
– saksham
May 13 '18 at 5:42
Then what is the use of this if it can't fulfill the basic requirement. A code can be a hack as accepted if it clearly fulfills all the requirements in every case else not.
– saksham
May 13 '18 at 5:42
add a comment |
You can use
shouldShowRequestPermissionRationale()
inside
onRequestPermissionsResult()
See the example below:
Check if it has permission when the user clicks the button:
@Override
public void onClick(View v) {
if (v.getId() == R.id.appCompatBtn_changeProfileCoverPhoto) {
if (Build.VERSION.SDK_INT < 23) { // API < 23 don't need to ask permission
navigateTo(MainActivity.class); // Navigate to activity to change photos
} else {
if (ContextCompat.checkSelfPermission(SettingsActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted yet. Ask for permission...
requestWriteExternalPermission();
} else {
// Permission is already granted, good to go :)
navigateTo(MainActivity.class);
}
}
}
}
When the user answer the permission dialog box we will go to onRequestPermissionResult:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == WRITE_EXTERNAL_PERMISSION_REQUEST_CODE) {
// Case 1. Permission is granted.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(SettingsActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
// Before navigating, I still check one more time the permission for good practice.
navigateTo(MainActivity.class);
}
} else { // Case 2. Permission was refused
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// Case 2.1. shouldShowRequest... returns true because the
// permission was denied before. If it is the first time the app is running we will
// end up in this part of the code. Because he need to deny at least once to get
// to onRequestPermissionsResult.
Snackbar snackbar = Snackbar.make(findViewById(R.id.relLayout_container), R.string.you_must_verify_permissions_to_send_media, Snackbar.LENGTH_LONG);
snackbar.setAction("VERIFY", new View.OnClickListener() {
@Override
public void onClick(View v) {
ActivityCompat.requestPermissions(SettingsActivity.this
, new String{Manifest.permission.WRITE_EXTERNAL_STORAGE}
, WRITE_EXTERNAL_PERMISSION_REQUEST_CODE);
}
});
snackbar.show();
} else {
// Case 2.2. Permission was already denied and the user checked "Never ask again".
// Navigate user to settings if he choose to allow this time.
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.instructions_to_turn_on_storage_permission)
.setPositiveButton(getString(R.string.settings), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent settingsIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
settingsIntent.setData(uri);
startActivityForResult(settingsIntent, 7);
}
})
.setNegativeButton(getString(R.string.not_now), null);
Dialog dialog = builder.create();
dialog.show();
}
}
}
}
add a comment |
You can use
shouldShowRequestPermissionRationale()
inside
onRequestPermissionsResult()
See the example below:
Check if it has permission when the user clicks the button:
@Override
public void onClick(View v) {
if (v.getId() == R.id.appCompatBtn_changeProfileCoverPhoto) {
if (Build.VERSION.SDK_INT < 23) { // API < 23 don't need to ask permission
navigateTo(MainActivity.class); // Navigate to activity to change photos
} else {
if (ContextCompat.checkSelfPermission(SettingsActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted yet. Ask for permission...
requestWriteExternalPermission();
} else {
// Permission is already granted, good to go :)
navigateTo(MainActivity.class);
}
}
}
}
When the user answer the permission dialog box we will go to onRequestPermissionResult:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == WRITE_EXTERNAL_PERMISSION_REQUEST_CODE) {
// Case 1. Permission is granted.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(SettingsActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
// Before navigating, I still check one more time the permission for good practice.
navigateTo(MainActivity.class);
}
} else { // Case 2. Permission was refused
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// Case 2.1. shouldShowRequest... returns true because the
// permission was denied before. If it is the first time the app is running we will
// end up in this part of the code. Because he need to deny at least once to get
// to onRequestPermissionsResult.
Snackbar snackbar = Snackbar.make(findViewById(R.id.relLayout_container), R.string.you_must_verify_permissions_to_send_media, Snackbar.LENGTH_LONG);
snackbar.setAction("VERIFY", new View.OnClickListener() {
@Override
public void onClick(View v) {
ActivityCompat.requestPermissions(SettingsActivity.this
, new String{Manifest.permission.WRITE_EXTERNAL_STORAGE}
, WRITE_EXTERNAL_PERMISSION_REQUEST_CODE);
}
});
snackbar.show();
} else {
// Case 2.2. Permission was already denied and the user checked "Never ask again".
// Navigate user to settings if he choose to allow this time.
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.instructions_to_turn_on_storage_permission)
.setPositiveButton(getString(R.string.settings), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent settingsIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
settingsIntent.setData(uri);
startActivityForResult(settingsIntent, 7);
}
})
.setNegativeButton(getString(R.string.not_now), null);
Dialog dialog = builder.create();
dialog.show();
}
}
}
}
add a comment |
You can use
shouldShowRequestPermissionRationale()
inside
onRequestPermissionsResult()
See the example below:
Check if it has permission when the user clicks the button:
@Override
public void onClick(View v) {
if (v.getId() == R.id.appCompatBtn_changeProfileCoverPhoto) {
if (Build.VERSION.SDK_INT < 23) { // API < 23 don't need to ask permission
navigateTo(MainActivity.class); // Navigate to activity to change photos
} else {
if (ContextCompat.checkSelfPermission(SettingsActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted yet. Ask for permission...
requestWriteExternalPermission();
} else {
// Permission is already granted, good to go :)
navigateTo(MainActivity.class);
}
}
}
}
When the user answer the permission dialog box we will go to onRequestPermissionResult:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == WRITE_EXTERNAL_PERMISSION_REQUEST_CODE) {
// Case 1. Permission is granted.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(SettingsActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
// Before navigating, I still check one more time the permission for good practice.
navigateTo(MainActivity.class);
}
} else { // Case 2. Permission was refused
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// Case 2.1. shouldShowRequest... returns true because the
// permission was denied before. If it is the first time the app is running we will
// end up in this part of the code. Because he need to deny at least once to get
// to onRequestPermissionsResult.
Snackbar snackbar = Snackbar.make(findViewById(R.id.relLayout_container), R.string.you_must_verify_permissions_to_send_media, Snackbar.LENGTH_LONG);
snackbar.setAction("VERIFY", new View.OnClickListener() {
@Override
public void onClick(View v) {
ActivityCompat.requestPermissions(SettingsActivity.this
, new String{Manifest.permission.WRITE_EXTERNAL_STORAGE}
, WRITE_EXTERNAL_PERMISSION_REQUEST_CODE);
}
});
snackbar.show();
} else {
// Case 2.2. Permission was already denied and the user checked "Never ask again".
// Navigate user to settings if he choose to allow this time.
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.instructions_to_turn_on_storage_permission)
.setPositiveButton(getString(R.string.settings), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent settingsIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
settingsIntent.setData(uri);
startActivityForResult(settingsIntent, 7);
}
})
.setNegativeButton(getString(R.string.not_now), null);
Dialog dialog = builder.create();
dialog.show();
}
}
}
}
You can use
shouldShowRequestPermissionRationale()
inside
onRequestPermissionsResult()
See the example below:
Check if it has permission when the user clicks the button:
@Override
public void onClick(View v) {
if (v.getId() == R.id.appCompatBtn_changeProfileCoverPhoto) {
if (Build.VERSION.SDK_INT < 23) { // API < 23 don't need to ask permission
navigateTo(MainActivity.class); // Navigate to activity to change photos
} else {
if (ContextCompat.checkSelfPermission(SettingsActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted yet. Ask for permission...
requestWriteExternalPermission();
} else {
// Permission is already granted, good to go :)
navigateTo(MainActivity.class);
}
}
}
}
When the user answer the permission dialog box we will go to onRequestPermissionResult:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == WRITE_EXTERNAL_PERMISSION_REQUEST_CODE) {
// Case 1. Permission is granted.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(SettingsActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
// Before navigating, I still check one more time the permission for good practice.
navigateTo(MainActivity.class);
}
} else { // Case 2. Permission was refused
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// Case 2.1. shouldShowRequest... returns true because the
// permission was denied before. If it is the first time the app is running we will
// end up in this part of the code. Because he need to deny at least once to get
// to onRequestPermissionsResult.
Snackbar snackbar = Snackbar.make(findViewById(R.id.relLayout_container), R.string.you_must_verify_permissions_to_send_media, Snackbar.LENGTH_LONG);
snackbar.setAction("VERIFY", new View.OnClickListener() {
@Override
public void onClick(View v) {
ActivityCompat.requestPermissions(SettingsActivity.this
, new String{Manifest.permission.WRITE_EXTERNAL_STORAGE}
, WRITE_EXTERNAL_PERMISSION_REQUEST_CODE);
}
});
snackbar.show();
} else {
// Case 2.2. Permission was already denied and the user checked "Never ask again".
// Navigate user to settings if he choose to allow this time.
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.instructions_to_turn_on_storage_permission)
.setPositiveButton(getString(R.string.settings), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent settingsIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
settingsIntent.setData(uri);
startActivityForResult(settingsIntent, 7);
}
})
.setNegativeButton(getString(R.string.not_now), null);
Dialog dialog = builder.create();
dialog.show();
}
}
}
}
answered Jun 28 '18 at 12:44
Soon SantosSoon Santos
639410
639410
add a comment |
add a comment |
you can listener pretty.
Listener
interface PermissionListener {
fun onNeedPermission()
fun onPermissionPreviouslyDenied(numberDenyPermission: Int)
fun onPermissionDisabledPermanently(numberDenyPermission: Int)
fun onPermissionGranted()
}
MainClass for permission
class PermissionUtil {
private val PREFS_FILENAME = "permission"
private val TAG = "PermissionUtil"
private fun shouldAskPermission(context: Context, permission: String): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val permissionResult = ActivityCompat.checkSelfPermission(context, permission)
if (permissionResult != PackageManager.PERMISSION_GRANTED) {
return true
}
}
return false
}
fun checkPermission(context: Context, permission: String, listener: PermissionListener) {
Log.i(TAG, "CheckPermission for $permission")
if (shouldAskPermission(context, permission)) {
// Load history permission
val sharedPreference = context.getSharedPreferences(PREFS_FILENAME, 0)
val numberShowPermissionDialog = sharedPreference.getInt(permission, 0)
if (numberShowPermissionDialog == 0) {
(context as? Activity)?.let {
if (ActivityCompat.shouldShowRequestPermissionRationale(it, permission)) {
Log.e(TAG, "User has denied permission but not permanently")
listener.onPermissionPreviouslyDenied(numberShowPermissionDialog)
} else {
Log.e(TAG, "Permission denied permanently.")
listener.onPermissionDisabledPermanently(numberShowPermissionDialog)
}
} ?: kotlin.run {
listener.onNeedPermission()
}
} else {
// Is FirstTime
listener.onNeedPermission()
}
// Save history permission
sharedPreference.edit().putInt(permission, numberShowPermissionDialog + 1).apply()
} else {
listener.onPermissionGranted()
}
}
}
Used by this way
PermissionUtil().checkPermission(this, Manifest.permission.ACCESS_FINE_LOCATION,
object : PermissionListener {
override fun onNeedPermission() {
log("---------------------->onNeedPermission")
// ActivityCompat.requestPermissions(this@SplashActivity,
// Array(1) { Manifest.permission.ACCESS_FINE_LOCATION },
// 118)
}
override fun onPermissionPreviouslyDenied(numberDenyPermission: Int) {
log("---------------------->onPermissionPreviouslyDenied")
}
override fun onPermissionDisabledPermanently(numberDenyPermission: Int) {
log("---------------------->onPermissionDisabled")
}
override fun onPermissionGranted() {
log("---------------------->onPermissionGranted")
}
})
override onRequestPermissionsResult in activity or fragmnet
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
if (requestCode == 118) {
if (permissions[0] == Manifest.permission.ACCESS_FINE_LOCATION && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
getLastLocationInMap()
}
}
}
add a comment |
you can listener pretty.
Listener
interface PermissionListener {
fun onNeedPermission()
fun onPermissionPreviouslyDenied(numberDenyPermission: Int)
fun onPermissionDisabledPermanently(numberDenyPermission: Int)
fun onPermissionGranted()
}
MainClass for permission
class PermissionUtil {
private val PREFS_FILENAME = "permission"
private val TAG = "PermissionUtil"
private fun shouldAskPermission(context: Context, permission: String): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val permissionResult = ActivityCompat.checkSelfPermission(context, permission)
if (permissionResult != PackageManager.PERMISSION_GRANTED) {
return true
}
}
return false
}
fun checkPermission(context: Context, permission: String, listener: PermissionListener) {
Log.i(TAG, "CheckPermission for $permission")
if (shouldAskPermission(context, permission)) {
// Load history permission
val sharedPreference = context.getSharedPreferences(PREFS_FILENAME, 0)
val numberShowPermissionDialog = sharedPreference.getInt(permission, 0)
if (numberShowPermissionDialog == 0) {
(context as? Activity)?.let {
if (ActivityCompat.shouldShowRequestPermissionRationale(it, permission)) {
Log.e(TAG, "User has denied permission but not permanently")
listener.onPermissionPreviouslyDenied(numberShowPermissionDialog)
} else {
Log.e(TAG, "Permission denied permanently.")
listener.onPermissionDisabledPermanently(numberShowPermissionDialog)
}
} ?: kotlin.run {
listener.onNeedPermission()
}
} else {
// Is FirstTime
listener.onNeedPermission()
}
// Save history permission
sharedPreference.edit().putInt(permission, numberShowPermissionDialog + 1).apply()
} else {
listener.onPermissionGranted()
}
}
}
Used by this way
PermissionUtil().checkPermission(this, Manifest.permission.ACCESS_FINE_LOCATION,
object : PermissionListener {
override fun onNeedPermission() {
log("---------------------->onNeedPermission")
// ActivityCompat.requestPermissions(this@SplashActivity,
// Array(1) { Manifest.permission.ACCESS_FINE_LOCATION },
// 118)
}
override fun onPermissionPreviouslyDenied(numberDenyPermission: Int) {
log("---------------------->onPermissionPreviouslyDenied")
}
override fun onPermissionDisabledPermanently(numberDenyPermission: Int) {
log("---------------------->onPermissionDisabled")
}
override fun onPermissionGranted() {
log("---------------------->onPermissionGranted")
}
})
override onRequestPermissionsResult in activity or fragmnet
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
if (requestCode == 118) {
if (permissions[0] == Manifest.permission.ACCESS_FINE_LOCATION && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
getLastLocationInMap()
}
}
}
add a comment |
you can listener pretty.
Listener
interface PermissionListener {
fun onNeedPermission()
fun onPermissionPreviouslyDenied(numberDenyPermission: Int)
fun onPermissionDisabledPermanently(numberDenyPermission: Int)
fun onPermissionGranted()
}
MainClass for permission
class PermissionUtil {
private val PREFS_FILENAME = "permission"
private val TAG = "PermissionUtil"
private fun shouldAskPermission(context: Context, permission: String): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val permissionResult = ActivityCompat.checkSelfPermission(context, permission)
if (permissionResult != PackageManager.PERMISSION_GRANTED) {
return true
}
}
return false
}
fun checkPermission(context: Context, permission: String, listener: PermissionListener) {
Log.i(TAG, "CheckPermission for $permission")
if (shouldAskPermission(context, permission)) {
// Load history permission
val sharedPreference = context.getSharedPreferences(PREFS_FILENAME, 0)
val numberShowPermissionDialog = sharedPreference.getInt(permission, 0)
if (numberShowPermissionDialog == 0) {
(context as? Activity)?.let {
if (ActivityCompat.shouldShowRequestPermissionRationale(it, permission)) {
Log.e(TAG, "User has denied permission but not permanently")
listener.onPermissionPreviouslyDenied(numberShowPermissionDialog)
} else {
Log.e(TAG, "Permission denied permanently.")
listener.onPermissionDisabledPermanently(numberShowPermissionDialog)
}
} ?: kotlin.run {
listener.onNeedPermission()
}
} else {
// Is FirstTime
listener.onNeedPermission()
}
// Save history permission
sharedPreference.edit().putInt(permission, numberShowPermissionDialog + 1).apply()
} else {
listener.onPermissionGranted()
}
}
}
Used by this way
PermissionUtil().checkPermission(this, Manifest.permission.ACCESS_FINE_LOCATION,
object : PermissionListener {
override fun onNeedPermission() {
log("---------------------->onNeedPermission")
// ActivityCompat.requestPermissions(this@SplashActivity,
// Array(1) { Manifest.permission.ACCESS_FINE_LOCATION },
// 118)
}
override fun onPermissionPreviouslyDenied(numberDenyPermission: Int) {
log("---------------------->onPermissionPreviouslyDenied")
}
override fun onPermissionDisabledPermanently(numberDenyPermission: Int) {
log("---------------------->onPermissionDisabled")
}
override fun onPermissionGranted() {
log("---------------------->onPermissionGranted")
}
})
override onRequestPermissionsResult in activity or fragmnet
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
if (requestCode == 118) {
if (permissions[0] == Manifest.permission.ACCESS_FINE_LOCATION && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
getLastLocationInMap()
}
}
}
you can listener pretty.
Listener
interface PermissionListener {
fun onNeedPermission()
fun onPermissionPreviouslyDenied(numberDenyPermission: Int)
fun onPermissionDisabledPermanently(numberDenyPermission: Int)
fun onPermissionGranted()
}
MainClass for permission
class PermissionUtil {
private val PREFS_FILENAME = "permission"
private val TAG = "PermissionUtil"
private fun shouldAskPermission(context: Context, permission: String): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val permissionResult = ActivityCompat.checkSelfPermission(context, permission)
if (permissionResult != PackageManager.PERMISSION_GRANTED) {
return true
}
}
return false
}
fun checkPermission(context: Context, permission: String, listener: PermissionListener) {
Log.i(TAG, "CheckPermission for $permission")
if (shouldAskPermission(context, permission)) {
// Load history permission
val sharedPreference = context.getSharedPreferences(PREFS_FILENAME, 0)
val numberShowPermissionDialog = sharedPreference.getInt(permission, 0)
if (numberShowPermissionDialog == 0) {
(context as? Activity)?.let {
if (ActivityCompat.shouldShowRequestPermissionRationale(it, permission)) {
Log.e(TAG, "User has denied permission but not permanently")
listener.onPermissionPreviouslyDenied(numberShowPermissionDialog)
} else {
Log.e(TAG, "Permission denied permanently.")
listener.onPermissionDisabledPermanently(numberShowPermissionDialog)
}
} ?: kotlin.run {
listener.onNeedPermission()
}
} else {
// Is FirstTime
listener.onNeedPermission()
}
// Save history permission
sharedPreference.edit().putInt(permission, numberShowPermissionDialog + 1).apply()
} else {
listener.onPermissionGranted()
}
}
}
Used by this way
PermissionUtil().checkPermission(this, Manifest.permission.ACCESS_FINE_LOCATION,
object : PermissionListener {
override fun onNeedPermission() {
log("---------------------->onNeedPermission")
// ActivityCompat.requestPermissions(this@SplashActivity,
// Array(1) { Manifest.permission.ACCESS_FINE_LOCATION },
// 118)
}
override fun onPermissionPreviouslyDenied(numberDenyPermission: Int) {
log("---------------------->onPermissionPreviouslyDenied")
}
override fun onPermissionDisabledPermanently(numberDenyPermission: Int) {
log("---------------------->onPermissionDisabled")
}
override fun onPermissionGranted() {
log("---------------------->onPermissionGranted")
}
})
override onRequestPermissionsResult in activity or fragmnet
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
if (requestCode == 118) {
if (permissions[0] == Manifest.permission.ACCESS_FINE_LOCATION && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
getLastLocationInMap()
}
}
}
edited Dec 10 '18 at 10:47
answered Dec 10 '18 at 9:39
Rasoul MiriRasoul Miri
1,6641425
1,6641425
add a comment |
add a comment |
I would also like to obtain the information whether or not the user has selected "never ask again". I have achieved a 'almost solution' with an ugly looking flag, but before I tell you how, I will tell you about my motivation:
I would like to offer the permission referring functionality initially. If the user uses it and has no rights, he/she gets the either the 1th dialog from above or both the 2nd and 3rd. When the user has chosen 'Never ask again' I would like to disable the functionality and to display it differently. - My action is triggered by a spinner text entry, I would also like to add '(Permission revoked)' to the label text displayed. This shows to the user: 'There is functionality but I cannot use it, due to my permission settings.' However, this does not seem to be possible, as I cannot check whether or not 'Never ask again' has been chosen.
I came to a solution I can live with by having my functionality always enabled with an active permission check. I am showing a Toast message in onRequestPermissionsResult() in case of a negative response but only if I have not shown my custom rationale popup. So if the user has chosen 'Never ask again' he gets a toast message only. If the user is reluctant to chose 'never ask again' he gets only the custom rationale and the permission request popup by the operation system but not toast, as three notifications in a row would be too much pain.
add a comment |
I would also like to obtain the information whether or not the user has selected "never ask again". I have achieved a 'almost solution' with an ugly looking flag, but before I tell you how, I will tell you about my motivation:
I would like to offer the permission referring functionality initially. If the user uses it and has no rights, he/she gets the either the 1th dialog from above or both the 2nd and 3rd. When the user has chosen 'Never ask again' I would like to disable the functionality and to display it differently. - My action is triggered by a spinner text entry, I would also like to add '(Permission revoked)' to the label text displayed. This shows to the user: 'There is functionality but I cannot use it, due to my permission settings.' However, this does not seem to be possible, as I cannot check whether or not 'Never ask again' has been chosen.
I came to a solution I can live with by having my functionality always enabled with an active permission check. I am showing a Toast message in onRequestPermissionsResult() in case of a negative response but only if I have not shown my custom rationale popup. So if the user has chosen 'Never ask again' he gets a toast message only. If the user is reluctant to chose 'never ask again' he gets only the custom rationale and the permission request popup by the operation system but not toast, as three notifications in a row would be too much pain.
add a comment |
I would also like to obtain the information whether or not the user has selected "never ask again". I have achieved a 'almost solution' with an ugly looking flag, but before I tell you how, I will tell you about my motivation:
I would like to offer the permission referring functionality initially. If the user uses it and has no rights, he/she gets the either the 1th dialog from above or both the 2nd and 3rd. When the user has chosen 'Never ask again' I would like to disable the functionality and to display it differently. - My action is triggered by a spinner text entry, I would also like to add '(Permission revoked)' to the label text displayed. This shows to the user: 'There is functionality but I cannot use it, due to my permission settings.' However, this does not seem to be possible, as I cannot check whether or not 'Never ask again' has been chosen.
I came to a solution I can live with by having my functionality always enabled with an active permission check. I am showing a Toast message in onRequestPermissionsResult() in case of a negative response but only if I have not shown my custom rationale popup. So if the user has chosen 'Never ask again' he gets a toast message only. If the user is reluctant to chose 'never ask again' he gets only the custom rationale and the permission request popup by the operation system but not toast, as three notifications in a row would be too much pain.
I would also like to obtain the information whether or not the user has selected "never ask again". I have achieved a 'almost solution' with an ugly looking flag, but before I tell you how, I will tell you about my motivation:
I would like to offer the permission referring functionality initially. If the user uses it and has no rights, he/she gets the either the 1th dialog from above or both the 2nd and 3rd. When the user has chosen 'Never ask again' I would like to disable the functionality and to display it differently. - My action is triggered by a spinner text entry, I would also like to add '(Permission revoked)' to the label text displayed. This shows to the user: 'There is functionality but I cannot use it, due to my permission settings.' However, this does not seem to be possible, as I cannot check whether or not 'Never ask again' has been chosen.
I came to a solution I can live with by having my functionality always enabled with an active permission check. I am showing a Toast message in onRequestPermissionsResult() in case of a negative response but only if I have not shown my custom rationale popup. So if the user has chosen 'Never ask again' he gets a toast message only. If the user is reluctant to chose 'never ask again' he gets only the custom rationale and the permission request popup by the operation system but not toast, as three notifications in a row would be too much pain.
answered Oct 6 '15 at 23:00
ChristianKoelleChristianKoelle
165
165
add a comment |
add a comment |
Instead you will receive callback on onRequestPermissionsResult()
as PERMISSION_DENIED when you request permission again while falling in false condition of shouldShowRequestPermissionRationale()
From Android doc:
When the system asks the user to grant a permission, the user has the option of telling the system not to ask for that permission again. In that case, any time an app uses requestPermissions()
to ask for that permission again, the system immediately denies the request. The system calls your onRequestPermissionsResult()
callback method and passes PERMISSION_DENIED
, the same way it would if the user had explicitly rejected your request again. This means that when you call requestPermissions()
, you cannot assume that any direct interaction with the user has taken place.
add a comment |
Instead you will receive callback on onRequestPermissionsResult()
as PERMISSION_DENIED when you request permission again while falling in false condition of shouldShowRequestPermissionRationale()
From Android doc:
When the system asks the user to grant a permission, the user has the option of telling the system not to ask for that permission again. In that case, any time an app uses requestPermissions()
to ask for that permission again, the system immediately denies the request. The system calls your onRequestPermissionsResult()
callback method and passes PERMISSION_DENIED
, the same way it would if the user had explicitly rejected your request again. This means that when you call requestPermissions()
, you cannot assume that any direct interaction with the user has taken place.
add a comment |
Instead you will receive callback on onRequestPermissionsResult()
as PERMISSION_DENIED when you request permission again while falling in false condition of shouldShowRequestPermissionRationale()
From Android doc:
When the system asks the user to grant a permission, the user has the option of telling the system not to ask for that permission again. In that case, any time an app uses requestPermissions()
to ask for that permission again, the system immediately denies the request. The system calls your onRequestPermissionsResult()
callback method and passes PERMISSION_DENIED
, the same way it would if the user had explicitly rejected your request again. This means that when you call requestPermissions()
, you cannot assume that any direct interaction with the user has taken place.
Instead you will receive callback on onRequestPermissionsResult()
as PERMISSION_DENIED when you request permission again while falling in false condition of shouldShowRequestPermissionRationale()
From Android doc:
When the system asks the user to grant a permission, the user has the option of telling the system not to ask for that permission again. In that case, any time an app uses requestPermissions()
to ask for that permission again, the system immediately denies the request. The system calls your onRequestPermissionsResult()
callback method and passes PERMISSION_DENIED
, the same way it would if the user had explicitly rejected your request again. This means that when you call requestPermissions()
, you cannot assume that any direct interaction with the user has taken place.
answered Oct 26 '16 at 10:54
FarhanFarhan
1,2381522
1,2381522
add a comment |
add a comment |
I have to implement dynamic permission for camera. Where 3 possible cases occurs: 1. Allow, 2. Denied, 3. Don't ask again.
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) {
for (String permission : permissions) {
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), permission)) {
//denied
Log.e("denied", permission);
} else {
if (ActivityCompat.checkSelfPermission(getActivity(), permission) == PackageManager.PERMISSION_GRANTED) {
//allowed
Log.e("allowed", permission);
} else {
//set to never ask again
Log.e("set to never ask again", permission);
//do something here.
}
}
}
if (requestCode != MaterialBarcodeScanner.RC_HANDLE_CAMERA_PERM) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
return;
}
if (grantResults.length != 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mScannerView.setResultHandler(this);
mScannerView.startCamera(mCameraId);
mScannerView.setFlash(mFlash);
mScannerView.setAutoFocus(mAutoFocus);
return;
} else {
//set to never ask again
Log.e("set to never ask again", permissions[0]);
}
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Error")
.setMessage(R.string.no_camera_permission)
.setPositiveButton(android.R.string.ok, listener)
.show();
}
private void insertDummyContactWrapper() {
int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.CAMERA);
if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String{Manifest.permission.CAMERA},
REQUEST_CODE_ASK_PERMISSIONS);
return;
}
mScannerView.setResultHandler(this);
mScannerView.startCamera(mCameraId);
mScannerView.setFlash(mFlash);
mScannerView.setAutoFocus(mAutoFocus);
}
private int checkSelfPermission(String camera) {
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
return REQUEST_CODE_ASK_PERMISSIONS;
} else {
return REQUEST_NOT_CODE_ASK_PERMISSIONS;
}
}
add a comment |
I have to implement dynamic permission for camera. Where 3 possible cases occurs: 1. Allow, 2. Denied, 3. Don't ask again.
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) {
for (String permission : permissions) {
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), permission)) {
//denied
Log.e("denied", permission);
} else {
if (ActivityCompat.checkSelfPermission(getActivity(), permission) == PackageManager.PERMISSION_GRANTED) {
//allowed
Log.e("allowed", permission);
} else {
//set to never ask again
Log.e("set to never ask again", permission);
//do something here.
}
}
}
if (requestCode != MaterialBarcodeScanner.RC_HANDLE_CAMERA_PERM) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
return;
}
if (grantResults.length != 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mScannerView.setResultHandler(this);
mScannerView.startCamera(mCameraId);
mScannerView.setFlash(mFlash);
mScannerView.setAutoFocus(mAutoFocus);
return;
} else {
//set to never ask again
Log.e("set to never ask again", permissions[0]);
}
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Error")
.setMessage(R.string.no_camera_permission)
.setPositiveButton(android.R.string.ok, listener)
.show();
}
private void insertDummyContactWrapper() {
int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.CAMERA);
if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String{Manifest.permission.CAMERA},
REQUEST_CODE_ASK_PERMISSIONS);
return;
}
mScannerView.setResultHandler(this);
mScannerView.startCamera(mCameraId);
mScannerView.setFlash(mFlash);
mScannerView.setAutoFocus(mAutoFocus);
}
private int checkSelfPermission(String camera) {
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
return REQUEST_CODE_ASK_PERMISSIONS;
} else {
return REQUEST_NOT_CODE_ASK_PERMISSIONS;
}
}
add a comment |
I have to implement dynamic permission for camera. Where 3 possible cases occurs: 1. Allow, 2. Denied, 3. Don't ask again.
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) {
for (String permission : permissions) {
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), permission)) {
//denied
Log.e("denied", permission);
} else {
if (ActivityCompat.checkSelfPermission(getActivity(), permission) == PackageManager.PERMISSION_GRANTED) {
//allowed
Log.e("allowed", permission);
} else {
//set to never ask again
Log.e("set to never ask again", permission);
//do something here.
}
}
}
if (requestCode != MaterialBarcodeScanner.RC_HANDLE_CAMERA_PERM) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
return;
}
if (grantResults.length != 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mScannerView.setResultHandler(this);
mScannerView.startCamera(mCameraId);
mScannerView.setFlash(mFlash);
mScannerView.setAutoFocus(mAutoFocus);
return;
} else {
//set to never ask again
Log.e("set to never ask again", permissions[0]);
}
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Error")
.setMessage(R.string.no_camera_permission)
.setPositiveButton(android.R.string.ok, listener)
.show();
}
private void insertDummyContactWrapper() {
int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.CAMERA);
if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String{Manifest.permission.CAMERA},
REQUEST_CODE_ASK_PERMISSIONS);
return;
}
mScannerView.setResultHandler(this);
mScannerView.startCamera(mCameraId);
mScannerView.setFlash(mFlash);
mScannerView.setAutoFocus(mAutoFocus);
}
private int checkSelfPermission(String camera) {
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
return REQUEST_CODE_ASK_PERMISSIONS;
} else {
return REQUEST_NOT_CODE_ASK_PERMISSIONS;
}
}
I have to implement dynamic permission for camera. Where 3 possible cases occurs: 1. Allow, 2. Denied, 3. Don't ask again.
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) {
for (String permission : permissions) {
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), permission)) {
//denied
Log.e("denied", permission);
} else {
if (ActivityCompat.checkSelfPermission(getActivity(), permission) == PackageManager.PERMISSION_GRANTED) {
//allowed
Log.e("allowed", permission);
} else {
//set to never ask again
Log.e("set to never ask again", permission);
//do something here.
}
}
}
if (requestCode != MaterialBarcodeScanner.RC_HANDLE_CAMERA_PERM) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
return;
}
if (grantResults.length != 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mScannerView.setResultHandler(this);
mScannerView.startCamera(mCameraId);
mScannerView.setFlash(mFlash);
mScannerView.setAutoFocus(mAutoFocus);
return;
} else {
//set to never ask again
Log.e("set to never ask again", permissions[0]);
}
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Error")
.setMessage(R.string.no_camera_permission)
.setPositiveButton(android.R.string.ok, listener)
.show();
}
private void insertDummyContactWrapper() {
int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.CAMERA);
if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String{Manifest.permission.CAMERA},
REQUEST_CODE_ASK_PERMISSIONS);
return;
}
mScannerView.setResultHandler(this);
mScannerView.startCamera(mCameraId);
mScannerView.setFlash(mFlash);
mScannerView.setAutoFocus(mAutoFocus);
}
private int checkSelfPermission(String camera) {
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
return REQUEST_CODE_ASK_PERMISSIONS;
} else {
return REQUEST_NOT_CODE_ASK_PERMISSIONS;
}
}
edited Apr 4 '17 at 12:25
Federico Navarrete
1,07431832
1,07431832
answered Mar 21 '17 at 9:59
hitesh141hitesh141
8221024
8221024
add a comment |
add a comment |
You can use if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)
method to detect whether never ask is checked or not.
For more reference : Check this
To check for multiple permissions use:
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)
|| ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|| ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)
|| ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) {
showDialogOK("Service Permissions are required for this app",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
checkAndRequestPermissions();
break;
case DialogInterface.BUTTON_NEGATIVE:
// proceed with logic by disabling the related features or quit the app.
finish();
break;
}
}
});
}
//permission is denied (and never ask again is checked)
//shouldShowRequestPermissionRationale will return false
else {
explain("You need to give some mandatory permissions to continue. Do you want to go to app settings?");
// //proceed with logic by disabling the related features or quit the app.
}
explain() method
private void explain(String msg){
final android.support.v7.app.AlertDialog.Builder dialog = new android.support.v7.app.AlertDialog.Builder(this);
dialog.setMessage(msg)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
// permissionsclass.requestPermission(type,code);
startActivity(new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:com.exampledemo.parsaniahardik.marshmallowpermission")));
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
finish();
}
});
dialog.show();
}
Above code will also show dialog, which will redirect user to app settings screen from where he can give permission if had checked never ask again button.
add a comment |
You can use if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)
method to detect whether never ask is checked or not.
For more reference : Check this
To check for multiple permissions use:
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)
|| ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|| ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)
|| ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) {
showDialogOK("Service Permissions are required for this app",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
checkAndRequestPermissions();
break;
case DialogInterface.BUTTON_NEGATIVE:
// proceed with logic by disabling the related features or quit the app.
finish();
break;
}
}
});
}
//permission is denied (and never ask again is checked)
//shouldShowRequestPermissionRationale will return false
else {
explain("You need to give some mandatory permissions to continue. Do you want to go to app settings?");
// //proceed with logic by disabling the related features or quit the app.
}
explain() method
private void explain(String msg){
final android.support.v7.app.AlertDialog.Builder dialog = new android.support.v7.app.AlertDialog.Builder(this);
dialog.setMessage(msg)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
// permissionsclass.requestPermission(type,code);
startActivity(new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:com.exampledemo.parsaniahardik.marshmallowpermission")));
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
finish();
}
});
dialog.show();
}
Above code will also show dialog, which will redirect user to app settings screen from where he can give permission if had checked never ask again button.
add a comment |
You can use if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)
method to detect whether never ask is checked or not.
For more reference : Check this
To check for multiple permissions use:
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)
|| ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|| ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)
|| ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) {
showDialogOK("Service Permissions are required for this app",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
checkAndRequestPermissions();
break;
case DialogInterface.BUTTON_NEGATIVE:
// proceed with logic by disabling the related features or quit the app.
finish();
break;
}
}
});
}
//permission is denied (and never ask again is checked)
//shouldShowRequestPermissionRationale will return false
else {
explain("You need to give some mandatory permissions to continue. Do you want to go to app settings?");
// //proceed with logic by disabling the related features or quit the app.
}
explain() method
private void explain(String msg){
final android.support.v7.app.AlertDialog.Builder dialog = new android.support.v7.app.AlertDialog.Builder(this);
dialog.setMessage(msg)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
// permissionsclass.requestPermission(type,code);
startActivity(new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:com.exampledemo.parsaniahardik.marshmallowpermission")));
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
finish();
}
});
dialog.show();
}
Above code will also show dialog, which will redirect user to app settings screen from where he can give permission if had checked never ask again button.
You can use if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)
method to detect whether never ask is checked or not.
For more reference : Check this
To check for multiple permissions use:
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)
|| ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|| ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)
|| ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) {
showDialogOK("Service Permissions are required for this app",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
checkAndRequestPermissions();
break;
case DialogInterface.BUTTON_NEGATIVE:
// proceed with logic by disabling the related features or quit the app.
finish();
break;
}
}
});
}
//permission is denied (and never ask again is checked)
//shouldShowRequestPermissionRationale will return false
else {
explain("You need to give some mandatory permissions to continue. Do you want to go to app settings?");
// //proceed with logic by disabling the related features or quit the app.
}
explain() method
private void explain(String msg){
final android.support.v7.app.AlertDialog.Builder dialog = new android.support.v7.app.AlertDialog.Builder(this);
dialog.setMessage(msg)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
// permissionsclass.requestPermission(type,code);
startActivity(new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:com.exampledemo.parsaniahardik.marshmallowpermission")));
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
finish();
}
});
dialog.show();
}
Above code will also show dialog, which will redirect user to app settings screen from where he can give permission if had checked never ask again button.
edited Apr 15 '17 at 6:38
answered Mar 2 '17 at 8:00
user6435056user6435056
42734
42734
add a comment |
add a comment |
Expanding on mVck's answer above, the following logic determines whether "Never ask again" has been checked for a given Permission Request:
bool bStorage = grantResults[0] == Permission.Granted;
bool bNeverAskForStorage =
!bStorage && (
_bStorageRationaleBefore == true && _bStorageRationaleAfter == false ||
_bStorageRationaleBefore == false && _bStorageRationaleAfter == false
);
which is excerpted from below (for the full example see this answer)
private bool _bStorageRationaleBefore;
private bool _bStorageRationaleAfter;
private const int ANDROID_PERMISSION_REQUEST_CODE__SDCARD = 2;
//private const int ANDROID_PERMISSION_REQUEST_CODE__CAMERA = 1;
private const int ANDROID_PERMISSION_REQUEST_CODE__NONE = 0;
public override void OnRequestPermissionsResult(int requestCode, string permissions, [GeneratedEnum] Permission grantResults)
{
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode)
{
case ANDROID_PERMISSION_REQUEST_CODE__SDCARD:
_bStorageRationaleAfter = ShouldShowRequestPermissionRationale(Android.Manifest.Permission.WriteExternalStorage);
bool bStorage = grantResults[0] == Permission.Granted;
bool bNeverAskForStorage =
!bStorage && (
_bStorageRationaleBefore == true && _bStorageRationaleAfter == false ||
_bStorageRationaleBefore == false && _bStorageRationaleAfter == false
);
break;
}
}
private List<string> GetRequiredPermissions(out int requestCode)
{
// Android v6 requires explicit permission granting from user at runtime for security reasons
requestCode = ANDROID_PERMISSION_REQUEST_CODE__NONE; // 0
List<string> requiredPermissions = new List<string>();
_bStorageRationaleBefore = ShouldShowRequestPermissionRationale(Android.Manifest.Permission.WriteExternalStorage);
Permission writeExternalStoragePerm = ApplicationContext.CheckSelfPermission(Android.Manifest.Permission.WriteExternalStorage);
//if(extStoragePerm == Permission.Denied)
if (writeExternalStoragePerm != Permission.Granted)
{
requestCode |= ANDROID_PERMISSION_REQUEST_CODE__SDCARD;
requiredPermissions.Add(Android.Manifest.Permission.WriteExternalStorage);
}
return requiredPermissions;
}
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Android v6 requires explicit permission granting from user at runtime for security reasons
int requestCode;
List<string> requiredPermissions = GetRequiredPermissions(out requestCode);
if (requiredPermissions != null && requiredPermissions.Count > 0)
{
if (requestCode >= ANDROID_PERMISSION_REQUEST_CODE__SDCARD)
{
_savedInstanceState = savedInstanceState;
RequestPermissions(requiredPermissions.ToArray(), requestCode);
return;
}
}
}
OnCreate2(savedInstanceState);
}
add a comment |
Expanding on mVck's answer above, the following logic determines whether "Never ask again" has been checked for a given Permission Request:
bool bStorage = grantResults[0] == Permission.Granted;
bool bNeverAskForStorage =
!bStorage && (
_bStorageRationaleBefore == true && _bStorageRationaleAfter == false ||
_bStorageRationaleBefore == false && _bStorageRationaleAfter == false
);
which is excerpted from below (for the full example see this answer)
private bool _bStorageRationaleBefore;
private bool _bStorageRationaleAfter;
private const int ANDROID_PERMISSION_REQUEST_CODE__SDCARD = 2;
//private const int ANDROID_PERMISSION_REQUEST_CODE__CAMERA = 1;
private const int ANDROID_PERMISSION_REQUEST_CODE__NONE = 0;
public override void OnRequestPermissionsResult(int requestCode, string permissions, [GeneratedEnum] Permission grantResults)
{
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode)
{
case ANDROID_PERMISSION_REQUEST_CODE__SDCARD:
_bStorageRationaleAfter = ShouldShowRequestPermissionRationale(Android.Manifest.Permission.WriteExternalStorage);
bool bStorage = grantResults[0] == Permission.Granted;
bool bNeverAskForStorage =
!bStorage && (
_bStorageRationaleBefore == true && _bStorageRationaleAfter == false ||
_bStorageRationaleBefore == false && _bStorageRationaleAfter == false
);
break;
}
}
private List<string> GetRequiredPermissions(out int requestCode)
{
// Android v6 requires explicit permission granting from user at runtime for security reasons
requestCode = ANDROID_PERMISSION_REQUEST_CODE__NONE; // 0
List<string> requiredPermissions = new List<string>();
_bStorageRationaleBefore = ShouldShowRequestPermissionRationale(Android.Manifest.Permission.WriteExternalStorage);
Permission writeExternalStoragePerm = ApplicationContext.CheckSelfPermission(Android.Manifest.Permission.WriteExternalStorage);
//if(extStoragePerm == Permission.Denied)
if (writeExternalStoragePerm != Permission.Granted)
{
requestCode |= ANDROID_PERMISSION_REQUEST_CODE__SDCARD;
requiredPermissions.Add(Android.Manifest.Permission.WriteExternalStorage);
}
return requiredPermissions;
}
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Android v6 requires explicit permission granting from user at runtime for security reasons
int requestCode;
List<string> requiredPermissions = GetRequiredPermissions(out requestCode);
if (requiredPermissions != null && requiredPermissions.Count > 0)
{
if (requestCode >= ANDROID_PERMISSION_REQUEST_CODE__SDCARD)
{
_savedInstanceState = savedInstanceState;
RequestPermissions(requiredPermissions.ToArray(), requestCode);
return;
}
}
}
OnCreate2(savedInstanceState);
}
add a comment |
Expanding on mVck's answer above, the following logic determines whether "Never ask again" has been checked for a given Permission Request:
bool bStorage = grantResults[0] == Permission.Granted;
bool bNeverAskForStorage =
!bStorage && (
_bStorageRationaleBefore == true && _bStorageRationaleAfter == false ||
_bStorageRationaleBefore == false && _bStorageRationaleAfter == false
);
which is excerpted from below (for the full example see this answer)
private bool _bStorageRationaleBefore;
private bool _bStorageRationaleAfter;
private const int ANDROID_PERMISSION_REQUEST_CODE__SDCARD = 2;
//private const int ANDROID_PERMISSION_REQUEST_CODE__CAMERA = 1;
private const int ANDROID_PERMISSION_REQUEST_CODE__NONE = 0;
public override void OnRequestPermissionsResult(int requestCode, string permissions, [GeneratedEnum] Permission grantResults)
{
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode)
{
case ANDROID_PERMISSION_REQUEST_CODE__SDCARD:
_bStorageRationaleAfter = ShouldShowRequestPermissionRationale(Android.Manifest.Permission.WriteExternalStorage);
bool bStorage = grantResults[0] == Permission.Granted;
bool bNeverAskForStorage =
!bStorage && (
_bStorageRationaleBefore == true && _bStorageRationaleAfter == false ||
_bStorageRationaleBefore == false && _bStorageRationaleAfter == false
);
break;
}
}
private List<string> GetRequiredPermissions(out int requestCode)
{
// Android v6 requires explicit permission granting from user at runtime for security reasons
requestCode = ANDROID_PERMISSION_REQUEST_CODE__NONE; // 0
List<string> requiredPermissions = new List<string>();
_bStorageRationaleBefore = ShouldShowRequestPermissionRationale(Android.Manifest.Permission.WriteExternalStorage);
Permission writeExternalStoragePerm = ApplicationContext.CheckSelfPermission(Android.Manifest.Permission.WriteExternalStorage);
//if(extStoragePerm == Permission.Denied)
if (writeExternalStoragePerm != Permission.Granted)
{
requestCode |= ANDROID_PERMISSION_REQUEST_CODE__SDCARD;
requiredPermissions.Add(Android.Manifest.Permission.WriteExternalStorage);
}
return requiredPermissions;
}
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Android v6 requires explicit permission granting from user at runtime for security reasons
int requestCode;
List<string> requiredPermissions = GetRequiredPermissions(out requestCode);
if (requiredPermissions != null && requiredPermissions.Count > 0)
{
if (requestCode >= ANDROID_PERMISSION_REQUEST_CODE__SDCARD)
{
_savedInstanceState = savedInstanceState;
RequestPermissions(requiredPermissions.ToArray(), requestCode);
return;
}
}
}
OnCreate2(savedInstanceState);
}
Expanding on mVck's answer above, the following logic determines whether "Never ask again" has been checked for a given Permission Request:
bool bStorage = grantResults[0] == Permission.Granted;
bool bNeverAskForStorage =
!bStorage && (
_bStorageRationaleBefore == true && _bStorageRationaleAfter == false ||
_bStorageRationaleBefore == false && _bStorageRationaleAfter == false
);
which is excerpted from below (for the full example see this answer)
private bool _bStorageRationaleBefore;
private bool _bStorageRationaleAfter;
private const int ANDROID_PERMISSION_REQUEST_CODE__SDCARD = 2;
//private const int ANDROID_PERMISSION_REQUEST_CODE__CAMERA = 1;
private const int ANDROID_PERMISSION_REQUEST_CODE__NONE = 0;
public override void OnRequestPermissionsResult(int requestCode, string permissions, [GeneratedEnum] Permission grantResults)
{
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode)
{
case ANDROID_PERMISSION_REQUEST_CODE__SDCARD:
_bStorageRationaleAfter = ShouldShowRequestPermissionRationale(Android.Manifest.Permission.WriteExternalStorage);
bool bStorage = grantResults[0] == Permission.Granted;
bool bNeverAskForStorage =
!bStorage && (
_bStorageRationaleBefore == true && _bStorageRationaleAfter == false ||
_bStorageRationaleBefore == false && _bStorageRationaleAfter == false
);
break;
}
}
private List<string> GetRequiredPermissions(out int requestCode)
{
// Android v6 requires explicit permission granting from user at runtime for security reasons
requestCode = ANDROID_PERMISSION_REQUEST_CODE__NONE; // 0
List<string> requiredPermissions = new List<string>();
_bStorageRationaleBefore = ShouldShowRequestPermissionRationale(Android.Manifest.Permission.WriteExternalStorage);
Permission writeExternalStoragePerm = ApplicationContext.CheckSelfPermission(Android.Manifest.Permission.WriteExternalStorage);
//if(extStoragePerm == Permission.Denied)
if (writeExternalStoragePerm != Permission.Granted)
{
requestCode |= ANDROID_PERMISSION_REQUEST_CODE__SDCARD;
requiredPermissions.Add(Android.Manifest.Permission.WriteExternalStorage);
}
return requiredPermissions;
}
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Android v6 requires explicit permission granting from user at runtime for security reasons
int requestCode;
List<string> requiredPermissions = GetRequiredPermissions(out requestCode);
if (requiredPermissions != null && requiredPermissions.Count > 0)
{
if (requestCode >= ANDROID_PERMISSION_REQUEST_CODE__SDCARD)
{
_savedInstanceState = savedInstanceState;
RequestPermissions(requiredPermissions.ToArray(), requestCode);
return;
}
}
}
OnCreate2(savedInstanceState);
}
edited Jul 26 '17 at 12:50
answered Jul 26 '17 at 12:44
samissamis
3,46862151
3,46862151
add a comment |
add a comment |
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) {
switch (requestCode) {
case PERMISSIONS_REQUEST_EXTERNAL_STORAGE: {
if (grantResults.length > 0) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// Denied
} else {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
// To what you want
} else {
// Bob never checked click
}
}
}
}
}
}
add a comment |
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) {
switch (requestCode) {
case PERMISSIONS_REQUEST_EXTERNAL_STORAGE: {
if (grantResults.length > 0) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// Denied
} else {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
// To what you want
} else {
// Bob never checked click
}
}
}
}
}
}
add a comment |
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) {
switch (requestCode) {
case PERMISSIONS_REQUEST_EXTERNAL_STORAGE: {
if (grantResults.length > 0) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// Denied
} else {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
// To what you want
} else {
// Bob never checked click
}
}
}
}
}
}
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults) {
switch (requestCode) {
case PERMISSIONS_REQUEST_EXTERNAL_STORAGE: {
if (grantResults.length > 0) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// Denied
} else {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
// To what you want
} else {
// Bob never checked click
}
}
}
}
}
}
edited Oct 15 '17 at 21:05
Axe
4,84832237
4,84832237
answered Apr 4 '17 at 11:27
Vinod RangaVinod Ranga
354510
354510
add a comment |
add a comment |
you can read android official document
Request App Permissions
or you can find many popular android permission libraries on Github
- PermissionsDispatcher
- RxPermissions
- easypermissions
add a comment |
you can read android official document
Request App Permissions
or you can find many popular android permission libraries on Github
- PermissionsDispatcher
- RxPermissions
- easypermissions
add a comment |
you can read android official document
Request App Permissions
or you can find many popular android permission libraries on Github
- PermissionsDispatcher
- RxPermissions
- easypermissions
you can read android official document
Request App Permissions
or you can find many popular android permission libraries on Github
- PermissionsDispatcher
- RxPermissions
- easypermissions
answered Jan 20 at 3:39
shellhubshellhub
82369
82369
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f30719047%2fandroid-m-check-runtime-permission-how-to-determine-if-the-user-checked-nev%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
7
"does Google have plans to incorporate a custom message in the permission dialog that would explain why the app needs the permission?" -- in the Google I|O presentation about the M permission system, I seem to recall somebody asked in the Q&A, and the answer was that they're thinking about it.
– CommonsWare
Jun 8 '15 at 21:19
1
Didn't test it myself, but documentation say about Activity.shouldShowRequestPermissionRationale(String) : This method returns true if the app has requested this permission previously and the user denied the request. That indicates that you should probably explain to the user why you need the permission. 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. The method also returns false if the device policy prohibits the app from having that permission.
– Fraid
Jul 17 '15 at 13:45
1
@Fraid: looks like they added this with preview #2 of Android M: developer.android.com/preview/support.html#preview2-notes and it's probably what I was looking for. I can't test it right now but will do so next week. If it does what I hope it does, you can post it as an answer and get some reputation. In the meantime this might help others: youtube.com/watch?v=f17qe9vZ8RM
– Emanuel Moecklin
Jul 21 '15 at 16:16
example of Dangerous Permissions and Special Permissions: github.com/henrychuangtw/AndroidRuntimePermission
– HenryChuang
May 25 '16 at 6:52
I don't like this whole permission thingy. Made it more confusing
– Alex
Jul 22 '16 at 20:10