如何在 Android M 中检查单个请求的多个权限?
Posted
技术标签:
【中文标题】如何在 Android M 中检查单个请求的多个权限?【英文标题】:How to check the multiple permission at single request in Android M? 【发布时间】:2016-03-06 13:16:58 【问题描述】:我想使用
-
android.permission.CAMERA
android.permission.WRITE_EXTERNAL_STORAGE
在单个请求中使用
ActivityCompat.requestPermissions(Activity activity,new String permisionList[],int permissionRequestcode);
但我的问题是有时我只请求一个权限,
我阅读了有关组权限的信息,但它仅适用于由开发人员决定的同一组,例如 CONTACT_GROUP : read_contact,write_contact
等。
我想创建自定义组权限,它只询问我一个请求并只提供一个响应。
谢谢
【问题讨论】:
你不能。每个组都有自己的权限对话框,必须调用。 @Ragaisis 我只想在一个请求中显示所有权限,我知道如果我请求多个权限但我得到了一个结果 简单的请求多个权限的方法,看看github.com/sachinvarma/EasyPermission 【参考方案1】:在这个阶段没有可用的破解方法来规避一起向不同组请求权限。这就是 android 开发运行时权限的本质,让用户可以选择接受哪些权限。当然,不接受应用所需的所有权限,可能会导致应用无法正常运行。
CAMERA 和 WRITE_EXTERNAL_STORAGE 都是 regarded as dangerous permissions,并且在不同的组中,因此都需要 runtime permission request.
一旦为特定组授予权限,则无需在应用程序运行的整个生命周期内再次请求该权限,或者如果作为默认设置将其撤销,则无需再次请求。
你唯一能做的就是要求用户接受默认的决定,可以撤销,by using "never ask again"
【讨论】:
【参考方案2】:如前所述,目前每个权限组都有自己的权限对话框,必须单独调用。
每个权限组都有不同的对话框,但你肯定可以在 onRequestPermissionsResult() 回调方法中一起检查结果。
Here is a working example link, may be useful for someone.
【讨论】:
【参考方案3】:您可以在一个请求中请求多个权限(来自不同的组)。为此,您需要将所有权限添加到作为第一个参数提供给 requestPermissions API 的字符串数组中,如下所示:
requestPermissions(new String[]
Manifest.permission.READ_CONTACTS,
Manifest.permission.ACCESS_FINE_LOCATION,
ASK_MULTIPLE_PERMISSION_REQUEST_CODE);
执行此操作时,您将看到权限弹出窗口作为多个权限弹出窗口的堆栈。当然,您需要处理每个权限的接受和拒绝(包括“不再询问”)选项。在here 上也有很好的解释。
【讨论】:
请完美阅读我的问题。我想在单个请求中检查所有权限。而不是多个对话框。 &兄弟,您的链接与我的问题无关...对不起.. 太棒了!谢谢! 我必须添加this
,否则它不起作用ActivityCompat.requestPermissions(this, new String[] Manifest.permission.WRITE_EXTERNAL_STORAGE, ... ,ASK_MULTIPLE_PERMISSION_REQUEST_CODE);
@Yonjuni 它没有检查权限列表是否授予...【参考方案4】:
我遇到了同样的问题,下面是我想出的解决方法:
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;
你这样调用上面的方法:
if ( checkForPermission( new String[]Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.CAMERA, REQUEST_PERMISSION_EXTERNAL_STORAGE_RESULT, R.string.permission_image) )
// DO YOUR STUFF
【讨论】:
但是你检查你的代码?在此代码中还多次显示本机权限对话框。 @Zala Janaksinh 是的...android 将单独显示权限,但您只发出一个请求。 我知道,所以这是我的问题。兄弟..可能是android在下一次更新中解决了这个问题。【参考方案5】:对于多个权限,您可以使用此代码:
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;
【讨论】:
如果您使用的是 marshmellow,那么您必须使用这些单独的权限【参考方案6】:我遇到了同样的问题,偶然发现了这个library。
基本上,您可以按顺序请求多个权限,此外,如果用户拒绝您的权限,您还可以添加侦听器以弹出小吃栏。
【讨论】:
他没说要介绍图书馆【参考方案7】: // **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;
【讨论】:
【参考方案8】:首先初始化权限请求代码
public static final int PERMISSIONS_MULTIPLE_REQUEST = 123;
查看安卓版本
private void checkAndroidVersion()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
checkPermission();
else
// write your logic here
检查多个权限代码
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
用户授权后回调方法
@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;
【讨论】:
依靠幻数 (PERMISSION_GRANTED = 0) 非常粗略。 请求多个权限的方法很不整洁。 告诉我为什么? 很棒的答案!工作完美 这个答案有一个bug..如果你连续两次拒绝一个权限,当你点击Snackbar上的启用时,Snackbar会一次又一次地出现【参考方案9】:根据我的搜索,我认为这是我找到的最佳答案Android 6.0 multiple permissions
【讨论】:
【参考方案10】:为不同类型的权限添加通用代码。复制粘贴稍作改动。阅读下面代码中的“TODO”cmets。
将以下 Activity 设为您的 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));
【讨论】:
【参考方案11】:基于 vedval 我有这个解决方案。
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++;
【讨论】:
【参考方案12】:这里我有一个简单的解决方案,-(多重权限检查)
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
然后在 Oncreate 中调用它
if (checkPermissions()) // permissions granted.
getCallDetails();
最后复制下面的代码
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;
【讨论】:
如果可以,为什么这个条件只测试索引 0?if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
onrequestpermission 不起作用,因为只检查第一个 granResult...【参考方案13】:
一次请求多个权限可以使用这个方法link
compile 'com.kishan.askpermission:askpermission:1.0.3'
如果您在支持库中遇到冲突,那么
compile('com.kishan.askpermission:askpermission:1.0.3',
exclude group: 'com.android.support'
)
现在请求许可
new AskPermission.Builder(this)
.setPermissions(Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_EXTERNAL_STORAGE)
.setCallback(/* PermissionCallback */)
.setErrorCallback(/* ErrorCallback */)
.request(/* Request Code */);
权限授予回调
public void onPermissionsGranted(int requestCode)
// your code
权限被拒绝回调
public void onPermissionsDenied(int requestCode)
// your code
错误回调
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();
【讨论】:
不建议使用仅链接的答案。它可能会被否决,这只是一个警告,最终会被删除。【参考方案14】:我迟到了,但我想告诉图书馆我已经结束了。
RxPermission 是最好的反应式代码库,这使得权限代码意外只有 1 行。
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'
【讨论】:
【参考方案15】:如果未授予,请检查多个权限和请求
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);
【讨论】:
【参考方案16】:您应该使用名为 dexter 的依赖项,如下所示: https://github.com/Karumi/Dexter 这样,您可以轻松获得一项或多项许可: 这是给定的代码
Dexter.withContext(this).
withPermissions(Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
.withListener(new MultiplePermissionsListener()
@Override
public void onPermissionsChecked(MultiplePermissionsReport
multiplePermissionsReport)
displaySong();
@Override
public void onPermissionRationaleShouldBeShown(List<PermissionRequest> list,
PermissionToken permissionToken)
permissionToken.continuePermissionRequest();
).check();
【讨论】:
以上是关于如何在 Android M 中检查单个请求的多个权限?的主要内容,如果未能解决你的问题,请参考以下文章
我如何从服务器捕获多个响应,并且我必须检查 jmeter 中 JSR223 采样器的特定响应?
Android 如何发送多个联系人附加在单个 .vcf 文件中并发送到邮件?