[android] How to check the multiple permission at single request in Android M?

I want to use the

  1. android.permission.CAMERA
  2. android.permission.WRITE_EXTERNAL_STORAGE

in single request using

ActivityCompat.requestPermissions(Activity activity,new String permisionList[],int permissionRequestcode);

But my problem is at time I request only one permission, I read about group-permission,But it's work for only Same group which one decided by Developer, Like CONTACT_GROUP : read_contact,write_contact etc.

I want create the custom group permission which ask me only one request & provide me only one response.

Thanks

The answer is


Based on what i've searched, i think this is the best answers that i've found out Android 6.0 multiple permissions


For multiple permission you can use this code :

final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124;

private void insertDummyContactWrapper() {
    List<String> permissionsNeeded = new ArrayList<String>();

    final List<String> permissionsList = new ArrayList<String>();
    if (!addPermission(permissionsList, Manifest.permission.ACCESS_FINE_LOCATION))
        permissionsNeeded.add("GPS");
    if (!addPermission(permissionsList, Manifest.permission.READ_CONTACTS))
        permissionsNeeded.add("Read Contacts");
    if (!addPermission(permissionsList, Manifest.permission.WRITE_CONTACTS))
        permissionsNeeded.add("Write Contacts");

    if (permissionsList.size() > 0) {
        if (permissionsNeeded.size() > 0) {
            // Need Rationale
            String message = "You need to grant access to " + permissionsNeeded.get(0);
            for (int i = 1; i < permissionsNeeded.size(); i++)
                message = message + ", " + permissionsNeeded.get(i);
            showMessageOKCancel(message,
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
                                    REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
                        }
                    });
            return;
        }
        requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
                REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
        return;
    }

    insertDummyContact();
}

private boolean addPermission(List<String> permissionsList, String permission) {
    if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
        permissionsList.add(permission);
        // Check for Rationale Option
        if (!shouldShowRequestPermissionRationale(permission))
            return false;
    }
    return true;
}

For Asking Multiple Permission At Once You Can Use this Method link

compile 'com.kishan.askpermission:askpermission:1.0.3'

If you got conflicting in support library then

compile('com.kishan.askpermission:askpermission:1.0.3', {
    exclude group: 'com.android.support'
})

Now ask for Permission

new AskPermission.Builder(this)
    .setPermissions(Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_EXTERNAL_STORAGE)
    .setCallback(/* PermissionCallback */)
    .setErrorCallback(/* ErrorCallback */)
    .request(/* Request Code */);

permission granted callback

  public void onPermissionsGranted(int requestCode) {
// your code  }

permission denied callback

 public void onPermissionsDenied(int requestCode) {
// your code} 

ErrorCallbacks

public void onShowRationalDialog(PermissionInterface permissionInterface, int requestCode) {
// Alert user by Dialog or any other layout that you want.
// When user press OK you must need to call below method.
permissionInterface.onDialogShown();

}

public void onShowSettings(PermissionInterface permissionInterface, int requestCode) {
// Alert user by Dialog or any other layout that you want.
// When user press OK you must need to call below method.
// It will open setting screen.
permissionInterface.onSettingsShown();

}


I am late, but i want tell the library which i have ended with.

RxPermission is best library with reactive code, which makes permission code unexpected just 1 line.

RxPermissions rxPermissions = new RxPermissions(this);
rxPermissions
.request(Manifest.permission.CAMERA,
         Manifest.permission.READ_PHONE_STATE)
.subscribe(granted -> {
    if (granted) {
       // All requested permissions are granted
    } else {
       // At least one permission is denied
    }
});

add in your build.gradle

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

dependencies {
    implementation 'com.github.tbruyelle:rxpermissions:0.10.1'
    implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1'
}

Based on vedval i have this solution.

public boolean checkForPermission(final String[] permissions, final int permRequestCode) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        return true;
    }
    final List<String> permissionsNeeded = new ArrayList<>();
    for (int i = 0; i < permissions.length; i++) {
        final String perm = permissions[i];
        if (ContextCompat.checkSelfPermission(this, permissions[i]) != PackageManager.PERMISSION_GRANTED) {
            if (shouldShowRequestPermissionRationale(permissions[i])) {
                Snackbar.make(phrase, R.string.permission_location, Snackbar.LENGTH_INDEFINITE)
                        .setAction(android.R.string.ok, new View.OnClickListener() {
                            @Override
                            @TargetApi(Build.VERSION_CODES.M)
                            public void onClick(View v) {
                                permissionsNeeded.add(perm);
                            }
                        });
            } else {
                // add the request.
                permissionsNeeded.add(perm);
            }
        }
    }

    if (permissionsNeeded.size() > 0) {
        // go ahead and request permissions
        requestPermissions(permissionsNeeded.toArray(new String[permissionsNeeded.size()]), permRequestCode);
        return false;
    } else {
        // no permission need to be asked so all good...we have them all.
        return true;
    }
}

