RequestCode incorrecto en onActivityResult

310

Estoy comenzando una nueva Actividad desde mi Fragmento con

startActivityForResult(intent, 1);

y desea manejar el resultado en la Actividad principal del Fragmento:

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

El problema es que nunca recibí el requestCodeque acabo de publicar startActivityForResult().

Obtuve algo como 0x40001, 0x20001etc. con un conjunto de bits aleatorio más alto. Los documentos no dicen nada sobre esto. ¿Algunas ideas?

Dimanoide
fuente
posible duplicado de onActivityResult no ser llamado en Fragmento
PhoneixS

Respuestas:

837

Estás llamando startActivityForResult()desde tu Fragment. Cuando haces esto, requestCodeel Activityque posee el cambia el Fragment.

Si desea obtener lo correcto resultCodeen su actividad, intente esto:

Cambio:

startActivityForResult(intent, 1);

A:

getActivity().startActivityForResult(intent, 1);
Changwei Yao
fuente
44
Porque debería decidir a qué fragmento entregará el resultado. Entonces, cuando The Fragment llame a StartActivityForResult. La actividad cambiará el requestCode, por lo que sabrá cómo entregar el resultado a ese fragmento. si realmente quieres obtener el resultado en la Activiy. simplemente llame a getActivity (). startActivityForResult ().
Changwei Yao
31
Solo una nota: si usa startActivityForResultun fragmento y espera el resultado de onActivityResultese fragmento, solo asegúrese de llamar super.onActivityResulta la actividad del host (en caso de que anule ese método allí). Esto se debe a que la actividad onActivityResultparece llamar al fragmento onActivityResult. Además, tenga en cuenta que el código de solicitud, cuando viaja a través de la actividad onActivityResult, se modifica como se explica en el enlace que Dimanoid publicó en su respuesta a continuación. Puede que no necesite saber eso, pero nunca se sabe ...
Ferran Maylinch
31
"La actividad que posee el Fragmento cambia el código de solicitud" - Me encanta el diseño de Android ...
Tiago
13
Una información tan importante que no puedes encontrar nada claro en los documentos. Debo amar el diseño de Android diseñado para hacer de tu vida un infierno.
Driss Bounouar
2
Hombre, te amo, pasé muchos días tratando de entender este problema y corregir el error, ¡gracias!
tinyCoder
35

El código de solicitud no es incorrecto. Cuando se usan fragmentos de la biblioteca de soporte de v4, el índice de fragmento se codifica en los 16 bits superiores del código de solicitud y su código de solicitud se encuentra en los 16 bits inferiores. El índice de fragmentos se usa más tarde para encontrar el fragmento correcto para entregar el resultado.

Por lo tanto, para las actividades iniciadas en el objeto de fragmento de formulario, maneje onActivityResult requestCode como se muestra a continuación:

originalRequestCode = changedRequestCode - (indexOfFragment << 16)
      6             =      196614        -       (3 << 16)
Ashlesha Sharma
fuente
1
Gran información que explica la causa exacta de este problema
Muzikant
pregunta rápida: ¿qué es indexOfFragment?
Louis Tsai
indexOfFragment es el índice que produce getSupportFragmentManager (). getFragments ()
HerberthObregon
25

Más fácil:

Java : int unmaskedRequestCode = requestCode & 0x0000ffff

Kotlin : val unmaskedRequestCode = requestCode and 0x0000ffff

Verifique los 16 bits inferiores, simplemente desenmascare haciendo un AND lógico con los 16 bits superiores puestos a cero

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

    final int unmaskedRequestCode = requestCode & 0x0000ffff

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

    }
}
Jaime Agudo
fuente
1
¿Me puede decir la razón por la que no da el código de solicitud original?
K.Sopheak
3
Porque la actividad que posee el Fragmento cambia el requestCode. Ver la respuesta de Ashlesha Sharma
Jaime Agudo
gracias, esta es la respuesta que estaba buscando. Sin embargo, no veo por qué Android no debería devolver el código de solicitud original.
tonisives
Esto fue inmensamente útil para mí hoy y en realidad explica muy bien el problema. ¡Gracias!
Billy Lazzaro
6

Si está proporcionando constante, hágalo público y luego úselo en startActivityResult

ejemplo:

public static final int REQUEST_CODE =1;
getActivity().startActivityForresult(intent, REQUEST_CODE);
Nilesh Tiwari
fuente
2

También puede definir
super.onActivityResult(requestCode, resultCode, data)
en Activity(si anula onActivityResult) en este

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

        ...

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

y llama startActivityForResult(intent, requestCode)dentro de tuFragment

TarikW
fuente
0

en fragmento

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

en Actividad Principal:

if (requestCode == PLACE_PICKER_REQUEST) {
            if (resultCode == RESULT_OK) {    
     //what ever you want to do
            }
Excepción de puntero nulo
fuente