请求权限后,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.
}
但它没有清楚,也没有找到文件。
答案 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)
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 }