/**
 * Callback received when a permissions request has been completed.
 */
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {
    if (requestCode == REQUEST_READ_LOCATION) {
        int i = 0;
        for (String permission : permissions ){
            if ( permission.equals(Manifest.permission.ACCESS_FINE_LOCATION) && grantResults.length > 0 && grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                initLocationManager();
            }
            i++;
        }

    }
}

I faced the same problem and below is the workaround I came up with:

public boolean checkForPermission(final String[] permissions, final int permRequestCode, int msgResourceId) {
        final List<String> permissionsNeeded = new ArrayList<>();
        for (int i = 0; i < permissions.length; i++) {
            final String perm = permissions[i];
            if (ContextCompat.checkSelfPermission(getActivity(), permissions[i]) != PackageManager.PERMISSION_GRANTED) {
                if (shouldShowRequestPermissionRationale(permissions[i])) {
                    final AlertDialog dialog = AlertDialog.newInstance( getResources().getString(R.string.permission_title), getResources().getString(msgResourceId) );
                    dialog.setPositiveButton("OK", new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            // add the request.
                            permissionsNeeded.add(perm);
                            dialog.dismiss();
                        }
                    });
                    dialog.show( getActivity().getSupportFragmentManager(), "HCFAlertDialog" );
                } else {
                    // add the request.
                    permissionsNeeded.add(perm);
                }
            }
        }

        if (permissionsNeeded.size() > 0) {
            // go ahead and request permissions
            requestPermissions(permissionsNeeded.toArray(new String[permissionsNeeded.size()]), permRequestCode);
            return false;
        } else {
            // no permission need to be asked so all good...we have them all.
            return true;
        }
    }

And you call the above method like this:

if ( checkForPermission( new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, 
Manifest.permission.CAMERA}, REQUEST_PERMISSION_EXTERNAL_STORAGE_RESULT, R.string.permission_image) ) {
                        // DO YOUR STUFF

                    }

I had the same issue and stumbled on this library.

Basically you can ask for multiple permissions sequentially, plus you can add listeners to popup a snackbar if the user denies your permission.

dexter_sample


Adding generic code for different types of permissions. Copy-paste with minor changes. Read the "TODO" comments in the code below.

Make the following Activity your Launcher Activity:

public class PermissionReqActivity extends AppCompatActivity {

    private static final int CODE_WRITE_SETTINGS_PERMISSION = 332;
    private static String[] PERMISSIONS_ALL = {Manifest.permission.WRITE_EXTERNAL_STORAGE}; //TODO You can Add multiple permissions here.
    private static final int PERMISSION_REQUEST_CODE = 223;
    private Context context;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_permission_req);
        context = this;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

            boolean allPermissionsGranted = true;
            ArrayList<String> toReqPermissions = new ArrayList<>();

            for (String permission : PERMISSIONS_ALL) {
                if (ActivityCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
                    toReqPermissions.add(permission);

                    allPermissionsGranted = false;
                }
            }
            if (allPermissionsGranted)
                //TODO Now some permissions are very special and require Settings Activity to launch, as u might have seen in some apps. handleWriteSettingsPermission() is an example for WRITE_SETTINGS permission. If u don't need very special permission(s), replace handleWriteSettingsPermission() with initActivity().
                handleWriteSettingsPermission();
            else
                ActivityCompat.requestPermissions(this,
                        toReqPermissions.toArray(new String[toReqPermissions.size()]), PERMISSION_REQUEST_CODE);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == PERMISSION_REQUEST_CODE) {
            boolean allPermGranted = true;
            for (int i = 0; i < grantResults.length; i++) {
                if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(this, "Permissions not granted: " + permissions[i], Toast.LENGTH_LONG).show();
                    allPermGranted = false;
                    finish();
                    break;
                }
            }
            if (allPermGranted)
                handleWriteSettingsPermission();//TODO As mentioned above, use initActivity() here if u dont need very special permission WRITE_SETTINGS
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    private void handleWriteSettingsPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (Settings.System.canWrite(context)) {
                initActivity();
            } else {
                Toast.makeText(this, "Please Enable this permission for " +
                        getApplicationInfo().loadLabel(getPackageManager()).toString(), Toast.LENGTH_LONG).show();
                Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
                intent.setData(Uri.parse("package:" + context.getPackageName()));
                startActivityForResult(intent, CODE_WRITE_SETTINGS_PERMISSION);
            }
        }
    }

