Duplicate permission request after orientation change

前端 未结 3 1589
耶瑟儿~
耶瑟儿~ 2021-02-07 16:40

Because the Android SDK 23 gives users the possibility to deny apps access to certain functionalities I wanted to update one of my apps to request permissions as it is described

相关标签:
3条回答
  • 2021-02-07 17:03

    As CommonsWare said in his comment the best solution is to put a boolean into the savedInstanceState-Bundle to know if the dialog is still open.

    Example:

    // 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;
        }
    }
    
    0 讨论(0)
  • 2021-02-07 17:22

    I guess as this is a system dialog you cannot control it. You could instead prevent that your activity gets reloaded if you turn your device.

    0 讨论(0)
  • 2021-02-07 17:27

    As @user1991776 mentioned there is actually an undocumented extra that contains whether or not there is a permission dialog open at the moment, in Activity:

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

    However there is a better way. When you request a permission dialog the second time (due to a rotation), Activity automatically cancels the old dialog by calling your onRequestPermissionResult() with empty arrays:

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

    Or course this behaviour isn't documented because this is Android, and who wants to document complex behaviour?

    Anyway you can just always request permissions in onCreate() and then ignore calls to onRequestPermissionsResult() with zero-length permissions arrays.

    0 讨论(0)
提交回复
热议问题