Android 6.0多重权限

我知道安卓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个权限: 联系人,短信和照相机。它制作了一个页面1-3和调用他们在同一时间一起激活。

谁能告诉我如何调用4个权限,以激活同一时间喜欢短信,相机,联系人和存储?

示例(忘记了谷歌应用程序的名称: ()
该应用程序需要短信,联系人和照相机

应用程序要求我(并制作了一个对话页1-3)激活短信,激活联系人,然后相机。 因此,这个谷歌应用程序调用所有3个必需的权限在一起,我的问题是如何才能实现相同的?

213696 次浏览

我在 Google 的 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);

只要在 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;
}

或者在 Kotlin:

fun hasPermissions(context: Context, vararg permissions: String): Boolean = permissions.all {
ActivityCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED
}

然后发送所有的权限,Android 只会要求它需要的权限。

// The request code used in ActivityCompat.requestPermissions()
// and returned in the Activity's onRequestPermissionsResult()
int PERMISSION_ALL = 1;
String[] PERMISSIONS = {
android.Manifest.permission.READ_CONTACTS,
android.Manifest.permission.WRITE_CONTACTS,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
android.Manifest.permission.READ_SMS,
android.Manifest.permission.CAMERA
};


if (!hasPermissions(this, PERMISSIONS)) {
ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
}

检查本文中的“一次请求多个权限”部分:

关于 Android M 权限你需要知道的事情

它解释得很好,也可能触及其他相关的话题,你还没有想到。

下面是具有多个权限请求的详细示例:-

应用程序在启动时需要2个权限。

我正在使用 支援图书馆 v4,这是准备处理 Android 前棉花糖,所以没有必要检查构建版本。

一旦应用程序启动,它就会一起请求多个权限。如果两个权限都被授予,则正常流继续。

enter image description here

enter image description here

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<String> 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;
}

CheckSelfPermission () ,ActivityCompat.requestPermission () ,ActivityCompat.should dShowRequestPermisonRationale ()是支持库的一部分。

如果未授予一个或多个权限,则 ActivityCompat.requestPermission ()将请求权限,控件将转到 onRequestPermisonsResult ()回调方法。

您应该在 onRequestPermisonsResult ()回调方法中检查 should dShowRequestPermisonRationale ()标志的值。

只有两种情况:

案例1: -任何时候用户点击拒绝权限(包括第一次) ,它将返回 true。因此,当用户否认,我们可以显示更多的解释,并不断要求再次

案例2: -只有当用户选择“ never ask again”时才会返回 false。在这种情况下,我们可以继续使用有限的功能,并指导用户从设置中激活更多功能的权限,或者我们可以完成设置,如果权限对应用程序来说是微不足道的。

案件一

enter image description here

案件二

enter image description here

    @Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
Log.d(TAG, "Permission callback called-------");
switch (requestCode) {
case REQUEST_ID_MULTIPLE_PERMISSIONS: {


Map<String, Integer> 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 < 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;
List<String> 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 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);


List<String> 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 < 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");


}
}




}


}




}
}

}

我已经成功地实现了一次多权限的简单代码。 按照以下步骤操作 1: 创建 Utility.java 类,如下所示

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;
}
}

现在打电话

boolean permissionCheck = Utility.checkPermissions(this, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.CALL_PHONE, Manifest.permission.GET_ACCOUNTS);

在您的活动 onCreate ()或根据您的逻辑。

3: 现在在执行特定任务的操作之前检查权限

if (permissionCheck) {
performTaskOperation();//this method what you need to perform
} else {
Toast.makeText(this, "Need permission ON.", Toast.LENGTH_SHORT).show();
}

现在在活动中实现 onRequestPermisonsResult ()方法,如下所示

  @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;
}
}

很简单,这样做

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();
}
}
}


}

下面的方法论是关于

  • 动态请求权限;
  • 如果用户拒绝任何权限,则显示 AlertDialog
  • 循环,直到用户接受权限为止

为权限方法创建一个“静态”类

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;
}
}

在 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<Integer> indexesOfPermissionsNeededToShow = new ArrayList<>();


for(int i = 0; i < permissions.length; ++i) {
if(ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[i])) {
indexesOfPermissionsNeededToShow.add(i);
}
}


