Richiesta errata Codice in onActivityResult


310

Sto iniziando una nuova attività dal mio frammento con

startActivityForResult(intent, 1);

e vuoi gestire il risultato nell'attività principale del frammento:

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

Il problema è che non ho mai ricevuto il messaggio a requestCodecui ho appena pubblicato startActivityForResult().

Ho qualcosa del genere 0x40001, 0x20001ecc. Con un bit casuale più alto impostato. I documenti non dicono nulla al riguardo. Qualche idea?


Risposte:


837

Stai chiamando startActivityForResult()dal tuo Fragment. Quando lo fai, il requestCodeviene cambiato dal Activityproprietario del Fragment.

Se vuoi ottenere il corretto resultCodenella tua attività prova questo:

Modificare:

startActivityForResult(intent, 1);

Per:

getActivity().startActivityForResult(intent, 1);

44
Perché dovrebbe decidere a quale frammento consegnerà il risultato. Quindi quando The Fragment chiama StartActivityForResult. il requestCode verrà modificato dall'attività, quindi saprà come consegnare il risultato a quale frammento. se vuoi davvero ottenere il risultato in Activiy. basta chiamare getActivity (). startActivityForResult ().
Changwei Yao,

31
Solo una nota: se si utilizza startActivityForResultin un frammento e ci si aspetta il risultato onActivityResultin quel frammento, assicurarsi di chiamare super.onActivityResultl'attività dell'host (nel caso in cui si ignori quel metodo). Questo perché l'attività onActivityResultsembra chiamare frammento onActivityResult. Inoltre, nota che il codice di richiesta, quando viaggia attraverso l'attività onActivityResult, viene modificato come spiegato nel link che Dimanoid ha pubblicato nella sua risposta di seguito. Potresti non aver bisogno di saperlo ma non lo saprai mai ...
Ferran Maylinch,

31
"il requestCode è cambiato dall'attività che possiede il frammento" - Devo amare il design Android ...
Tiago

13
Un'informazione così importante, che non puoi trovare da nessuna parte nei documenti. Devi amare il design Android progettato per rendere la tua vita un inferno.
Driss Bounouar,

2
Amico, ti ho trascorso molti giorni cercando di capire questo problema e correggere l'errore, grazie!
tinyCoder

35

Il codice di richiesta non è sbagliato. Quando si utilizzano frammenti della libreria di supporto v4, l'indice di frammento viene codificato nei primi 16 bit del codice di richiesta e il codice di richiesta si trova nei 16 bit di fondo. L'indice di frammento viene successivamente utilizzato per trovare il frammento corretto per fornire il risultato.

Quindi per le attività avviate dall'oggetto frammento, gestire onActivityResult requestCode come di seguito:

originalRequestCode = changedRequestCode - (indexOfFragment << 16)
      6             =      196614        -       (3 << 16)

1
Grandi informazioni che spiegano la causa esatta di questo problema
Muzikant,

domanda veloce: che cos'è indexOfFragment?
Louis Tsai

indexOfFragment è l'indice prodotto da getSupportFragmentManager (). getFragments ()
HerberthObregon

25

Più facile:

Java : int unmaskedRequestCode = requestCode & 0x0000ffff

Kotlin : val unmaskedRequestCode = requestCode and 0x0000ffff

Controlla i 16 bit inferiori, basta smascherarlo facendo un AND logico con i 16 bit superiori azzerati

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

    final int unmaskedRequestCode = requestCode & 0x0000ffff

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

    }
}

1
Puoi dirmi il motivo per cui non fornisce il codice di richiesta originale?
K.Sopheak, l'

3
Causa il requestCode viene modificato dall'attività proprietaria del frammento. Vedi la risposta di Ashlesha Sharma
Jaime Agudo,

grazie, questa è la risposta che stavo cercando. Tuttavia, non vedo perché Android non debba restituire il codice di richiesta originale.
tonificanti

Questo è stato immensamente utile per me oggi e in realtà spiega il problema davvero bene. Grazie!
Billy Lazzaro,

6

Se stai fornendo costantemente rendilo pubblico e poi usalo in startActivityResult

esempio:

public static final int REQUEST_CODE =1;
getActivity().startActivityForresult(intent, REQUEST_CODE);

2

Puoi anche definire
super.onActivityResult(requestCode, resultCode, data)
in Activity(se esegui l'override onActivityResult) in questo

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

        ...

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

e chiama startActivityForResult(intent, requestCode)dentro di teFragment


0

nel frammento

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

nell'attività principale:

if (requestCode == PLACE_PICKER_REQUEST) {
            if (resultCode == RESULT_OK) {    
     //what ever you want to do
            }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.