//TODO You don't need the following onActivityResult() function if u dont need very special permissions.

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && requestCode == CODE_WRITE_SETTINGS_PERMISSION) {
            if (Settings.System.canWrite(this))
                initActivity();
            else {
                Toast.makeText(this, "Permissions not granted: " + Manifest.permission.WRITE_SETTINGS, Toast.LENGTH_LONG).show();
                finish();
            }
        }
    }

    private void initActivity() {
        startActivity(new Intent(this, MainActivity.class));
    }
}

There is no hack available at this stage to circumvent asking for permissions from different groups together. That is the nature of how android has developed runtime permissions, to give users a choice of which permissions to accept. Of course not accepting all permissions required by an app, may make the app fail to work properly.

CAMERA and WRITE_EXTERNAL_STORAGE are both regarded as dangerous permissions, and in separate groups, thus both requiring a runtime permission request.

Once permission is granted for a particular group, it does not need to be requested again for the lifetime of the app run, or until it is revoked if given as a default setting.

enter image description here

enter image description here

The only thing you can do is ask the user to accept the decisions as default, which can be revoked, by using "never ask again"

enter image description here


check More than one Permission and Request if Not Granted

 public void checkPermissions(){
    if(ContextCompat.checkSelfPermission(getApplicationContext(),
            Manifest.permission.WRITE_EXTERNAL_STORAGE)== PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(getApplicationContext(),Manifest.permission.CAMERA)==PackageManager.PERMISSION_GRANTED){
        //Do_SOme_Operation();
    }else{
        requestStoragePermission();
    }
}

public void requestStoragePermission(){
    ActivityCompat.requestPermissions(this
            ,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.CAMERA},1234);
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode){
        case 1234:if(grantResults[0]==PackageManager.PERMISSION_GRANTED && grantResults[1]==PackageManager.PERMISSION_GRANTED){
  // Do_SOme_Operation();
        }

        default:super.onRequestPermissionsResult(requestCode,permissions,grantResults);
    }
}

       // **For multiple permission you can use this code :**

       // **First:**
//Write down in onCreate method.

         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    requestPermissions(new String[]{
                                    android.Manifest.permission.READ_EXTERNAL_STORAGE,
                                    android.Manifest.permission.CAMERA},
                            MY_PERMISSIONS_REQUEST);

         }

        //**Second:**
    //Write down in a activity.
     @Override
        public void onRequestPermissionsResult(int requestCode,
                                               String permissions[], int[] grantResults) {
            switch (requestCode) {
                case MY_PERMISSIONS_REQUEST:

                    if (grantResults.length > 0
                            && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                        new Handler().postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                progressBar.setVisibility(View.GONE);
                                Intent i = new Intent(SplashActivity.this,
                                        HomeActivity.class);
                                startActivity(i);
                                finish();
                            }
                        }, SPLASH_DISPLAY_LENGTH);

                    } else {
                        finish();
                    }
                    return;
            }
        }

Here i have a simple solution, - (Multiple permission checking)

String[] permissions = new String[]{
  Manifest.permission.WRITE_CALL_LOG,
  Manifest.permission.READ_CALL_LOG,
  Manifest.permission.READ_CONTACTS,
  Manifest.permission.WRITE_CONTACTS}; // Here i used multiple permission check

Then call it in Oncreate

 if (checkPermissions()) { //  permissions  granted.
    getCallDetails();
 }

