onRequestPermissionsResult nie jest wywoływany we fragmencie, jeśli jest zdefiniowany zarówno w fragmencie, jak i aktywności

167

Mam fragment, w którym mam przegląd recyklingu i ustawienia danych w tym widoku recyklingu przy użyciu adaptera recyklingu.

Teraz mam przycisk w elemencie listy adaptera, po kliknięciu którego muszę sprawdzić uprawnienie READ_EXTERNAL_STORAGE w systemie Android, aby uzyskać nowy model uprawnień w systemie Android.

Utworzyłem nową funkcję we fragmencie tego adaptera, aby sprawdzić, czy zezwolenie zostało udzielone, czy nie, i poprosić o pozwolenie, jeśli nie zostało już przyznane.

Przekazałem MyFragment.this jako parametr w adapterze i wywołałem metodę fragmentu po kliknięciu przycisku w adapterze.

Użyłem poniższego kodu, aby wywołać requestPermission fragmentem.

if(ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED){
       requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                ConstantVariables.READ_EXTERNAL_STORAGE);
    }

Zastąpiłem onRequestPermissionsResultmetodę we fragmencie, używając poniższego kodu:

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case ConstantVariables.READ_EXTERNAL_STORAGE:
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, proceed to the normal flow.
                startImageUploading();
            } else {}

Ale nie jest wywoływana, zamiast metody onRequestPermissionsResult tego działania jest wywoływana.

Zdefiniowałem tę samą metodę onRequestPermissionsResult również w aktywności nadrzędnej fragmentu i jest ona wywoływana.

Nie mogę usunąć metody onRequestPermissionsResult działania, ale chcę wywołać metodę onRequestPermissionsResult fragmentu, gdy żądam pozwolenia od fragmentu. W jaki sposób mogę to zrobić? Czy robię coś źle, pomóż mi, jeśli ktoś ma tutaj pomysł.

Prithniraj Nicyone
źródło
1
odwołaj się do tego linku uprawnienia czasu wykonywania we fragmencie To jest dokładne rozwiązanie
Antony jackson

Odpowiedzi:

372

Zredagowana odpowiedź obejmująca szersze zagadnienia

Myślę, że mylisz metodę fragmentacji i aktywności. Miałem podobny problem z moim projektem w zeszłym miesiącu. Sprawdź, czy masz wreszcie:

  1. W AppCompatActivity użyj metody ActivityCompat.requestpermissions
  2. We fragmencie wsparcia v4 powinieneś używać requestpermissions
  3. Catch polega na tym, że jeśli wywołasz AppcompatActivity.requestpermissions w swoim fragmencie, wywołanie zwrotne przyjdzie do działania, a nie fragmentu
  4. Pamiętaj, aby zadzwonić super.onRequestPermissionsResultz aktywności onRequestPermissionsResult.

Zobacz, czy to pomaga.

VarunJoshi129
źródło
9
Aby dokładnie sprawdzić, upewnij się, że masz super.onrequestpermissionresult ustawione w swojej działalności
VarunJoshi129
27
Dodanie super.onrequestpermissionresultonrequestpermissionresult działania do wywołania fragmentu onrequestpermissionresult, gdy poproszę o pozwolenie na użycie requestpermissions. Teraz działa dobrze, dziękuję bardzo .. :)
Prithniraj Nicyone
1
W wywołaniu zwrotnym aktywności brakowało wyniku super.onrequestpermissionres, co spowodowało, że moje wywołanie zwrotne fragmentu nie zostało wywołane
sakis kaliakoudas
4
requestPermissions () wymaga interfejsu API na poziomie 23. Czy istnieje inne rozwiązanie, które jest wstecznie kompatybilne z interfejsem API na poziomie 21?
Adam Hurwitz
2
@ msc87 1. w onRequestPermissionsResult aktywności i fragmentu pierwsza linia powinna mieć postać : super.onRequestPermissionsResult (requestCode, permissions, grantResults); 2. we fragmencie, w którym rozpoznajesz uprawnienia, które nie zostały przyznane, po prostu wywołaj metodę requestPermission w następujący sposób: requestPermissions (nowy ciąg [] {Manifest.permission.CALL_PHONE}, MY_PERMISSIONS_REQUEST_CALL_PHONE);
AREF
122

