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?


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

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)

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

    }
}

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

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


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
            }
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.