12

Such a new and awesome security functionality is RUN-TIME Permission

I am trying to understand it and make one demo for that But one question raise in my mind that when i am at handle user permission with DIALOG.

How to handle "Never ask Again"

enter image description here

Suppose my application MUST need Location/contact but user DENY it with "NEVER ASK AGAIN".

What can i do for that. Not all User understand my field is required.

ANY SUGGESTION?

Pratik Butani
  • 60,504
  • 58
  • 273
  • 437
Vishal Patel
  • 2,931
  • 3
  • 24
  • 60

4 Answers4

5

First you need to implement OnRequestPermissionsResultCallback Listener of ActivityCompat class in your Activity and override void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) Method to check whether User is allowing or denying the permission

You can do like this. Here i check for permission access for WRITE_EXTERNAL_STORAGE:

int REQUEST_STORAGE = 1;

private void checkPermissions() {
    if (hasStoragePermissionGranted()) {
        // you can do whatever you want
    } else {
        requestPermission();
    }
}

public boolean hasPermissionGranted(){
        return  ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
}

public void requestPermission() {
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
        ActivityCompat.requestPermissions(MainActivity.this, {Manifest.permission.WRITE_EXTERNAL_STORAGE},
                REQUEST_STORAGE);
    }
}

Here is onRequestPermissionsResult() method will be called when user allow or deny Permission from Runtime permission dialog.

You can also handle situation when User has checked never show Runtime Permission dialog for that you can show Snackbar or button to redirect user to your application settings page as you can not show permission dialog after user has checked "Never ask again".

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

        if (requestCode == REQUEST_STORAGE) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
               //Storage permission is enabled
               canSendAttachments = true;
               systemLogsCheckbox.setEnabled(true);
            } else if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivtity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                //User has deny from permission dialog
                Snackbar.make(mainLayout, getResources().getString("Please enable storage permission"),
                        Snackbar.LENGTH_INDEFINITE)
                        .setAction("OK", new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                ActivityCompat.requestPermissions(MainActivity.this, {Manifest.permission.WRITE_EXTERNAL_STORAGE},
                REQUEST_STORAGE);
                            }
                        })
                        .show();
            } else {
                // User has deny permission and checked never show permission dialog so you can redirect to Application settings page
                Snackbar.make(mainLayout, getResources().getString("Please enable permission from settings"),
                        Snackbar.LENGTH_INDEFINITE)
                        .setAction("OK", new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                Intent intent = new Intent();
                                intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                Uri uri = Uri.fromParts("package", MainActivity.this.getPackageName(), null);
                                intent.setData(uri);
                                startActivity(intent);
                            }
                        })
                        .show();
            }
        }
    }

Here i have used Snackbar to show relevant message to user about Permission and mainLayout is id of Activity's Main Layout.

Hope it helps you.

Rajesh Jadav
  • 12,801
  • 5
  • 53
  • 78
  • tx for suggestion, i am already implement it , but what i am say that suppose user click deny but my app must required location than what can i do?? how to Convince user ? – Vishal Patel Jan 11 '16 at 09:06
  • You give explanation to user why this permission is required by app. you also give situation that what happens if user not allowed permission – Rajesh Jadav Jan 11 '16 at 09:09
  • 1
    @VishalPatel yes app will not work if permission is must needed – Rajesh Jadav Jan 11 '16 at 09:13
  • 1
    @VishalPatel If the user selects 'never ask again' your permission has been denied permanently and it can only be enabled through android settings. If the permission is key for you app, I'd suggest you use 'priming' messages prior asking the permission. You could show a priming dialog (or full screen view) to make the user aware why you need the permission and what happens to the app functionality if it's not granted. After that you can request the permission. Take a look at this library https://github.com/aitorvs/allowme that implements also simple priming dialogs. – Aitor Viana Jan 11 '16 at 10:11
  • I have created library for it. It is easy to use by simple steps. https://github.com/Kishanjvaghela/Ask-Permission – Kishan Vaghela Dec 01 '16 at 17:24
2

I have created a library that handle all the permissions for you. you can find it in here:

PermissionHelper


To answer your question:

in order for you to know if the user checked never show again you'll have to check against two things, if the permission is declined and no explanation needed if these two returned **true** that means that the permission is no longer available to be asked again and the only solution to handle this case is to open the settings screen.

P.S: the library i created handle all these kind of scenarios for you and returns callbacks for you to decide what to do next!. the library has two implementations

  1. Manual implementation (which mean you'll have to implement the callback in your activity and listen to the returned callback from the library).
  2. Let the library request the permission for you and it'll as well return you a callback to let you decide what happens when the permission is permanently denied.
Kosh
  • 6,140
  • 3
  • 36
  • 67
1

open your app setting when user chose "Nerver ask again"

Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, REQUEST_PERMISSION_SETTING);

my example to handle RuntimePermission:
https://github.com/henrychuangtw/RuntimePermission

HenryChuang
  • 1,449
  • 17
  • 28
0

Use Dexter library

or

Use PermissionsDispatcher:

Step 1 : use PermissionsDispatcher library by hotchemi (the library is annotation based, simple to use and well documented)

Step 2 : you have to provide 4 annotated methods and one of them is @OnNeverAskAgain(Manifest.permission.[permission_you_want]) as below

@OnNeverAskAgain(Manifest.permission.[permission_you_want])
void showNeverAsk() {  
   // handle here
}  

Here is sample

MD TAREQ HASSAN
  • 1,188
  • 20
  • 46