Подтвердить что ты не робот

Запросить разрешения во время выполнения из v4.Fragment и вернуть обратный вызов в Fragment?

У меня возникла странная проблема, которая вызывает конфликт. Мне пришлось переключиться на native Fragments, чтобы исправить это, но есть ошибки с этим.

Моя первоначальная проблема: у меня есть настройка ящика для навигации с помощью v4 Fragments. Чтобы запросить разрешение в одном из моих фрагментов, я вызываю ActivityCompat.requestPermissions(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION, 1); Свидание отображается просто отлично, но когда я принимаю или отклоняю разрешение, ничего не происходит. Обратный вызов onRequestPermissionsResult() никогда не вызывается. Вместо этого он вызывает в Activity, к которому привязаны мои фрагменты. Бесполезный для меня, мне нужен обратный вызов для работы во Фрагменте.

С учетом этого мне сказали, что мне нужно использовать FragmentCompat, но это работает только с native Fragments (v13+), поэтому я изменил навигационный ящик для работы с родными фрагментами, а не с библиотекой поддержки V4 Fragments. Однако, поскольку я использую AppCompatActivity, некоторые вещи не работают, например addToBackStack() и возвращаются к предыдущему фрагменту.

Короче говоря, кто-нибудь знает, как я могу использовать v4.Fragment и все еще вызывать разрешение в Fragment и получить обратный вызов в Fragment? Я чувствую, что это ошибка в Android, которая не была устранена, но я не на 100%.

Дайте мне знать, если вам нужно увидеть мой код, это просто стандартные методы, необходимые для разрешений времени выполнения, я хотел бы работать с фрагментами V4, хотя это не работает из моего понимания.

4b9b3361

Ответ 1

Такое поведение, по-видимому, присутствует в классе поддержки фрагмента v4 [1]. Реализации Activity/FragmentCompat существуют для людей, которые хотят использовать родные классы с расширенной функциональностью на уровнях API между 11 и 23.

Ответ 2

Добавление этого в родительскую активность работает для меня:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    List<Fragment> fragments = getSupportFragmentManager().getFragments();
    if (fragments != null) {
        for (Fragment fragment : fragments) {
            fragment.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
}

Источник: https://code.google.com/p/android/issues/detail?id=189121#c5

Ответ 3

Если вам нужно получить разрешениеResult в fragment v4, убедитесь, что вы используете

Fragment.requestPermission(String[], int);

вместо

AppCompat.requestPermission(Activity, String[], int)

Обратите внимание на этот ответ!

Ответ 4

Вы можете использовать эту часть кода

requestPermissions(new String[]{Manifest.permission.GET_ACCOUNTS}, PERMISSION_REQUEST_CODE);

Ответ 5

В последнее время я столкнулся с такой же ситуацией, когда мне нужно было проверить разрешение внутри фрагмента поддержки и получить там обратный вызов.

Мне удалось использовать ContextCompat to checkSelfPermission, а затем, как @NasaGeek, вызвал android.support.v4.app.Fragment requestPermissions, чтобы запросить разрешение, а затем получил обратный вызов onRequestPermissionsResult в фрагменте v4.

Надеюсь, это поможет.

Спасибо.

Ответ 6

v4. Фрагмент работает хорошо. У меня проблема с вложенным фрагментом v4.Fragment. Требуется разрешение, но обратный вызов onRequestPermissionsResult() никогда не вызывается во вложенном фрагменте!

Проблема открыта

Ответ 7

В настоящее время наиболее устойчивое решение делает это вручную. Я сам решил это просто, уведомив дочерние фрагменты из родительских фрагментов.

if (fragment.getParentFragment() != null) {
                            Fragment parentFragment = fragment.getParentFragment();
                            try {
                                ChildFragmentPermissionRegistry registry = (ChildFragmentPermissionRegistry) parentFragment;
                                registry.registerPermissionListener((ChildFragmentPermissionCallback) fragment);
                                parentFragment.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_REQUEST_CODE);
                            } catch (ClassCastException e) {
                                Log.e(PermissionVerifier.class.getSimpleName(), e.getMessage());
                            }
                        } else {
                            fragment.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_REQUEST_CODE);
                        }

Где родительский фрагмент реализует интерфейс ChildFragmentPermissionRegistry и регистрирует дочерний фрагмент,

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (callback != null) {
        callback.onRequestPermissionsResult(requestCode, permissions, grantResults);
        callback = null;
    }
}

и дочерние фрагменты реализуют ChildFragmentPermissionCallback

и интерфейсы - это примерно так:

public interface ChildFragmentPermissionCallback {
    void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults);
}

public interface ChildFragmentPermissionRegistry {
    void registerPermissionListener(ChildFragmentPermissionCallback callback);
}

Ответ 8

Просто используйте requestPermission ( "ваше разрешение /s в массиве строк", ваш код запроса) просто не нужно использовать Fragment.requestPermissons(String[],int );

Этот метод в вашем фрагменте вызывает requestPermissions android.support.v4.app.Fragment class i.e

public final void requestPermissions(@NonNull String[] permissions, int requestCode) {
        if (mHost == null) {
            throw new IllegalStateException("Fragment " + this + " not attached to Activity");
        }
        mHost.onRequestPermissionsFromFragment(this, permissions, requestCode);
    }