Niepoprawne requestCode w onActivityResult

310

Rozpoczynam nową aktywność od mojego fragmentu za pomocą

startActivityForResult(intent, 1);

i chcę obsłużyć wynik w nadrzędnej aktywności Fragmentu:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d(TAG, "onActivityResult, requestCode: " + requestCode + ", resultCode: " + resultCode);
    if (requestCode == 1) {
        // bla bla bla
    }
}

Problem polega na tym, że nigdy nie dostałem tego requestCode, co właśnie wysłałem startActivityForResult().

Mam coś podobnego 0x40001, 0x20001itd o losowej wyżej ustawionym bitem. Dokumenty nic o tym nie mówią. Jakieś pomysły?

Dimanoid
źródło

Odpowiedzi:

837

Dzwonisz startActivityForResult()ze swojego Fragment. Gdy to zrobisz, requestCodezostanie zmieniony przez Activitywłaściciela Fragment.

Jeśli chcesz uzyskać prawidłową resultCodeaktywność, spróbuj:

Zmiana:

startActivityForResult(intent, 1);

Do:

getActivity().startActivityForResult(intent, 1);
Changwei Yao
źródło
44
Ponieważ powinien zdecydować, który fragment dostarczy wynik. Więc kiedy Fragment wywoła StartActivityForResult. kod żądania zostanie zmieniony przez działanie, dzięki czemu będzie wiedział, jak dostarczyć wynik do którego fragmentu. jeśli naprawdę chcesz uzyskać wynik w Activiy. wystarczy wywołać getActivity (). startActivityForResult ().
Changwei Yao,
31
Tylko uwaga: jeśli używasz startActivityForResultfragmentu i oczekujesz wyniku z onActivityResulttego fragmentu, po prostu upewnij się, że wywołujesz super.onActivityResultdziałanie hosta (na wypadek, gdybyś tam zastąpił tę metodę). Wynika to z tego, że aktywność onActivityResultwywołuje fragment onActivityResult. Zauważ też, że kod żądania, gdy przechodzi przez działanie onActivityResult, jest zmieniany, jak wyjaśniono w linku, który Dimanoid opublikował w swojej odpowiedzi poniżej. Być może nie musisz tego wiedzieć, ale nigdy nie wiesz ...
Ferran Maylinch
31
„Kod żądania został zmieniony przez działanie, które jest właścicielem fragmentu” - Uwielbiam projekt Androida ...
Tiago,
13
Tak ważna informacja, że ​​nigdzie nie można znaleźć wyraźnych dokumentów. Uwielbiam design Androida zaprojektowany, aby Twoje życie było piekłem.
Driss Bounouar
2
Człowieku, kocham cię, spędziłem wiele dni próbując zrozumieć ten problem i naprawić błąd, dzięki!
tinyCoder,
35

Kod żądania nie jest zły. Podczas korzystania z fragmentów biblioteki obsługi v4, indeks fragmentów jest kodowany w 16 górnych bitach kodu żądania, a kod żądania w dolnych 16 bitach. Indeks fragmentów jest później wykorzystywany do znalezienia odpowiedniego fragmentu, aby dostarczyć wynik.

Stąd dla działań rozpoczętych z fragmentu obiektu, obsłuż onCode onActivityResult requestCode jak poniżej:

originalRequestCode = changedRequestCode - (indexOfFragment << 16)
      6             =      196614        -       (3 << 16)
Ashlesha Sharma
źródło
1
Świetna informacja, która wyjaśnia dokładną przyczynę tego problemu
Muzikant,
szybkie pytanie: co to jest indexOfFragment?
Louis Tsai,
indexOfFragment to indeks tworzony przez getSupportFragmentManager (). getFragments () tworzy
HerberthObregon
25

Łatwiej:

Java : int unmaskedRequestCode = requestCode & 0x0000ffff

Kotlin : val unmaskedRequestCode = requestCode and 0x0000ffff

Sprawdź dolne 16 bitów, po prostu zdemaskuj to logicznie ORAZ z górnymi 16 bitami wyzerowanymi

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    final int unmaskedRequestCode = requestCode & 0x0000ffff

    if(unmaskedRequestCode == ORIGINAL_REQUEST_CODE){
      //Do stuff

    }
}
Jaime Agudo
źródło
1
Czy możesz mi powiedzieć, dlaczego nie podałeś oryginalnego kodu żądania?
K.Sopheak,
3
Ponieważ kod requestCode został zmieniony przez działanie, które jest właścicielem fragmentu. Zobacz odpowiedź Ashlesha Sharma
Jaime Agudo,
dziękuję, to była odpowiedź, której szukałem. Nie rozumiem jednak, dlaczego Android nie powinien zwracać oryginalnego kodu żądania.
tonisives
Było to dla mnie niezwykle pomocne i naprawdę bardzo ładnie wyjaśnia problem. Dzięki!
Billy Lazzaro,
6

Jeśli zapewniasz stałą, upublicznij ją, a następnie użyj w startActivityResult

przykład:

public static final int REQUEST_CODE =1;
getActivity().startActivityForresult(intent, REQUEST_CODE);
Nilesh Tiwari
źródło
2

Możesz także zdefiniować
super.onActivityResult(requestCode, resultCode, data)
w Activity(jeśli przesłonisz onActivityResult)

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {

        ...

        default:
            super.onActivityResult(requestCode, resultCode, data);
    }
}

i zadzwoń startActivityForResult(intent, requestCode)do twojegoFragment

TarikW
źródło
0

we fragmencie

  getActivity().startActivityForResult(builder.build(getActivity()), PLACE_PICKER_REQUEST);

w głównej działalności:

if (requestCode == PLACE_PICKER_REQUEST) {
            if (resultCode == RESULT_OK) {    
     //what ever you want to do
            }
Wyjątek wskaźnika zerowego
źródło