我知道Android 6.0有新的权限,我知道我可以用这样的东西来调用它们
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); }
今天我看到了一个需要3个权限的Google应用:联系人,短信和相机.它正在制作第1-3页并同时将它们全部调用以激活.
任何人都可以告诉我如何调用4个权限同时激活短信,相机,联系人和存储?
示例(忘记了谷歌应用程序的名称:()
该应用程序需要短信,联系人和相机
应用程序问我(并进行了对话框1-3)激活短信,激活联系人,然后是相机.所以这个谷歌应用程序一起调用所有3个必需的权限,我的问题是我怎么能得到相同的?
只需在ActivityCompat.requestPermissions(...)
通话中包含所有4个权限,Android就会像您提到的那样自动将它们一起分页.
我有一个帮助方法来检查多个权限,看看是否有任何权限.
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; }
然后只需发送所有权限.Android只会询问它需要的那些.
fun hasPermissions(context: Context, vararg permissions: String): Boolean = permissions.all { ActivityCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED }
以下是多个权限请求的详细示例: -
该应用程序在启动时需要2个权限.SEND_SMS和ACCESS_FINE_LOCATION(在manifest.xml中都提到了).
我正在使用支持库v4,它准备处理Android前Marshmallow,因此无需检查构建版本.
应用启动后,它会一起请求多个权限.如果两个权限都被授予,则正常流程会进行.
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); ListlistPermissionsNeeded = 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()是支持库的一部分.
如果未授予一个或多个权限,ActivityCompat.requestPermissions()将请求权限,控件将转到onRequestPermissionsResult()回调方法.
您应该在onRequestPermissionsResult()回调方法中检查shouldShowRequestPermissionRationale()标志的值.
只有两种情况: -
案例1: - 任何时间用户点击拒绝权限(包括第一次),它将返回true.因此,当用户拒绝时,我们可以显示更多解释并再次询问
案例2: - 只有当用户选择"永不再问"时,它才会返回false.在这种情况下,我们可以继续使用有限的功能并引导用户从设置中激活权限以获得更多功能,或者我们可以完成设置,如果权限对于应用程序来说是微不足道的.
情况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: { Mapperms = 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 < permissions.length; i++) perms.put(permissions[i], grantResults[i]); // Check for both permissions if (perms.get(Manifest.permission.SEND_SMS) == PackageManager.PERMISSION_GRANTED && perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { Log.d(TAG, "sms & location services permission granted"); // process the normal flow //else any one or both the permissions are not granted } else { Log.d(TAG, "Some permissions are not granted ask again "); //permission is denied (this is the first time, when "never ask again" is not checked) so ask again explaining the usage of permission // // shouldShowRequestPermissionRationale will return true //show the dialog or snackbar saying its necessary and try again otherwise proceed with setup. if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.SEND_SMS) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) { showDialogOK("SMS and Location Services Permission 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. break; } } }); } //permission is denied (and never ask again is checked) //shouldShowRequestPermissionRationale will return false else { Toast.makeText(this, "Go to settings and enable permissions", Toast.LENGTH_LONG) .show(); // //proceed with logic by disabling the related features or quit the app. } } } } } } private void showDialogOK(String message, DialogInterface.OnClickListener okListener) { new AlertDialog.Builder(this) .setMessage(message) .setPositiveButton("OK", okListener) .setNegativeButton("Cancel", okListener) .create() .show(); }
小代码:
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; ListlistPermissionsNeeded = 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 permissionsList[], int[] grantResults) { switch (requestCode) { case MULTIPLE_PERMISSIONS:{ if (grantResults.length > 0) { String permissionsDenied = ""; for (String per : permissionsList) { if(grantResults[0] == PackageManager.PERMISSION_DENIED){ permissionsDenied += "\n" + per; } } // Show permissionsDenied updateViews(); } return; } } }
API 23中的Android权限列表正常权限和危险权限
在片段中
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); ListlistPermissionsNeeded = 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 < permissions.length; i++) { if (permissions[i].equals(Manifest.permission.GET_ACCOUNTS)) { if (grantResults[i] == PackageManager.PERMISSION_GRANTED) { Log.e("msg", "accounts granted"); } } else if (permissions[i].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)) { if (grantResults[i] == PackageManager.PERMISSION_GRANTED) { Log.e("msg", "storage granted"); } } else if (permissions[i].equals(Manifest.permission.CALL_PHONE)) { if (grantResults[i] == PackageManager.PERMISSION_GRANTED) { Log.e("msg", "call granted"); } } else if (permissions[i].equals(Manifest.permission.RECEIVE_SMS)) { if (grantResults[i] == PackageManager.PERMISSION_GRANTED) { Log.e("msg", "sms granted"); } } else if (permissions[i].equals(Manifest.permission.ACCESS_FINE_LOCATION)) { if (grantResults[i] == PackageManager.PERMISSION_GRANTED) { Log.e("msg", "location granted"); } } } } } }
}
这很容易,这样做
private static final int REQUEST_READ_PHONE_STATE = 110 , REQUEST_ACCESS_FINE_LOCATION = 111, REQUEST_WRITE_STORAGE = 112;
在你的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); }
然后检查结果
@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(); } } } }
我的方法基于Nicks的回答,希望可以用于多个(需要的数量,而不仅仅是两个)权限。它建议添加单职责PermissionsHelper类:
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) { ListlistPermissionsNeeded = 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 < permissions.length; i++) perms.put(permissions[i], grantResults[i]); boolean allPermissionsGranted = true; for (String permission1 : permissions) { allPermissionsGranted = allPermissionsGranted && (perms.get(permission1) == PackageManager.PERMISSION_GRANTED); } if (allPermissionsGranted) { Log.d(PermissionsHelper.class.getSimpleName(), "onRequestPermissionsResult: all permissions granted"); } else { for (String permission2 : perms.keySet()) if (perms.get(permission2) == PackageManager.PERMISSION_GRANTED) perms.remove(permission2); StringBuilder message = new StringBuilder("The app has not been granted permissions:\n\n"); for (String permission : perms.keySet()) { message.append(permission); message.append("\n"); } message.append("\nHence, it cannot function properly." + "\nPlease consider granting it this permission in phone Settings."); AlertDialog.Builder builder = new AlertDialog.Builder(activity); builder.setTitle(R.string.permission_required) .setMessage(message) .setPositiveButton(android.R.string.ok, (dialog, id) -> dialog.cancel()); AlertDialog alert = builder.create(); alert.show(); } } } } }
}
如果用户未授予一个或几个必需的权限,则会向他显示详细的AlertDialog消息。
在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); }
希望这对某人有用。
我的处理程序类用于请求多个权限。您可以在此处使用查看完整
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) { ListunGrantedPermissionList = 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(); } }