可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I know that Android 6.0 has new permissions and I know I can call them with something like this
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, PERMISSION_WRITE_STORAGE); }
Today I saw a Google app which needs 3 permissions: contacts, sms and camera. It's making a page 1-3 and calls them all together at the same time to activate.
Can anybody tell me how I can call 4 permissions to activate at the same time like sms, camera, contacts and storage?
Example (forgot the name of the google app :( )
The app needs sms,contacts and camera
the app asked me (and made a dialog page1-3) activate sms, activate contacts and then camera. So this google app was calling all 3 required permissions together and my question is how can i achive the same ?
回答1:
Just include all 4 permissions in the ActivityCompat.requestPermissions(...)
call and Android will automatically page them together like you mentioned.
I have a helper method to check multiple permissions and see if any of them are not granted.
public static boolean hasPermissions(Context context, String... permissions) { if (context != null && permissions != null) { for (String permission : permissions) { if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) { return false; } } } return true; }
Then just send it all of the permissions. Android will ask only for the ones it needs.
// The request code used in ActivityCompat.requestPermissions() // and returned in the Activity's onRequestPermissionsResult() int PERMISSION_ALL = 1; String[] PERMISSIONS = {Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_SMS, Manifest.permission.CAMERA}; if(!hasPermissions(this, PERMISSIONS)){ ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL); }
回答2:
Here is detailed example with multiple permission requests:-
The app needs 2 permissions at startup . SEND_SMS and ACCESS_FINE_LOCATION (both are mentioned in manifest.xml).
I am using Support Library v4 which is prepared to handle Android pre-Marshmallow and so no need to check build versions.
As soon as the app starts up, it asks for multiple permissions together. If both permissions are granted the normal flow goes.


