Żądanie uprawnień runtime z wersji 4.Fragment i mieć callback przejść do Fragment?

Mam dziwny problem, który powoduje konflikt. Musiałem przełączyć się na natywny Fragments, aby to naprawić, ale są z tym błędy.

Mój oryginalny problem: mam konfigurację szuflady nawigacyjnej z v4 Fragments., aby poprosić o pozwolenie w jednym z moich fragmentów wywołuję ActivityCompat.requestPermissions(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION, 1); monit pojawia się w porządku, ale kiedy Akceptuję lub odmawiam pozwolenia, nic się nie dzieje. Wywołanie zwrotne onRequestPermissionsResult() nigdy nie jest wywoływane. Zamiast tego zostaje wywołana w aktywności, do której przywiązane są moje fragmenty. Bezużyteczne dla ja, potrzebuję połączenia zwrotnego, żeby zadziałało we fragmencie.

Mając to na uwadze powiedziano mi, że muszę używać FragmentCompat, ale to działa tylko z native Fragments (v13+), więc zmieniłem szufladę nawigacyjną na działającą z fragmentów natywnych zamiast fragmentów biblioteki obsługującej v4. jednak , ponieważ używam AppCompatActivity, pewne rzeczy nie działają, jak addToBackStack() i wracam do poprzedniego fragmentu.

Krótko mówiąc, Czy ktoś wie, jak mogę użyć v4.Fragment i nadal wołać o pozwolenie w Fragment i uzyskać odpowiedź zwrotną, aby być w Fragment? Mam wrażenie, że jest to błąd w Androidzie, który nie został rozwiązany, ale nie jestem w 100%.

Daj mi znać, jeśli chcesz zobaczyć mój kod, to tylko standardowe metody, których potrzebujesz do uprawnień runtime, chciałbym pracować z fragmentami v4, ale które nie działają z mojego zrozumienia.

Author: ROMANIA_engineer, 2015-10-01

10 answers

To zachowanie wydaje się być obecne w klasie obsługi fragmentów V4 requestPermissions in Fragment. Implementacje Activity / FragmentCompat istnieją dla osób, które chcą korzystać z natywnych klas o rozszerzonej funkcjonalności na poziomach API od 11 do 23.

 18
Author: NasaGeek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-06 07:04:42

Dodanie tego do aktywności rodzica działa dla mnie:

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

Źródło: https://code.google.com/p/android/issues/detail?id=189121#c5

 71
Author: Samuel Gaona,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-25 11:47:40

Jeśli chcesz uzyskać pozwolenie w fragment v4 Upewnij się, że używasz

Fragment.requestPermission(String[], int);

Zamiast

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

Sprawdź to odpowiedz!

 19
Author: DoruChidean,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:47

Możesz użyć tej części kodu

requestPermissions(new String[]{Manifest.permission.GET_ACCOUNTS}, PERMISSION_REQUEST_CODE);
 12
Author: Abubakar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-09 19:37:30

Spotkałem się ostatnio z tą samą sytuacją, kiedy musiałem sprawdzić pozwolenie wewnątrz fragmentu wsparcia i uzyskać tam oddzwonienie.

Udało mi się użyć ContextCompat do checkSelfPermission, a następnie, jak powiedział @NasaGeek, wywołał android.support.v4.app.Fragment'S requestPermissions, aby poprosić o pozwolenie, a następnie otrzymał połączenie z powrotem do onRequestPermissionsResult we fragmencie v4.

Mam nadzieję, że to pomoże. Dzięki.
 7
Author: Nitesh Mudireddy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-04 11:24:30

V4.Fragment działa dobrze. Mam problem z zagnieżdżonym fragmentem v4.Fragment. Prośba o pozwolenie, ale wywołanie zwrotne onRequestPermissionsResult() nigdy nie jest wywoływane w zagnieżdżonym fragmencie!

Wydanie otwarte

 3
Author: android_dev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-09 08:11:42

W tej chwili najbardziej stabilnym rozwiązaniem jest zrobienie tego ręcznie. Ja sam rozwiązałem to po prostu powiadamiając fragmenty dziecka z fragmentów rodzica.

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

Gdzie fragment rodzica implementuje interfejs ChildFragmentPermissionRegistry i rejestruje fragment potomny,

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

I fragmenty dzieci implementują ChildFragmentPermissionCallback

A Interfejsy to coś takiego:

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

public interface ChildFragmentPermissionRegistry {
    void registerPermissionListener(ChildFragmentPermissionCallback callback);
}
 3
Author: Szymon Klimaszewski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-16 15:31:37

Nie wiem, czy został ostatnio naprawiony przez google, ale mogę osiągnąć oczekiwany wynik bez robienia żadnych sztuczek.

Najważniejszą rzeczą jest wywołanie super.onRequestPermissionsResult(requestCode, permissions, grantResults); w aktywności, więc przekaże wynik do fragmentu, jeśli jest żądany z fragmentu.

Więc to co robię to:

1) we fragmencie poproś o pozwolenie używając v4 fragment.requestPermissions(permissions, requestCode)

2) w zadaniu zadaniowym, musi wywołać super.onRequestPermissionsResult(requestCode, permissions, grantResults);

3) w fragmencie ' s onRequestPermissionsResult, napisz kod, który chcę poradź sobie z wynikiem.

 1
Author: YunhaoLIU,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-26 13:29:56

W moim przypadku poprosiłem o pozwolenie fragmentu i również muszę uzyskać odpowiedź we fragmencie.

Ale mój telefon działa na Androidzie 8.1

Więc musiałem dodać jeszcze jeden warunek, aby sprawdzić to

Więc w końcu jest moje rozwiązanie

private void doOnWazeButtonClick()
{
    int permissionStatus = PackageManager.PERMISSION_DENIED;

    if (getContext() != null)
    {
        permissionStatus = ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION);
    }

    if (permissionStatus == PackageManager.PERMISSION_GRANTED)
    {
        showContentWaze();
    }
    else
    {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
        {
            Objects.requireNonNull(getActivity()).requestPermissions(new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE_PERMISSION_ACCESS_FINE_LOCATION);
        }
        else
        {
            requestPermissions(new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE_PERMISSION_ACCESS_FINE_LOCATION);
        }
    }
}
 0
Author: Aleksey Timoshchenko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-13 07:48:37

Po prostu użyj requestPermission ("Twoje uprawnienia/s w tablicy łańcuchowej", kod żądania) po prostu nie musisz używać Fragment.requestPermissons(String[],int );

Ta metoda w Twoim fragmencie wywołuje requestPermissions z 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);
    }
 -1
Author: Andrew Coder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-28 11:04:17