Pregunta onActivityResult no se llama en Fragment


La actividad que aloja este fragmento tiene su onActivityResult se llama cuando la actividad de la cámara vuelve.

Mi fragmento inicia una actividad para obtener un resultado con el intento enviado para que la cámara tome una fotografía. La aplicación de imagen se carga bien, toma una foto y regresa. los onActivityResult sin embargo, nunca es golpeado. Establecí puntos de interrupción, pero no se activó nada. ¿Puede un fragmento tener onActivityResult? Creo que sí, ya que es una función provista. ¿Por qué no se activa esto?

ImageView myImage = (ImageView)inflatedView.findViewById(R.id.image);
myImage.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        startActivityForResult(cameraIntent, 1888);
    }
});

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if( requestCode == 1888 ) {
        Bitmap photo = (Bitmap) data.getExtras().get("data");
        ((ImageView)inflatedView.findViewById(R.id.image)).setImageBitmap(photo);
    }
}

685
2018-05-27 04:35


origen


Respuestas:


La actividad de alojamiento anula onActivityResult(), pero no hizo una llamada a super.onActivityResult() para códigos de resultado no controlados. Aparentemente, a pesar de que el fragmento es el que hace la startActivityForResult() llamada, la actividad tiene la primera oportunidad de manejar el resultado. Esto tiene sentido cuando se considera la modularidad de los fragmentos. Una vez que implementé super.onActivityResult() para todos los resultados no controlados, el fragmento tuvo la oportunidad de manejar el resultado.

Y también de la respuesta @siqing:

Para obtener el resultado en su fragmento, asegúrese de llamar startActivityForResult(intent,111); en lugar de getActivity().startActivityForResult(intent,111); dentro de tu fragmento


1034
2018-05-27 04:42



Creo que llamaste getActivity().startActivityForResult(intent,111);. Deberías llamar startActivityForResult(intent,111);.


297
2018-06-13 09:13



Opción 1:

Si llamas startActivityForResult() del fragmento, entonces debes llamar startActivityForResult()no getActivity().startActivityForResult(), ya que dará como resultado un fragmento en ActivityResult ().

Si no está seguro de dónde está llamando startActivityForResult() y cómo llamarás a los métodos.

Opcion 2:

Como Activity obtiene el resultado de onActivityResult(), deberás anular la actividad onActivityResult() y llama super.onActivityResult() para propagar al fragmento respectivo para códigos de resultados no controlados o para todos.

Si las dos opciones anteriores no funcionan, consulte la opción 3, ya que definitivamente funcionará.

Opción 3:

Una llamada explícita desde el fragmento a la función onActivityResult es la siguiente.

En la clase de actividad principal, anule el método onActivityResult () e incluso anule el mismo en la clase Fragment y llame como el siguiente código.

En la clase de padres:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.dualPane);
    fragment.onActivityResult(requestCode, resultCode, data);
}

En la clase de niños:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // In fragment class callback
}

186
2018-06-12 09:17



Estoy teniendo el mismo problema con el ChildFragmentManager. El administrador no pasará el resultado al fragmento anidado, tienes que hacerlo manualmente en tu fragmento base.

public void onActivityResult(int requestCode, int resultCode, Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);
    Fragment fragment = (Fragment) getChildFragmentManager().findFragmentByTag(childTag);
    if (fragment != null) {
        fragment.onActivityResult(requestCode, resultCode, intent);
    }
}

70
2018-05-08 20:44



En caso de que no conozca fragmentos en su actividad, solo enumere todos y envíe los argumentos del resultado de la actividad:

// In your activity
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    for (Fragment fragment : getSupportFragmentManager().getFragments()) {
        fragment.onActivityResult(requestCode, resultCode, data);
    }
}

63
2018-03-27 10:40



Publicación original.

FragmentActivity reemplaza requestCode por uno modificado. Después de eso, cuando onActivityResult() será invocado, FragmentActivity analiza los 16 bits más altos y restaura el índice del Fragmento original. Mira este esquema:

Enter image description here

Si tiene algunos fragmentos en el nivel raíz, no hay problemas. Pero si tienes fragmentos anidados, por ejemplo Fragment con algunas pestañas adentro ViewPager, tú garantizado se enfrentará con un problema (o ya lo enfrentaron).

Porque solo un índice se almacena dentro requestCode. Ese es un índice de Fragment dentro de su FragmentManager. Cuando estamos usando fragmentos anidados, hay niños FragmentManagers, que tienen su propia lista de Fragmentos. Por lo tanto, es necesario guardar toda la cadena de índices, comenzando desde la raíz FragmentManager.

Enter image description here

¿Cómo resolvemos este problema? Hay una solución alternativa común en esta publicación.

GitHub: https://github.com/shamanland/nested-fragment-issue


53
2018-06-19 09:34



Este es uno de los problemas más populares. Podemos encontrar muchos hilos con respecto a este tema. Pero ninguno de ellos es útil para MÍ.

Así que he resuelto este problema usando esta solución.

Primero, comprendamos por qué sucede esto.

Podemos llamar startActivityForResult directamente desde Fragment, pero en realidad mecánicamente detrás están todos manejados por Activity.

Una vez que llamas startActivityForResult desde un Fragmento, requestCode se cambiará para adjuntar la identidad de Fragment al código. Eso permitirá que Activity pueda rastrear quién envía esta solicitud una vez que se recibe el resultado.

Una vez que se haya navegado hacia atrás la actividad, el resultado se enviará a ActivityActivityResult con el requestCode modificado que se decodificará a la identidad de requestCode + Fragment original. Después de eso, Activity enviará el Resultado de la actividad a ese Fragmento a través de ActivityResult. Y todo está hecho.

El problema es:

La actividad podría enviar el resultado solo al Fragmento que se ha adjuntado directamente a la Actividad pero no al anidado. Esa es la razón por la cual onActivityResult del fragmento anidado nunca se habría llamado sin importar qué.

Solución: 

1) Comience con intención en su Fragmento por el siguiente código:

       /** Pass your fragment reference **/
       frag.startActivityForResult(intent, REQUEST_CODE); // REQUEST_CODE = 12345

2) Ahora en su anulación de Actividad para padres **onActivityResult() : **

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
    }

Tienes que llamar esto a la actividad de los padres para que funcione.

3) En tu llamada de fragmento:

@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {

       }
}

Eso es. Con esta solución, podría aplicarse a cualquier fragmento individual, ya sea anidado o no. Y sí, ¡también cubre todo el caso! Además, los códigos también son agradables y limpios.


35
2017-09-01 09:12