public static final int REQUEST_ID_MULTIPLE_PERMISSIONS = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if(checkAndRequestPermissions()) { // carry on the normal flow, as the case of permissions granted. } } private boolean checkAndRequestPermissions() { int permissionSendMessage = ContextCompat.checkSelfPermission(this, Manifest.permission.SEND_SMS); int locationPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION); List listPermissionsNeeded = new ArrayList(); if (locationPermission != PackageManager.PERMISSION_GRANTED) { listPermissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION); } if (permissionSendMessage != PackageManager.PERMISSION_GRANTED) { listPermissionsNeeded.add(Manifest.permission.SEND_SMS); } if (!listPermissionsNeeded.isEmpty()) { ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]),REQUEST_ID_MULTIPLE_PERMISSIONS); return false; } return true; }
ContextCompat.checkSelfPermission(), ActivityCompat.requestPermissions(), ActivityCompat.shouldShowRequestPermissionRationale() are part of support library.
In case one or more permissions are not granted, ActivityCompat.requestPermissions() will request permissions and the control goes to onRequestPermissionsResult() callback method.
You should check the value of shouldShowRequestPermissionRationale() flag in onRequestPermissionsResult() callback method.
There are only two cases:--
Case 1:-Any time user clicks Deny permissions (including the very first time), it will return true. So when the user denies, we can show more explanation and keep asking again
Case 2:-Only if user select “never asks again” it will return false. In this case, we can continue with limited functionality and guide user to activate the permissions from settings for more functionalities, or we can finish the setup, if the permissions are trivial for the app.
CASE -1

CASE-2

@Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { Log.d(TAG, "Permission callback called-------"); switch (requestCode) { case REQUEST_ID_MULTIPLE_PERMISSIONS: { Map perms = new HashMap(); // Initialize the map with both permissions perms.put(Manifest.permission.SEND_SMS, PackageManager.PERMISSION_GRANTED); perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED); // Fill with actual results from user if (grantResults.length > 0) { for (int i = 0; i
回答3:
Small code :
public static final int MULTIPLE_PERMISSIONS = 10; // code you want. String[] permissions= new String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}; if (checkPermissions()) // permissions granted. } private boolean checkPermissions() { int result; List listPermissionsNeeded = new ArrayList(); for (String p:permissions) { result = ContextCompat.checkSelfPermission(getActivity(),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. } else { String permissions = ""; for (String per : permissionsList) { permissions += "\n" + per; } // permissions list of don't granted permission } return; } } }
List of Android permissions normal permissions and dangerous permissions in API 23
回答4:
In a Fragment
public class Homefragment extends Fragment { View hfrag; Context context; public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { //first we must check the permissions are already granted hfrag = inflater.inflate(R.layout.home, container, false); context = getActivity(); checkAndRequestPermissions(); } } private boolean checkAndRequestPermissions() { int permissionSendMessage = ContextCompat.checkSelfPermission(context, Manifest.permission.READ_SMS); int contactpermission = ContextCompat.checkSelfPermission(context, Manifest.permission.GET_ACCOUNTS); int writepermission = ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE); int callpermission = ContextCompat.checkSelfPermission(context, Manifest.permission.CALL_PHONE); int receivepermission = ContextCompat.checkSelfPermission(context, Manifest.permission.RECEIVE_SMS); int locationpermission = ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION); List listPermissionsNeeded = new ArrayList(); if (locationpermission != PackageManager.PERMISSION_GRANTED) { listPermissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION); } if (contactpermission != PackageManager.PERMISSION_GRANTED) { listPermissionsNeeded.add(Manifest.permission.GET_ACCOUNTS); } if (writepermission != PackageManager.PERMISSION_GRANTED) { listPermissionsNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); } if (permissionSendMessage != PackageManager.PERMISSION_GRANTED) { listPermissionsNeeded.add(Manifest.permission.READ_SMS); } if (receivepermission != PackageManager.PERMISSION_GRANTED) { listPermissionsNeeded.add(Manifest.permission.RECEIVE_SMS); } if (callpermission != PackageManager.PERMISSION_GRANTED) { listPermissionsNeeded.add(Manifest.permission.CALL_PHONE); } if (!listPermissionsNeeded.isEmpty()) { requestPermissions(listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), REQUEST_ID_MULTIPLE_PERMISSIONS); return false; } return true; } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_ID_MULTIPLE_PERMISSIONS) { if (grantResults.length > 0) { for (int i = 0; i
}
回答5:
It's easy, do this way
private static final int REQUEST_READ_PHONE_STATE = 110 , REQUEST_ACCESS_FINE_LOCATION = 111, REQUEST_WRITE_STORAGE = 112;
In your onCreate
//request permission boolean hasPermissionPhoneState = (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED); if (!hasPermissionPhoneState) { ActivityCompat.requestPermissions(LoginActivity.this, new String[]{Manifest.permission.READ_PHONE_STATE}, REQUEST_READ_PHONE_STATE); } boolean hasPermissionLocation = (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED); if (!hasPermissionLocation) { ActivityCompat.requestPermissions(LoginActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_ACCESS_FINE_LOCATION); } boolean hasPermissionWrite = (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED); if (!hasPermissionWrite) { ActivityCompat.requestPermissions(LoginActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_STORAGE); }
Then check result
@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode) { case REQUEST_READ_PHONE_STATE: { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { Toast.makeText(LoginActivity.this, "Permission granted.", Toast.LENGTH_SHORT).show(); //reload my activity with permission granted or use the features what required the permission finish(); startActivity(getIntent()); } else { Toast.makeText(LoginActivity.this, "The app was not allowed to get your phone state. Hence, it cannot function properly. Please consider granting it this permission", Toast.LENGTH_LONG).show(); } } case REQUEST_ACCESS_FINE_LOCATION: { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { Toast.makeText(LoginActivity.this, "Permission granted.", Toast.LENGTH_SHORT).show(); //reload my activity with permission granted or use the features what required the permission finish(); startActivity(getIntent()); } else { Toast.makeText(LoginActivity.this, "The app was not allowed to get your location. Hence, it cannot function properly. Please consider granting it this permission", Toast.LENGTH_LONG).show(); } } case REQUEST_WRITE_STORAGE: { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { Toast.makeText(LoginActivity.this, "Permission granted.", Toast.LENGTH_SHORT).show(); //reload my activity with permission granted or use the features what required the permission finish(); startActivity(getIntent()); } else { Toast.makeText(LoginActivity.this, "The app was not allowed to write to your storage. Hence, it cannot function properly. Please consider granting it this permission", Toast.LENGTH_LONG).show(); } } } }
回答6:
The following methodology is about
- asking permissions dynamically ;
- showing a AlertDialog if the user denies any permission
- looping until the user accepts permission(s)
Create a "static" class for permissions methods
public class PermissionsUtil { public static final int PERMISSION_ALL = 1; public static boolean doesAppNeedPermissions(){ return android.os.Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1; } public static String[] getPermissions(Context context) throws PackageManager.NameNotFoundException { PackageInfo info = context.getPackageManager().getPackageInfo( context.getPackageName(), PackageManager.GET_PERMISSIONS); return info.requestedPermissions; } public static void askPermissions(Activity activity){ if(doesAppNeedPermissions()) { try { String[] permissions = getPermissions(activity); if(!checkPermissions(activity, permissions)){ ActivityCompat.requestPermissions(activity, permissions, PERMISSION_ALL); } } catch(Exception e) { e.printStackTrace(); } } } public static boolean checkPermissions(Context context, String... permissions){ if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) { for (String permission : permissions) { if (ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) { return false; } } } return true; } }
In MainActivity.java
private void checkPermissions(){ PermissionsUtil.askPermissions(this); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode) { case PermissionsUtil.PERMISSION_ALL: { if (grantResults.length > 0) { List indexesOfPermissionsNeededToShow = new ArrayList(); for(int i = 0; i
回答7:
I have successfully implemented simple code for Multiple permission at Once. Follow the below steps 1:Make Utility.java class like below
public class Utility { public static final int MY_PERMISSIONS_REQUEST = 123; @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public static boolean checkPermissions(Context context, String... permissions) { if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) { for (String permission : permissions) { if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) { if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, permission)) { ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.CALL_PHONE,Manifest.permission.GET_ACCOUNTS}, MY_PERMISSIONS_REQUEST); } else { ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.CALL_PHONE,Manifest.permission.GET_ACCOUNTS}, MY_PERMISSIONS_REQUEST); } return false; } } } return true; } }
2: Now call
boolean permissionCheck = Utility.checkPermissions(this, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.CALL_PHONE, Manifest.permission.GET_ACCOUNTS);
in your Activity onCreate() or according to your logic.
3:Now check permission before performing operation for particular task
if (permissionCheck) { performTaskOperation();//this method what you need to perform } else { Toast.makeText(this, "Need permission ON.", Toast.LENGTH_SHORT).show(); }
4: Now implement onRequestPermissionsResult() method in your Activity as below
@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch (requestCode) { case Utility.MY_PERMISSIONS_REQUEST: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { if (userChoosenTask.equals("STORAGE")) performTaskOperation();//this method what you need to perform } break; } }
回答8:
My approach is based on Nicks' answer and hopefully is a bit more usable for multiple (as many as needed, not only two) permissions. It suggests adding single-responsibility PermissionsHelper class:
import android.app.Activity; import android.app.AlertDialog; import android.content.pm.PackageManager; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.util.Log; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class PermissionsHelper { private static final int REQUEST_ID_MULTIPLE_PERMISSIONS = 100; // any code you want. public void checkAndRequestPermissions(Activity activity, String... permissions) { List listPermissionsNeeded = new ArrayList(); for (String permission : permissions) { if (ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) { listPermissionsNeeded.add(permission); } } if (!listPermissionsNeeded.isEmpty()) { ActivityCompat.requestPermissions(activity, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), REQUEST_ID_MULTIPLE_PERMISSIONS); } } public void onRequestPermissionsResult(Activity activity, int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case REQUEST_ID_MULTIPLE_PERMISSIONS: { Map perms = new HashMap(); for (String permission : permissions) { perms.put(permission, PackageManager.PERMISSION_GRANTED); } if (grantResults.length > 0) { for (int i = 0; i dialog.cancel()); AlertDialog alert = builder.create(); alert.show(); } } } } }
}
If one or several required permissions have not been granted by user, the detailed AlertDialog message will be shown to him.
Example of usage in Activity:
private PermissionsHelper permissionsHelper; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); checkPermissions(); //any other code } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { permissionsHelper.onRequestPermissionsResult(this, requestCode, permissions, grantResults); } private void checkPermissions() { permissionsHelper = new PermissionsHelper(); permissionsHelper.checkAndRequestPermissions(this, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION); }
Hope that this will be useful for someone.
回答9:
I found this is in the runtime permissions example from Google's github.
private static String[] PERMISSIONS_CONTACT = {Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS}; private static final int REQUEST_CONTACTS = 1; ActivityCompat.requestPermissions(this, PERMISSIONS_CONTACT, REQUEST_CONTACTS);
回答10:
Check the "Asking for multiple permissions at a time" section in this article:
Things you need to know about Android M permissions
It's very well explained, and may also touch other related topics you haven't think about.
回答11:
Short and sweet :). what I believe in.
int PERMISSION_ALL = 1; String[] PERMISSIONS = {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}; // List of permissions required public void askPermission() { for (String permission : PERMISSIONS) { if (ActivityCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) { requestPermissions(PERMISSIONS, PERMISSION_ALL); return; } } } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch (requestCode) { case 1:{ if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED){ //Do your work. } else { Toast.makeText(this, "Until you grant the permission, we cannot proceed further", Toast.LENGTH_SHORT).show(); } return; } }
回答12:
Use helper like this (permissions names do not matter).
public class MyPermission { private static final int PERMISSION_REQUEST_ALL = 127; private MainActivity mMainActivity; MyPermission(MainActivity mainActivity) { mMainActivity = mainActivity; } public static boolean hasPermission(String permission, Context context) { if (isNewPermissionModel()) { return (ActivityCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED); } return true; } private static boolean hasPermissions(Context context, String... permissions) { if (isNewPermissionModel() && context != null && permissions != null) { for (String permission : permissions) { if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) { return false; } } } return true; } private static boolean shouldShowRationale(Activity activity, String permission) { return isNewPermissionModel() && ActivityCompat.shouldShowRequestPermissionRationale(activity, permission); } private static boolean isNewPermissionModel() { return VERSION.SDK_INT > VERSION_CODES.LOLLIPOP_MR1; } /** * check all permissions */ void checkAll() { //check dangerous permissions, make request if need (Android will ask only for the ones it needs) String[] PERMISSIONS = { permission.READ_CALENDAR, permission.ACCESS_COARSE_LOCATION }; if (!hasPermissions(mMainActivity, PERMISSIONS)) { ActivityCompat.requestPermissions(mMainActivity, PERMISSIONS, PERMISSION_REQUEST_ALL); } } void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == PERMISSION_REQUEST_ALL) { if (grantResults.length > 0) { //for not granted for (int i = 0; i
}
回答13:
My handler class for request multiple permissions. You can check the full using here
public class RequestPermissionHandler { private Activity mActivity; private RequestPermissionListener mRequestPermissionListener; private int mRequestCode; public void requestPermission(Activity activity, @NonNull String[] permissions, int requestCode, RequestPermissionListener listener) { mActivity = activity; mRequestCode = requestCode; mRequestPermissionListener = listener; if (!needRequestRuntimePermissions()) { mRequestPermissionListener.onSuccess(); return; } requestUnGrantedPermissions(permissions, requestCode); } private boolean needRequestRuntimePermissions() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M; } private void requestUnGrantedPermissions(String[] permissions, int requestCode) { String[] unGrantedPermissions = findUnGrantedPermissions(permissions); if (unGrantedPermissions.length == 0) { mRequestPermissionListener.onSuccess(); return; } ActivityCompat.requestPermissions(mActivity, unGrantedPermissions, requestCode); } private boolean isPermissionGranted(String permission) { return ActivityCompat.checkSelfPermission(mActivity, permission) == PackageManager.PERMISSION_GRANTED; } private String[] findUnGrantedPermissions(String[] permissions) { List unGrantedPermissionList = new ArrayList(); for (String permission : permissions) { if (!isPermissionGranted(permission)) { unGrantedPermissionList.add(permission); } } return unGrantedPermissionList.toArray(new String[0]); } public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == mRequestCode) { if (grantResults.length > 0) { for (int grantResult : grantResults) { if (grantResult != PackageManager.PERMISSION_GRANTED) { mRequestPermissionListener.onFailed(); return; } } mRequestPermissionListener.onSuccess(); } else { mRequestPermissionListener.onFailed(); } } } public interface RequestPermissionListener { void onSuccess(); void onFailed(); } }
