Разрешение среды выполнения Android вызывает тот же фрагмент после принятия или отклонения разрешения

#android #android-fragments #android-permissions #android-dialogfragment

#Android #android-фрагменты #android-разрешения #android-dialogfragment

Вопрос:

Привет, ребята,

У меня есть активность с компонентом «BottomNavigationView», и в этом компоненте у меня есть четыре фрагмента. Когда я нажимаю, например, на второй фрагмент и нажимаю кнопку «Дать разрешение», появляется всплывающее окно для получения разрешения во время выполнения для записи и чтения внешнего хранилища.

Когда я принимаю или отклоняю разрешение во время выполнения, приложение автоматически выполняет обратный вызов MainActivity и показывает первый фрагмент по умолчанию (потому что первый фрагмент является фрагментом по умолчанию в Main Activitiy).

Возможно ли после принятия или отклонения остаться на втором фрагменте? Или мне нужно, например, сохранить в позиции sharedpreference мой фрагмент и пригласить фрагмент в эту позицию.

Я пробовал с libhttps://github.com/googlesamples/easypermissions. После успешного завершения я попытался получить разрешение с помощью пользовательской реализации.

Вот мой код.

 private static final int REQUEST_CODE = 121;
private void requiredUserPermissionForDownloadPDF(){
    if(!permissionAlreadyGranted()){
        requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE);
    }
}


private boolean permissionAlreadyGranted() {
    String[] perms = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
    for (String permission : perms) {
        if (ContextCompat.checkSelfPermission(getContext(), permission) != PackageManager.PERMISSION_GRANTED) {
            return false;
        }
    }
    return true;
}

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

    if (requestCode == REQUEST_CODE
            amp;amp; grantResults[0] == PackageManager.PERMISSION_GRANTED
            amp;amp; grantResults[1] == PackageManager.PERMISSION_GRANTED) {
        System.out.println("Granted");
    }
}
  

Возможно ли после принятия или отклонения остаться на втором фрагменте? Или мне нужно, например, сохранить в позиции sharedpreference мой фрагмент и пригласить фрагмент в эту позицию.

Ответ №1:

У меня была такая же проблема, это происходит из-за повторного создания activity. Вы должны сохранить выбранный идентификатор элемента из BottomNavigationView в onSaveInstanceState методе, подобном этому:

 @Override
protected void onSaveInstanceState(Bundle outState) {
    outState.putInt(KEY_BOT_NAV_VIEW_SELECTED_ITEM_ID, mBottomNavigationView.getSelectedItemId());
    super.onSaveInstanceState(outState);
}
  

Где KEY_BOT_NAV_VIEW_SELECTED_ITEM_ID — строковый ключ для сохранения и извлечения идентификатора. Затем, после этого, когда ваше действие создается снова и protected void onCreate(Bundle savedInstanceState) вызывается, аргумент bundle не равен null, и вы можете получить сохраненный идентификатор:

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mBottomNavigationView.setOnNavigationItemSelectedListener(this);
    if (savedInstanceState != null) {
        restoreInstanceState(savedInstanceState);
    } else {
        //show first fragment fragment 
    }
}
  

Вы можете узнать больше о сохранении и восстановлении состояния здесь

Комментарии:

1. Спасибо за ответ. Да, будет тот же эффект, если я использую savedInstanceState или SharedPreference. Но разве это невозможно без этих советов и хитростей? Этот метод onRequestPermissionsResult вызывает Activity. Я не знаю, возможно ли переопределить этот метод для фрагмента или это всегда действие вызова.

2. если вы будете использовать SharedPreference для этой цели, вы не будете знать, когда сохранять состояние, так как on destroy будет вызываться каждый раз, когда действие будет завершено. Но когда вы используете onSaveInstanceState — вы будете точно знать, что необходимо сохранить текущий фрагмент

3. onSaveInstanceState предназначено для этой цели — сохранения и восстановления состояния при завершении или перезапуске процесса приложения. Взгляните на ссылку, которую я предоставил, там есть довольно хорошее объяснение по этому поводу

4. ОК. Спасибо за ответ 🙂

5. @Mirko, я не заметил вашего вопроса об onRequestPermissionsResult раньше. Если вы вызовете requestPermissions в своем классе Fragment — вы получите onRequestPermissionsResult во Fragment. Убедитесь, что ваше действие вызывает super.onRequestPermissionsResult, если вы переопределите его

Ответ №2:

Вы запрашиваете разрешение у второго фрагмента или у действия? При запросе из фрагмента он остается внутри фрагмента.

Комментарии:

1. Я запрашиваю у фрагмента. Моя проблема была решена, когда я удалил метод onResume () из MainActivity и выполнил всю свою работу в методе onCreate ().