如何在 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 &gt; 0 &amp;&amp; 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 文件中并发送到邮件?

Firebase 在单个请求中发送多个通知

Phonegap:在单个请求中上传多个图像

Android KInvey 如何在单个查询中从多个集合中查询详细信息

针对单个值检查多个 MySQL 列