Android onRequestPermissionsResult grantResults size> 1

时间:2016-07-08 06:24:51

标签: android android-permissions

请求权限后,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.
    }

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

4 个答案:

答案 0 :(得分:12)

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

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

答案 1 :(得分:0)

您可以查看所有

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

通过最短方式,可以确保所有权限均由用户授予。

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