Android request run time permission not working

2019-08-13 14:24发布

问题:

I was having some problem when trying to request run time permission on Android emulator. What I am trying to do is upon button clicked, request for read and write to external storage permission before moving on to my async task class.

Here is my code:

private static final int PERMISSION_REQUEST_CODE = 1;
String readPermission = Manifest.permission.READ_EXTERNAL_STORAGE;
String writePermission = Manifest.permission.WRITE_EXTERNAL_STORAGE;
@Click(R.id.buttonVersionUpgrade)
void buttonVersionUpgradeClicked(View v) {

    if (!checkPermission(readPermission) || !checkPermission(writePermission)) {
        requestPermission(readPermission);
        requestPermission(writePermission);
    }
   // async task here
}

private boolean checkPermission(String permission){
    if (Build.VERSION.SDK_INT >= 23) {
        int result = ContextCompat.checkSelfPermission(getApplicationContext(), permission);
        if (result == PackageManager.PERMISSION_GRANTED){
            return true;
        } else {
            return false;
        }
    } else {
        return true;
    }
}

private void requestPermission(String permission){
    if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission)){
        Toast.makeText(getApplicationContext(), "Read/Write external storage permission allows us to read/write data. Please allow in App Settings for additional functionality.",Toast.LENGTH_LONG).show();
    }
    ActivityCompat.requestPermissions(this, new String[]{permission},PERMISSION_REQUEST_CODE);
}

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case PERMISSION_REQUEST_CODE:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(getApplicationContext(), "Permission Granted. Now you can read/write data.",
                        Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(getApplicationContext(),"Permission Denied. You cannot read/write data.",
                        Toast.LENGTH_LONG).show();
            }
            break;
    }
}

However, it does not prompt the user for the permission before moving to async task execution and this resulting in app crash. It only prompt user upon app crashes. Any ideas?

Thanks!

回答1:

This is because ActivityCompat.requestPermissions is not a synchronous call. OS will show the popup (which is actually an Activity) and the statements following it will be executed.

Since both permissions are mandatory for your request them at same time.

 if (!checkPermission(readPermission) || !checkPermission(writePermission)) {
        requestPermission(new String[] {readPermission,writePermission});        
  } else{
    //Run Async task directly since the permissions are already granted
  }



private void requestPermission(String[] permissions){
    if (ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[0])||ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[1])){
        Toast.makeText(getApplicationContext(), "Read/Write external storage permission allows us to read/write data. Please allow in App Settings for additional functionality.",Toast.LENGTH_LONG).show();
    }
    ActivityCompat.requestPermissions(this, permissions,PERMISSION_REQUEST_CODE);
}

ActivityCompat.requestPermissions(this, permissions, requestCode);

Move the AsyncTask execution to onRequestPermissionsResult as follows:

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case PERMISSION_REQUEST_CODE:
            if (verifyGrantResults(grantResults)) {
                Toast.makeText(getApplicationContext(), "Permission Granted. Now you can read/write data.",
                        Toast.LENGTH_LONG).show();
                        //start Async Task here
            } else {
                Toast.makeText(getApplicationContext(),"Permission Denied. You cannot read/write data.",
                        Toast.LENGTH_LONG).show();
            }
            break;
    }
}

private boolean verifyGrantResults(final int[] grantResults) {
        boolean permissionsGranted = true;
        if (grantResults.length > 0) {
            for (int result : grantResults) {
                if (result == PackageManager.PERMISSION_DENIED) {
                    permissionsGranted = false;
                }
            }
            return permissionsGranted;
        }
        return false;
    }