int size = indexesOfPermissionsNeededToShow.size();
if(size != 0) {
int i = 0;
boolean isPermissionGranted = true;


while(i < size && isPermissionGranted) {
isPermissionGranted = grantResults[indexesOfPermissionsNeededToShow.get(i)]
== PackageManager.PERMISSION_GRANTED;
i++;
}


if(!isPermissionGranted) {


showDialogNotCancelable("Permissions mandatory",
"All the permissions are required for this app",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
checkPermissions();
}
});
}
}
}
}
}
}


private void showDialogNotCancelable(String title, String message,
DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(this)
.setTitle(title)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setCancelable(false)
.create()
.show();
}

简短而甜蜜:)我所相信的。

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;
}
}

像这样使用助手(权限名称并不重要)。

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 < permissions.length; i++) {


if (permissions[i].equals(permission.READ_CALENDAR)) {
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
smartRequestPermissions(permission.READ_CALENDAR, R.string.permission_required_dialog_read_calendar);
}
} else if (permissions[i].equals(permission.ACCESS_COARSE_LOCATION)) {
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
smartRequestPermissions(permission.ACCESS_COARSE_LOCATION, R.string.permission_required_dialog_access_coarse_location);
}
}


}
}
}
}


private void smartRequestPermissions(final String permissionName, int permissionRequiredDialog) {
if (shouldShowRationale(mMainActivity, permissionName)) {// If the user turned down the permission request in the past and chose the Don't ask again option in the permission request system dialog, this method returns false.


//Show an explanation to the user with action
mMainActivity.mSnackProgressBarManager.show(
new SnackProgressBar(
SnackProgressBar.TYPE_ACTION, mMainActivity.getString(permissionRequiredDialog)
)
.setAction("OK", new OnActionClickListener() {
@Override
public void onActionClick() {
checkAll();
}
})
.setSwipeToDismiss(true).setAllowUserInput(true)
, MainActivity.SNACKBAR_WARNING_DURATION
);


} // else do nothing
}

}

我的方法基于 Nicks 的答案,希望对于多个(需要多个,而不仅仅是两个)权限更有用一些。 它建议添加单责任 Permission Helper 类:

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<String> 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<String, Integer> 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 消息。

活动中使用的例子:

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) {
List<String> 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();
}
}

enter image description here

检查所有情况

如果拒绝-显示警报对话框给用户为什么我们需要权限

public static final int MULTIPLE_PERMISSIONS = 1;
public static final int CAMERA_PERMISSION_REQUEST_CODE = 2;
public static final int STORAGE_PERMISSION_REQUEST_CODE = 3;


private void askPermissions() {


int permissionCheckStorage = ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE);


int permissionCheckCamera = ContextCompat.checkSelfPermission(this,
Manifest.permission.CAMERA);


// we already asked for permisson & Permission granted, call camera intent
if (permissionCheckStorage == PackageManager.PERMISSION_GRANTED && permissionCheckCamera == PackageManager.PERMISSION_GRANTED) {


launchCamera();


} //asking permission for the first time
else if (permissionCheckStorage != PackageManager.PERMISSION_GRANTED && permissionCheckCamera != PackageManager.PERMISSION_GRANTED) {


ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE},
MULTIPLE_PERMISSIONS);


} else {
// Permission denied, so request permission


// if camera request is denied
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.CAMERA)) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("You need to give permission to take pictures in order to work this feature.");
builder.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
});
builder.setPositiveButton("GIVE PERMISSION", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();


// Show permission request popup
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.CAMERA},
CAMERA_PERMISSION_REQUEST_CODE);
}
});
builder.show();


}   // if storage request is denied
else if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("You need to give permission to access storage in order to work this feature.");
builder.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
});
builder.setPositiveButton("GIVE PERMISSION", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();


// Show permission request popup
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
STORAGE_PERMISSION_REQUEST_CODE);
}
});
builder.show();


}


}
}

查看许可结果

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


switch (requestCode) {
case CAMERA_PERMISSION_REQUEST_CODE:
if (grantResults.length > 0 && permissions[0].equals(Manifest.permission.CAMERA)) {
// check whether camera permission granted or not.
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
launchCamera();
}
}
break;
case STORAGE_PERMISSION_REQUEST_CODE:
if (grantResults.length > 0 && permissions[0].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// check whether storage permission granted or not.
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
launchCamera();
}
}
break;
case MULTIPLE_PERMISSIONS:
if (grantResults.length > 0 && permissions[0].equals(Manifest.permission.CAMERA) && permissions[1].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// check whether All permission granted or not.
if (grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
launchCamera();


}
}
break;
default:
break;
}
}

你可以复制粘贴这个代码,它工作正常。改变上下文(这)和权限根据你。