Poprosiłem o pozwolenie na lokalizację z fragmentu i we fragmencie musiałem to zmienić:

            ActivityCompat.requestPermissions(getActivity(), new String[]{
                Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_REQ_CODE);

do tego:

            requestPermissions(new String[]{
                Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_REQ_CODE);

następnie we fragmencie wywołano onRequestPermissionsResult.

Badr
źródło
2
Działa jak urok :)
Antonio Vlasic
1
to nie działa z kotlin, czy możesz mi pomóc w tym samym tutaj jest używane to żądaniePermissions (kontekst jak Activity, PermissionsList.toTypedArray (), MY_PERMISSIONS_REQUEST)
Arbaz.
Dzięki :), oszczędzasz mój czas
Axrorxo'ja Yodgorov
19

Jest to częsty błąd, który ludzie popełniają podczas kodowania ptasie mleczko.

Kiedy jesteś w AppCompatActivity, powinieneś użyć ActivityCompat.requestPermissions; W android.support.v4.app.Fragment powinieneś użyć po prostu requestPermissions (jest to metoda instancji android.support.v4.app.Fragment) Jeśli wywołasz ActivityCompat.requestPermissions we fragmencie, wywołanie zwrotne onRequestPermissionsResult jest aktywność, a nie fragment.

requestPermissions(permissions, PERMISSIONS_CODE);

Jeśli wywołujesz ten kod z fragmentu, ma on własną metodę requestPermissions.

Tak więc podstawowa koncepcja brzmi: jeśli bierzesz udział w działaniu, zadzwoń

ActivityCompat.requestPermissions(this,
                            new String[]{Manifest.permission.CAMERA},
                            MY_PERMISSIONS_REQUEST_CAMERA);

a jeśli we fragmencie, po prostu zadzwoń

requestPermissions(new String[]{Manifest.permission.CAMERA},
                            MY_PERMISSIONS_REQUEST_CAMERA);

W celach informacyjnych otrzymałem odpowiedź z tego linku https://www.coderzheaven.com/2016/10/12/onrequestpermissionsresult-not-called-on-fragments/

Farruh Habibullaev
źródło
6

Metoda requestPermissionsna fragmentach wymaga interfejsu API na poziomie 23 lub wyższym.
Jeśli Twoja aplikacja jest przeznaczona dla niższej wersji, możesz użyć

FragmentCompat.requestPermissions(this,
            new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
            ConstantVariables.READ_EXTERNAL_STORAGE);

Najpierw musisz dodać zależność support-v13:

implementation "com.android.support:support-v13:$supportLibVersion"
Juan Cruz Soler
źródło
FragmentCompat jest przestarzały z wersji 27.1.0
Raj kannan Iyyappan
6

Zmień to :

ActivityCompat.requestPermissions(
    activity,
    arrayOf(Manifest.permission.READ_CONTACTS),
    PERMISSIONS_REQUEST_READ_CONTACTS
)

do tego :

requestPermissions(
     arrayOf(Manifest.permission.READ_CONTACTS),
     PERMISSIONS_REQUEST_READ_CONTACTS
)
opóźnienieKg
źródło
Niższa jest do użycia we fragmencie (onRequestPermissionsResult jest wywoływana we fragmencie), wersja ActivityCompat jest używana, gdy onRequestPermissionsResult znajduje się w działaniu.
Roar Grønmo
1
private void showContacts() {
 if (getActivity().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
         != PackageManager.PERMISSION_GRANTED) {
     requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
             PERMISSIONS_REQUEST_READ_STORAGE);
 } else {
     doShowContacts();
 }
}

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

zmienić uprawnienia

user2002721
źródło
2
Cześć user2002721; Twój kod może być poprawny, ale w pewnym kontekście dałby lepszą odpowiedź; na przykład, możesz wyjaśnić, w jaki sposób i dlaczego ta proponowana zmiana miałaby rozwiązać problem pytającego, być może dołączając link do odpowiedniej dokumentacji. To uczyniłoby go bardziej użytecznym dla nich, a także bardziej przydatnym dla innych czytelników witryny, którzy szukają rozwiązań podobnych problemów.
Vince Bowdren,
Program może zgłosić tablicę poza granicami wyjątku, jeśli spróbujesz uzyskać dostęp do indeksu 0 w grantResults bez uprzedniego sprawdzenia długości. Stało się to z moim programem. Oddzieliłem instrukcję if dla grantResults jako wewnętrzną instrukcję if, aby temu zapobiec, i teraz działa dobrze.
Peter Griffin,
1

