Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is onResume called after onRequestPermissionsResult?

I run into some problems with the android permissions. The problem is that onResume get called every time onRequestPermissionsResult has been called even if the user already said "Never ask again".

An example:

  @Override
  public void onResume() {
    super.onResume();
    startLocationProvider();
  }

  private void startLocationProvider() {
    if ( !locationService.requestLocationPermission( this, 0 ) ) {
      return;
    }

  @Override
  public void onRequestPermissionsResult( int requestCode, String[] permissions, int[] grantResults ) {
    if ( requestCode == 0 ) {
      if ( grantResults.length == 1 && grantResults[ 0 ] == PackageManager.PERMISSION_GRANTED ) {
        startLocationProvider();
      }
    }

It works fine until the user select "Never ask again" and deny. I don't know why onResume is called again and again although no dialog is shown to the user.

like image 357
user3005267 Avatar asked Feb 04 '16 15:02

user3005267


3 Answers

You need to make use of shouldShowRequestPermissionRationale as part of your conditional checks after checking for permissions.

onResume is called to allow you to sample the results of that permission check.

Here is a snipped of what I have for a project I am working on:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    if (grantResults.length > 0) {
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // Permission Granted
            pickDownloadFolder();
        } else if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
            // Permission Denied
            if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                result = "PERMISSION_DENIED";
                Intent returnIntent = new Intent();
                returnIntent.putExtra(resultKey, result);
                setResult(RESULT_CANCELED, returnIntent);
                finish();
            } else {
                result = "PERMISSION_DENIED_FORCED";
                Intent returnIntent = new Intent();
                returnIntent.putExtra(resultKey, result);
                setResult(RESULT_CANCELED, returnIntent);
                finish();
            }
        }
    }
}
like image 186
avluis Avatar answered Nov 13 '22 16:11

avluis


Have you tried moving your permission request to onStart instead of onResume?

like image 34
Zeek Aran Avatar answered Nov 13 '22 17:11

Zeek Aran


According to Simone's answer:

The onResume get called since the permission dialog causes your activity get paused.

The correct chain of events is the following:

  1. You call requestPermissions in the Activity's onCreate

  2. requestPermissions start running in another thread, because it is designed to not block the UI thread. So your activity goes through onStart and then onResume

  3. the request of the permission generates a dialog, which fires onPause on the Activity, because it is no more in foreground position.

  4. The activity at this moment is paused and you can see a dialog asking to allow or deny the permission.

  5. You make your choice, the dialog gets resolved and onResume is called on the Activity.

Also notice that the onPause is fired by the dialog always after onStart and onResume of the Activity, no matter how long it takes to execute the code in them.

And now you can also see why you shouldn't put requestPermissions in onResume.

like image 1
Duy Pham Avatar answered Nov 13 '22 17:11

Duy Pham