请求多个权限的简单方法,

Https://github.com/sachinvarma/easypermission

如何添加:

repositories {
maven { url "https://jitpack.io" }
}


implementation 'com.github.sachinvarma:EasyPermission:1.0.1'

如何请求许可:

 List<String> permission = new ArrayList<>();
permission.add(EasyPermissionList.READ_EXTERNAL_STORAGE);
permission.add(EasyPermissionList.ACCESS_FINE_LOCATION);


new EasyPermissionInit(MainActivity.this, permission);

更多详情->

Https://github.com/sachinvarma/easypermission/blob/master/app/src/main/java/com/sachinvarma/easypermissionsample/mainactivity.java

也许以后能帮到别人。

在看了所有冗长而复杂的答案之后。我想发布这个答案。

RxPermission 现在被广泛用于在一行代码中请求权限。

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
}
});

加入你的 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'
}

这不是很简单吗?

我只是用一个数组来实现多个请求,希望它能帮到别人。(科特林)

    // got all permission
private fun requestPermission(){
var mIndex: Int = -1
var requestList: Array<String> = Array(10, { "" } )


// phone call Permission
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
mIndex ++
requestList[mIndex] = Manifest.permission.CALL_PHONE
}
// SMS Permission
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
mIndex ++
requestList[mIndex] = Manifest.permission.SEND_SMS
}


// Access photos Permission
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
mIndex ++
requestList[mIndex] = Manifest.permission.READ_EXTERNAL_STORAGE
}


// Location Permission
if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
mIndex ++
requestList[mIndex] = Manifest.permission.ACCESS_FINE_LOCATION
}


if(mIndex != -1){
ActivityCompat.requestPermissions(this, requestList, PERMISSIONS_REQUEST_ALL)
}
}




// permission response
override fun onRequestPermissionsResult(requestCode: Int,
permissions: Array<String>, grantResults: IntArray) {
when (requestCode) {
PERMISSIONS_REQUEST_ALL -> {
// If request is cancelled, the result arrays are empty.
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission accept location
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "Phone Call permission accept.")
}


// permission accept location
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.SEND_SMS) == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "SMS permission accept.")
}


// permission accept location
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "SMS permission accept.")
}


// permission accept location
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "Location permission accept.")
}


} else {
Toast.makeText(mContext, "Permission Failed!", Toast.LENGTH_LONG).show()
}
return
}
}
}

请参考此链接以获得对多个权限的完全理解,也可以下载完整的源代码 点击这里

   private boolean checkAndRequestPermissions() {
int permissionReadPhoneState = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE);
int permissionProcessOutGogingCalls = ContextCompat.checkSelfPermission(this, Manifest.permission.PROCESS_OUTGOING_CALLS);
int permissionProcessReadContacts = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS);
int permissionProcessReadCallLog = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG);


int permissionWriteStorage = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
int permissionReadStorage = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);


List<String> listPermissionsNeeded = new ArrayList<>();
if (permissionReadPhoneState != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.READ_PHONE_STATE);
}
if (permissionProcessOutGogingCalls != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.PROCESS_OUTGOING_CALLS);
}
if (permissionProcessReadContacts != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.READ_CONTACTS);
}
if (permissionProcessReadCallLog != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.READ_CALL_LOG);
}
if (permissionWriteStorage != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if (permissionReadStorage != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.READ_EXTERNAL_STORAGE);
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), REQUEST_ID_MULTIPLE_PERMISSIONS);
return false;
}
return true;
}


@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults.length == 0 || grantResults == null) {
/*If result is null*/
} else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
/*If We accept permission*/
} else if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
/*If We Decline permission*/
}
}

请求多个权限的答案没有错,但是多个权限结果代码实现得不是很好,可能会导致检查错误的权限结果。

if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)对于检查多个权限结果来说是糟糕的逻辑,我不知道为什么 Google 实现了这么糟糕的代码。

这是一个混乱,尤其是当你检查多个权限。让我们说你要求 CAMERAACCESS_FINE_LOCATIONACCESS_NETWORK_STATE

您需要检查 ACCESS_FINE_LOCATION,但是用户在第一次运行时仅授予 CAMERA,并且您检查 grantResults[1],但是在第二次运行时,ACCESS_FINE_LOCATION成为索引为0的权限。我有这么多的问题,用户不授予所有的权限一次,不得不写这么无意义的权限结果逻辑。

你可以选择

   int size = permissions.length;
boolean locationPermissionGranted = false;


