【问题标题】:Android onRequestPermissionsResult grantResults size > 1Android onRequestPermissionsResult grantResults 大小 > 1
【发布时间】:2016-11-10 15:21:40
【问题描述】:

请求权限后,ActivityCompat.OnRequestPermissionsResultCallback 有时会包含多个grantResults,只检查第一个是否安全?

training doc 像这样检查参数:

    if (grantResults.length > 0
      && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
      // permission was granted, yay! Do the
      // contacts-related task you need to do.
    } else {
      // permission denied, boo! Disable the
      // functionality that depends on this permission.
    }

但不清楚,也没有找到文件。

【问题讨论】:

    标签: android android-permissions


    【解决方案1】:

    不,仅检查第一个权限不是一个好方法,用户可能已允许第一个权限但拒绝其余权限。这是我正在共享的功能,用于检查是否授予了所有权限

    public boolean hasAllPermissionsGranted(@NonNull int[] grantResults) {
        for (int grantResult : grantResults) {
            if (grantResult == PackageManager.PERMISSION_DENIED) {
                return false;
            }
        }
        return true;
    }
    

    在你的onRequestPermissionsResult

    if(hasAllPermissionsGranted(grantResults)){
        // all permissions granted
    }else {
        // some permission are denied.
    }
    

    【讨论】:

      【解决方案2】:

      最短的方法可以确保所有权限都由用户授予。

      @Override
      public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
          super.onRequestPermissionsResult(requestCode, permissions, grantResults);
      
          if (Arrays.binarySearch(grantResults, -1) >= 0) {
      
              /* Some permissions are not granted
              request permission again if required */
      
              return;
          }
      }
      

      可用于验证权限的整数数组:

      if (Arrays.binarySearch(grantResults, -1) >= 0) { // some permissions are not granted }
      

      【讨论】:

        【解决方案3】:

        您可以全部查看

           @Override
            public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
                switch (requestCode) {
                    case REQUEST_CODE_ASK_PERMISSIONS:
                        final int numOfRequest = grantResults.length;
                        final boolean isGranted = numOfRequest == 1
                                && PackageManager.PERMISSION_GRANTED == grantResults[numOfRequest - 1];
                        if (isGranted) {
                          // you are good to go
                        }
                        break;
                    default:
                        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
                }
        

        【讨论】:

          【解决方案4】:

          根据requestPermissions 的文档

          requestCode int:应用程序特定请求代码以匹配 结果报告给 onRequestPermissionsResult(int, String[], int[])。 应该 >= 0。

          由于requestCode特定于应用程序的,它是由开发人员针对特定需求定义的,即

          public class Main : Activity
          {
              private Bundle _savedInstanceState;        
              private bool _bStorageRationaleBefore;
              private bool _bStorageRationaleAfter;
              private bool _bCameraRationaleBefore;
              private bool _bCameraRationaleAfter;
              private const int ANDROID_PERMISSION_REQUEST_CODE__SDCARD = 2;
              private const int ANDROID_PERMISSION_REQUEST_CODE__CAMERA = 1;
              private const int ANDROID_PERMISSION_REQUEST_CODE__NONE = 0;
          
              private bool VerifyWriteExternalStoragePermissionRequestResult(string permission, Permission grantResult)
              {
                  _bStorageRationaleAfter = ShouldShowRequestPermissionRationale(Android.Manifest.Permission.WriteExternalStorage);            
                  if (permission != Android.Manifest.Permission.WriteExternalStorage || grantResult != Permission.Granted)
                  {                
                      return false;
                  }
          
                  return true;
              }
          
              private bool VerifyCameraPermissionRequestResult(string permission, Permission grantResult)
              {
                  _bCameraRationaleAfter = ShouldShowRequestPermissionRationale(Android.Manifest.Permission.Camera);
                  if (permission != Android.Manifest.Permission.Camera || grantResult != Permission.Granted)
                  {                
                      return false;
                  }
          
                  return true;
              }
          
              public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Permission[] grantResults)
              {
                  // note: OnRequestPermissionsResult() runs in a separate thread.
                  base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
          
                  bool bStorage = true;
                  bool bCamera = true;
          
                  switch (requestCode)
                  {
                      case ANDROID_PERMISSION_REQUEST_CODE__SDCARD:
                          bStorage = VerifyWriteExternalStoragePermissionRequestResult(permissions[0],grantResults[0]);
                          break;
                      case ANDROID_PERMISSION_REQUEST_CODE__CAMERA:
                          bCamera = VerifyCameraPermissionRequestResult(permissions[0], grantResults[0]);
                          break;
                      case ANDROID_PERMISSION_REQUEST_CODE__SDCARD | ANDROID_PERMISSION_REQUEST_CODE__CAMERA:
                          bStorage = VerifyWriteExternalStoragePermissionRequestResult(permissions[0], grantResults[0]);
                          bCamera = VerifyCameraPermissionRequestResult(permissions[1], grantResults[1]);
                          break;
                  }
          
                  // Could check bCamera, but it isn't necessary to continue, and can be prompted for again when camera is needed.
                  // Note however that every view that potentially requires the camera will have to:
                  ///////////////////////////////////////////////////////////////////
                  // 1. Call ApplicationContext.CheckSelfPermission()
                  // 2. Call RequestPermissions()
                  // 3. Override OnRequestPermissionsResult()
                  ///////////////////////////////////////////////////////////////////
                  // hence why I'd rather get it done in one spot during startup (main)
          
                  if (bStorage && bCamera)
                  {
                      RestartActivity();
                  }
                  else
                  {
                      // Show error message alert. RestartActivity called from MessageAlertDialogOkClickEventHandler()
                      // to prevent race condition between StartActivity() and ShowDialog()
          
                      System.Text.StringBuilder errMsg = new System.Text.StringBuilder();
          
                      string appName = this.ApplicationContext.ApplicationInfo.LoadLabel(PackageManager);
                      PermissionGroupInfo pgiStorage = this.PackageManager.GetPermissionGroupInfo(Android.Manifest.Permission_group.Storage, PackageInfoFlags.Permissions);
                      PermissionGroupInfo pgiCamera = this.PackageManager.GetPermissionGroupInfo(Android.Manifest.Permission_group.Camera, PackageInfoFlags.Permissions);
          
                      bool bNeverAskForStorage =
                          !bStorage && (
                              _bStorageRationaleBefore == true  && _bStorageRationaleAfter == false ||
                              _bStorageRationaleBefore == false && _bStorageRationaleAfter == false
                          );
          
                      bool bNeverAskForCamera =
                          !bCamera && (
                              _bCameraRationaleBefore == true && _bCameraRationaleAfter == false ||
                              _bCameraRationaleBefore == false && _bCameraRationaleAfter == false
                          );                
          
                      if (bNeverAskForStorage || bNeverAskForCamera)
                      {
                          errMsg.Append("To continue, enable " + appName + " Permissions:\n\n");
          
                          if (!bStorage) errMsg.Append("\t* " + pgiStorage.LoadLabel(PackageManager) + "\n");                    
                          if (!bCamera) errMsg.Append("\t* " + pgiCamera.LoadLabel(PackageManager) + "\n");
          
                          errMsg.Append("\n(Use \"back button\" when finished to return.)");
          
                          CommonView.ShowMessageAlertDialog(this.FragmentManager, errMsg.ToString(), PermissionMessageAlertDialogOkClickEventHandler2);
                      } 
                      else // if (!bNeverAskForStorage && !bNeverAskForCamera)
                      {
                          errMsg.Append("To continue, allow " + appName + " to:\n\n");
          
                          if (!bStorage) errMsg.Append("\t* " + pgiStorage.LoadDescription(PackageManager) + "\n");
                          if (!bCamera) errMsg.Append("\t* " + pgiCamera.LoadDescription(PackageManager) + "\n");
          
                          CommonView.ShowMessageAlertDialog(this.FragmentManager, errMsg.ToString(), PermissionMessageAlertDialogOkClickEventHandler);
                      }
                  }
              }
          
              private void PermissionMessageAlertDialogOkClickEventHandler(object sender, EventArgs e)
              {
                  RestartActivity();
              }
          
              private void PermissionMessageAlertDialogOkClickEventHandler2(object sender, EventArgs e)
              {
                  Intent intent = new Intent();
                  intent.SetAction(Settings.ActionApplicationDetailsSettings);
                  Android.Net.Uri uri = Android.Net.Uri.FromParts("package", this.PackageName, null);
          
                  intent.SetData(uri);            
                  StartActivityForResult(intent, 0);
          
                  //RestartActivity();
              }
          
              protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
              {
                  base.OnActivityResult(requestCode, resultCode, data);
          
                  RestartActivity();
              }
          
              private void RestartActivity()
              {
                  Intent restartThisActivityIntent = new Intent(this, this.GetType());
          
                  if (_savedInstanceState != null)
                  {
                      restartThisActivityIntent.PutExtras(_savedInstanceState);
                  }
          
                  StartActivity(restartThisActivityIntent);
              }
          
              private List<string> GetRequiredPermissions(out int requestCode)
              {
                  // Android v6 requires explicit permission granting from user at runtime for security reasons            
                  requestCode = ANDROID_PERMISSION_REQUEST_CODE__NONE; // 0
                  List<string> requiredPermissions = new List<string>();
          
                  _bStorageRationaleBefore = ShouldShowRequestPermissionRationale(Android.Manifest.Permission.WriteExternalStorage);
                  Permission writeExternalStoragePerm = ApplicationContext.CheckSelfPermission(Android.Manifest.Permission.WriteExternalStorage);
                  //if(extStoragePerm == Permission.Denied)
                  if (writeExternalStoragePerm != Permission.Granted)
                  {
                      requestCode |= ANDROID_PERMISSION_REQUEST_CODE__SDCARD;
                      requiredPermissions.Add(Android.Manifest.Permission.WriteExternalStorage);
                  }
          
                  _bCameraRationaleBefore = ShouldShowRequestPermissionRationale(Android.Manifest.Permission.Camera);
                  Permission cameraPerm = ApplicationContext.CheckSelfPermission(Android.Manifest.Permission.Camera);
                  if (cameraPerm != Permission.Granted)
                  {
                      requestCode |= ANDROID_PERMISSION_REQUEST_CODE__CAMERA;
                      requiredPermissions.Add(Android.Manifest.Permission.Camera);
                  }
          
                  return requiredPermissions;
              }
          
              protected override void OnCreate(Bundle savedInstanceState)
              {
                  base.OnCreate(savedInstanceState);
          
                  try
                  {
                      // Android v6 requires explicit permission granting from user at runtime for security reasons
                      int requestCode;
                      List<string> requiredPermissions = GetRequiredPermissions(out requestCode);
                      if (requiredPermissions != null && requiredPermissions.Count > 0)
                      {
                          //if (requestCode >= ANDROID_PERMISSION_REQUEST_CODE__SDCARD)
                          if (requestCode >= ANDROID_PERMISSION_REQUEST_CODE__CAMERA)
                          {
                              _savedInstanceState = savedInstanceState;
                              RequestPermissions(requiredPermissions.ToArray(), requestCode);
                              return;
                          }
                      }
                  }
                  catch (Exception ex)
                  {
                      Global.LogFile.WriteEntry(ex.ToString());
                      CommonView.ShowMessageAlertDialog(this.FragmentManager, ex.Message);
                      return;
                  }
          
                  OnCreate2(savedInstanceState);
              }
          }
          

          【讨论】:

            猜你喜欢
            • 2018-11-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-01-10
            • 2017-03-30
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多