Finally, copy the below code

private boolean checkPermissions() {
  int result;
  List<String> listPermissionsNeeded = new ArrayList<>();

   for (String p : permissions) {
     result = ContextCompat.checkSelfPermission(getApplicationContext(), p);
     if (result != PackageManager.PERMISSION_GRANTED) {
       listPermissionsNeeded.add(p);
     }
   }

   if (!listPermissionsNeeded.isEmpty()) {
     ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), MULTIPLE_PERMISSIONS);
     return false;
   }
     return true;
}


@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
  switch (requestCode) {
    case MULTIPLE_PERMISSIONS: {
      if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {  // permissions granted.
           getCallDetails(); // Now you call here what ever you want :)
        } else {
             String perStr = "";
               for (String per : permissions) {
                   perStr += "\n" + per;
                }   // permissions list of don't granted permission
              }
            return;
          }
       }
    }

First initialize permission request code

public  static final int PERMISSIONS_MULTIPLE_REQUEST = 123;

Check android version

 private void checkAndroidVersion() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        checkPermission();

    } else {
        // write your logic here
    }

}

check multiple permission code

 private void checkPermission() {
    if (ContextCompat.checkSelfPermission(getActivity(),
            Manifest.permission.READ_EXTERNAL_STORAGE) + ContextCompat
            .checkSelfPermission(getActivity(),
                    Manifest.permission.CAMERA)
            != PackageManager.PERMISSION_GRANTED) {

        if (ActivityCompat.shouldShowRequestPermissionRationale
                (getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE) ||
                ActivityCompat.shouldShowRequestPermissionRationale
                        (getActivity(), Manifest.permission.CAMERA)) {

      Snackbar.make(getActivity().findViewById(android.R.id.content),
                    "Please Grant Permissions to upload profile photo",
                    Snackbar.LENGTH_INDEFINITE).setAction("ENABLE",
                    new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            requestPermissions(
                                    new String[]{Manifest.permission
                                            .READ_EXTERNAL_STORAGE, Manifest.permission.CAMERA},
                                    PERMISSIONS_MULTIPLE_REQUEST);
                        }
                    }).show();
        } else {
            requestPermissions(
                    new String[]{Manifest.permission
                            .READ_EXTERNAL_STORAGE, Manifest.permission.CAMERA},
                    PERMISSIONS_MULTIPLE_REQUEST);
        }
    } else {
        // write your logic code if permission already granted
    }
}

call back method after grant permission by user

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

    switch (requestCode) {
        case PERMISSIONS_MULTIPLE_REQUEST:
            if (grantResults.length > 0) {
               boolean cameraPermission = grantResults[1] == PackageManager.PERMISSION_GRANTED;
               boolean readExternalFile = grantResults[0] == PackageManager.PERMISSION_GRANTED;

                if(cameraPermission && readExternalFile)
                {
                    // write your logic here 
                } else {
                    Snackbar.make(getActivity().findViewById(android.R.id.content),
                        "Please Grant Permissions to upload profile photo",
                        Snackbar.LENGTH_INDEFINITE).setAction("ENABLE",
                        new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                requestPermissions(
                                        new String[]{Manifest.permission
                                                .READ_EXTERNAL_STORAGE, Manifest.permission.CAMERA},
                                        PERMISSIONS_MULTIPLE_REQUEST);
                            }
                        }).show();
                }
           }
           break;
    }
}

You can ask multiple permissions (from different groups) in a single request. For that, you need to add all the permissions to the string array that you supply as the first parameter to the requestPermissions API like this:

requestPermissions(new String[]{
                                Manifest.permission.READ_CONTACTS,
                                Manifest.permission.ACCESS_FINE_LOCATION},
                        ASK_MULTIPLE_PERMISSION_REQUEST_CODE);

On doing this, you will see the permission popup as a stack of multiple permission popups. Ofcourse you need to handle the acceptance and rejection (including the "Never Ask Again") options of each permissions. The same has been beautifully explained over here.


As said earlier, currently every permission group has own permission dialog which must be called separately.

You will have different dialog boxes for each permission group but you can surely check the result together in onRequestPermissionsResult() callback method.

Here is a working example link, may be useful for someone.