for (int i = 0; i < size; i++) {
if (permissions[i].equals(Manifest.permission.ACCESS_FINE_LOCATION)
&& grantResults[i] == PackageManager.PERMISSION_GRANTED) {
locationPermissionGranted = true;
}
}

或者更简单的

   if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
// Do something ...
}

onPermissionRequestResult方法中。

在 Kotlin:

private val id = 1
private val permissions = arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.ACCESS_FINE_LOCATION)
fun hasPermissions(): Boolean {
for (perm in permissions) {
if (ActivityCompat.checkSelfPermission(this, perm) != PackageManager.PERMISSION_GRANTED) {
return false
}
}


return true
}


if(! hasPermissions()){
requestPermissions(this, permissions, id)
}

这就是我在我的活动中所做的。希望会有帮助。我请求摄像头和麦克风的权限。

public class ActiveCallActivity extends AppCompatActivity {
.....


private static final String cameraPermissionKey = "cameraPermission";
private static final String microphonePermissionkey = "microphonePermission";


private static ArrayList<String> permissionsQueue = new ArrayList<String>();


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);


.....
// in ValidationCheckersAndValidators simply checking if have permission or not.
if(ValidationCheckersAndValidators.haveCameraPermission(this)) performHaveCameraPermissionLayout(); else performHaveNoCameraPermissionLayout();
if(ValidationCheckersAndValidators.haveMicrophonePermission(this)) performHaveMicrophonePermissionLayout(); else performHaveNoMicrophonePermissionLayout();


}


private void performHaveNoCameraPermissionLayout() {
.....
permissionsQueue.add(cameraPermissionKey);
}


private void performHaveNoMicrophonePermissionLayout() {
.....
permissionsQueue.add(microphonePermissionkey);
}


@Override
protected void onResume() {
super.onResume();


.....
passThroughPermissionsQueue();
}


private void passThroughPermissionsQueue() {
if(!permissionsQueue.isEmpty()) {
String permissionKey = permissionsQueue.remove(0);
switch (permissionKey) {
case cameraPermissionKey: {
ValidationCheckersAndValidators.requestForCameraPermission(this);
return;
}
case microphonePermissionkey: {
ValidationCheckersAndValidators.requestForMicrophonePermission(this);
return;
}
}
}
}


@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch(requestCode) {
case cameraPermissionRequestCode: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
performHaveCameraPermissionLayout();
}
break;
}
case microphonePermissionRequestCode: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
performHaveMicrophonePermissionLayout();
}
break;
}
}
passThroughPermissionsQueue();
}
}

你可以使用 Dexter

build.gradle中添加:

implementation 'com.karumi:dexter:5.0.0'

在你的活动中使用它:

val requiredPermissions = when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> listOf(Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_BACKGROUND_LOCATION)
else -> listOf(Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION)
}


Dexter.withActivity(this)
.withPermissions(
requiredPermissions
)
.withListener(object : MultiplePermissionsListener {
override fun onPermissionRationaleShouldBeShown(
permissions: MutableList<PermissionRequest>?,
token: PermissionToken?
) {
/* ... */
}




override fun onPermissionsChecked(report: MultiplePermissionsReport) =
if (report.isAnyPermissionPermanentlyDenied) {
toast("You should grant all permissions")
} else {
toast("All permissions granted")


// continue here if permission is a must


}).check()


// continue here if permission is not a must

2022年简单明了的多许可申请新方法

在你的活动课上名列前茅,写下

private val multiplePermissionContract = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissionsStatusMap ->
// permissionStatusMap is of type <String, Boolean>
// if all permissions accepted
if (!permissionsStatusMap.containsValue(false)) {


// All persmissions are accepted, do here whatever you want


} else {
Toast.makeText(this, "all permissions not accepted", Toast.LENGTH_SHORT).show()
}
}

并且,在任何时候都可以启动询问权限对话框,如下所示(现在,我认为您需要在单击 xyzButton 时询问权限)

    xyzButton.setOnClickListener {
multiplePermissionContract.launch(
arrayOf(
android.Manifest.permission.READ_CONTACTS,
android.Manifest.permission.WRITE_CONTACTS,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
android.Manifest.permission.READ_SMS,
android.Manifest.permission.CAMERA
)
)
}

注意-

  • 当我们单击 xyzButton 时,将始终调用 registerForActivityResult ()方法。如果之前未接受所有权限中的任何一个,它将再次请求该特定权限; 否则它将直接执行 If 条件块。