Ta zaakceptowana odpowiedź nie działa dla mnie, więc znalazłem własne rozwiązanie, wyjaśnione poniżej:

1. Najpierw stworzyłem metodę, we fragmencie:

public static void MyOnRequestPermissionResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults){
        if (requestCode == 1 && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            Log.d(TAG, "Permission: true");
        } else {
            Log.d(TAG, "permission: false");
        }
}

2. a następnie nazwał to na podstawie jego podstawowej działalności:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if(requestCode ==1){
        SignupFragment.MyOnRequestPermissionResult(requestCode, permissions, grantResults);
    }
}

I to działa ...

Biplob Das
źródło
0

Sprawdź, czy zarówno PERMISSION_REQUEST_CODEw, jak onRequestPermissionsResulti wewnątrz pliku Fragmentzawiera tę samą wartość.

dianakarenms
źródło
0

W przypadku tragetu SDK 28 działałoby sprawdzenie SDK (> 23) i requestpermissions from fragment. Działanie ActivityCompat.requestPermissions nie powiedzie się (jeśli ustawisz kod żądania poniżej 65536, pojawi się okno dialogowe uprawnień i jeśli użytkownik zezwoli na zezwolenie, uprawnienia są zapewnione, ale nie nastąpi wywołanie zwrotne. Jeśli jednak ustawisz wartość powyżej 65536, funkcja ActivityCompat.requestPermissions nie powiodło się natychmiast. Nie znam powodu tej logiki. może to być błąd lub celowo).

Kod roboczy:

  if (Build.VERSION.SDK_INT >= 23) {
                        requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_ACCESS_REQUEST);
                    }
Raj kannan Iyyappan
źródło
nie musisz sprawdzać wersji. w wersjach poniżej 23. zwróci tylko wartość „udzielono pozwolenia”. Wybór programisty tutaj: unikaj bloku „jeśli” dla uproszczenia lub unikaj wywołania żądania, gdy nie jest potrzebne
Psest328
0

Miałem ten sam problem. Twój fragment może zostać zainicjowany z układu aktywności. Tak:

main_activty.xml

<fragment
    android:id="@+id/fragment"
    android:name="com.exampe.SomeFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Ten problem został rozwiązany, gdy FragmentTransactionzamiast tego użyłem

Bohdan Ishchenko
źródło
0

w API poniżej 23 możesz stworzyć interfejs w działaniu, a następnie zaimplementować go we fragmencie potomnym, a gdy otrzymasz prośbę o pozwolenie, aktywność przekaże go do zaimplementowanego interfejsu we fragmencie. To takie proste :)

A.sobhdel
źródło
0

możesz wywołać metodę Fragment poniżej

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode) {
        case REQUEST_CODE:
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0 &&
                    grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission is granted. Continue the action or workflow
                // in your app.
                doActionBecauseNowYouCanBro();
            } else {
                // Explain to the user that the feature is unavailable because
                // the features requires a permission that the user has denied.
                // At the same time, respect the user's decision. Don't link to
                // system settings in an effort to convince the user to change
                // their decision.
                showWhyRequestPermissionsAndDontBlockUserItsCalledManners();
            }
            return;
    }
    // Other 'case' lines to check for other
    // permissions this app might request.

}
MFQ
źródło
-5

Ten problem był w rzeczywistości spowodowany przez NestedFragments. Zasadniczo większość fragmentów rozszerzyliśmy HostedFragment, który z kolei rozszerza CompatFragment. Posiadanie tych zagnieżdżonych fragmentów spowodowało problemy, które ostatecznie zostały rozwiązane przez innego programistę w projekcie.

Robił trochę rzeczy na niskim poziomie, takich jak przełączanie bitów, aby to działało, więc nie jestem zbyt pewien ostatecznego rozwiązania

Manikandan K
źródło
3
Zamiast kopiować odpowiedź, możesz po prostu podać link - stackoverflow.com/a/33081173/630833
jayeffkay