方向更改后重复的权限请求

因为Android SDK 23允许用户拒绝应用访问某些function,我想更新我的某个应用以请求权限,如下所述: https : //developer.android.com/preview/features/runtime- permissions.html 。

在其中一个活动中,我嵌入了一个SupportMapFragment 。 要使其工作,您需要具有WRITE_EXTERNAL_STORAGE权限,因此我在启动活动时请求它,这会导致创建权限请求对话框。

现在的问题是,当对话框仍然打开并且我旋转设备时,活动将重新启动并打开一个新的权限请求对话框,而旧的仍然存在。 结果是其中两个对话框彼此叠加,其中只有一个是有用的。

有没有办法摆脱首先启动的对话框?

正如CommonsWare在他的评论中所说,最好的解决方案是将一个布尔值放入savedInstanceState-Bundle中,以了解该对话框是否仍处于打开状态。

例:

 // true if dialog already open private boolean alreadyAskedForStoragePermission = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if(savedInstanceState != null) { alreadyAskedForStoragePermission = savedInstanceState.getBoolean(STORAGE_PERMISSION_DIALOG_OPEN_KEY, false); } } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean(KEY, alreadyAskedForStoragePermission); } private void checkStoragePermission(){ if(alreadyAskedForStoragePermission){ // don't check again because the dialog is still open return; } if(ActivityCompat.checkSelfPermission(this, STORAGE_PERMISSIONS[0]) != PackageManager.PERMISSION_GRANTED){ // the dialog will be opened so we have to keep that in memory alreadyAskedForStoragePermission = true; ActivityCompat.requestPermissions(this, STORAGE_PERMISSIONS, STORAGE_PERMISSION_REQUEST_CODE); } else { onStoragePermissionGranted(); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { switch (requestCode){ case STORAGE_PERMISSION_REQUEST_CODE: // the request returned a result so the dialog is closed alreadyAskedForStoragePermission = false; if(grantResults[0] == PackageManager.PERMISSION_GRANTED){ onStoragePermissionGranted(); } break; } } 

正如@ user1991776所提到的,实际上有一个未记录的额外内容,其中包含当前是否打开了权限对话框, 在Activity中 :

 private static final String HAS_CURENT_PERMISSIONS_REQUEST_KEY = "android:hasCurrentPermissionsRequest"; 

但是有更好的方法。 当您第二次请求权限对话框(由于轮换)时, Activity通过使用空数组调用onRequestPermissionResult() 来自动取消旧对话框:

 public final void requestPermissions(@NonNull String[] permissions, int requestCode) { if (mHasCurrentPermissionsRequest) { Log.w(TAG, "Can reqeust only one set of permissions at a time"); // Dispatch the callback with empty arrays which means a cancellation. onRequestPermissionsResult(requestCode, new String[0], new int[0]); return; } Intent intent = getPackageManager().buildRequestPermissionsIntent(permissions); startActivityForResult(REQUEST_PERMISSIONS_WHO_PREFIX, intent, requestCode, null); mHasCurrentPermissionsRequest = true; } 

或者当然没有记录这种行为,因为这是Android,谁想记录复杂的行为?

无论如何,你总是可以在onCreate()请求权限,然后忽略对具有零长度permissions数组的onRequestPermissionsResult()调用。

我想因为这是一个系统对话框,你无法控制它。 如果您转动设备,则可以防止重新加载您的活动。