Почему onResume вызывается после onRequestPermissionsResult?

Я столкнулся с некоторыми проблемами с разрешениями андроида. Проблема в том, что onResume вызывается каждый раз, когда onRequestPermissionsResult вызывается, даже если пользователь уже сказал "Никогда не спрашивать снова".

Пример:

  @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();
      }
    }

Он отлично работает, пока пользователь не выберет "Никогда не спрашивать снова" и отрицает. Я не знаю, почему onResume вызывается снова и снова, хотя пользователю не отображается диалог.

Ответ 1

Вам нужно использовать shouldShowRequestPermissionRationale как часть ваших условных проверок после проверки разрешений.

onResume вызывается, чтобы вы могли пробовать результаты проверки этого разрешения.

Вот отрывок из того, что у меня есть для проекта, над которым я работаю:

@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();
            }
        }
    }
}

Ответ 2

Вы пытались переместить запрос на разрешение на onStart вместо onResume?

Ответ 3

Согласно Симоне ответ:

onResume так как диалоговое окно разрешений приводит к приостановке вашей активности.

Правильная цепочка событий следующая:

  1. Вы вызываете requestPermissions в Активности наСоздать

  2. requestPermissions запускается в другом потоке, потому что он разработан, чтобы не блокировать поток пользовательского интерфейса. Таким образом, ваша активность проходит через OnStart, а затем OnResume

  3. запрос разрешения генерирует диалог, который запускает onPause для Activity, потому что он больше не находится на переднем плане.

  4. Активность в этот момент приостановлена, и вы можете увидеть диалоговое окно с просьбой разрешить или запретить разрешение.

  5. Вы делаете свой выбор, диалог разрешается, и onResume вызывается в Activity.

Также обратите внимание, что onPause запускается диалогом всегда после onStart и onResume Activity, независимо от того, сколько времени требуется для выполнения кода в них.

И теперь вы также можете увидеть, почему вы не должны помещать requestPermissions в onResume.