Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run-time permission of Marshmallow

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?

like image 419
Vishal Patel Avatar asked Jan 11 '16 08:01

Vishal Patel


People also ask

What are runtime permissions?

Runtime permissions cover areas where the app wants data or resources that involve the user's private information, or could potentially affect the user's stored data or the operation of other applications. For example, the ability to read the user's contacts, external storage, or location are runtime permissions.

How do I request runtime permission?

Requesting Android Runtime Permissions For this the following method needs to be called on every permission. checkSelfPermission(String perm); It returns an integer value of PERMISSION_GRANTED or PERMISSION_DENIED.

Which Android introduced the runtime permission?

Android 6.0 Marshmallow (SDK level 23) introduced the concept of Runtime Permissions, changing many aspects of managing them in Android.

How do I get runtime permission in Android 11?

Starting in Android 11, whenever your app requests a permission related to location, microphone, or camera, the user-facing permissions dialog contains an option called Only this time. If the user selects this option in the dialog, your app is granted a temporary one-time permission.


2 Answers

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.

like image 110
Rajesh Avatar answered Oct 09 '22 02:10

Rajesh


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.
like image 34
Kosh Avatar answered Oct 09 '22 03:10

Kosh