onActivityResult no se llama en Fragment


878

La actividad que aloja este fragmento se onActivityResultllama cuando vuelve la actividad de la cámara.

Mi fragmento inicia una actividad para obtener un resultado con la intención de que la cámara tome una foto. La aplicación de imagen se carga bien, toma una foto y regresa. El onActivityResultsin embargo nunca es golpeado. He establecido puntos de interrupción, pero no se activa nada. ¿Puede tener un fragmento onActivityResult? Creo que sí, ya que es una función proporcionada. ¿Por qué no se desencadena 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);
    }
}

2
revise esta publicación, hay una descripción del problema y una solución alternativa común: stackoverflow.com/questions/6147884/…
Oleksii K.

55
¡Cualquiera que lea esto, asegúrese de aprobar requestCode >= 0!
Muhammad Babar

3
También asegúrese de que su Activity LauchMode no debe ser singleInstance o singleTask. de lo contrario, onActivityResult no se llamará
Jawad Zeb


Necesitamos redirigir onActivityResult en la Actividad al Fragmento. Consulte este enlace: codexpedia.com/android/…
Reejesh PK

Respuestas:


1240

La actividad de alojamiento se anula onActivityResult(), pero no hizo una llamada a los super.onActivityResult()códigos de resultados no manejados. Aparentemente, aunque 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()todos los resultados no manejados, el fragmento tuvo la oportunidad de manejar el resultado.

Y también de @siqing respuesta:

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


34
En onActivityResult de su actividad, llame a super.onActivityResult ()
Spidy

167
@StErMi Asegúrese de llamar a startActivityForResult () y no a getActivity (). StartActivityForResult () desde su fragmento. Ver la respuesta siqing a continuación.
OferR

8
Parece que hay un error relacionado, donde se está utilizando la biblioteca de soporte code.google.com/p/android/issues/detail?id=15394
Ollie C

82
También tenga en cuenta que si está utilizando fragmentos anidados, el fragmento secundario debe llamar getParentFragment().startActivityForResultpara que el fragmento primario tenga su método onActivityResult llamado.
Eric Brynsvold

77
@EricBrynsvold tenía razón, startActivityForResult no funciona en fragmentos anidados. Para esto, será mejor que llame a getParentFragment (). StartActivityForResult (), y en ese fragmento primario, entonces, puede implementar onActivityResult () y en ese método entregar el resultado al elemento secundario fragmen, es decir: childFragment.getParentFragment (). onActivityResult (requestCode, resultCode, data)
edrian

328

Creo que llamaste getActivity().startActivityForResult(intent,111);. Debe llamar startActivityForResult(intent,111);.


3
También tuve el mismo problema con RingtonePreferenceubicado en PreferenceFragment. Desafortunadamente, RingtonePreferencellama getActivity().startActivityForResult()y no obtuve resultados a pesar de que llamé super.onActivityResulta la actividad onActivityResult. Me vi obligado a crear un derivado de la RingtonePreferenceclase, que se une a las PreferenceFragmentllamadas y fragment.startActivityForResult().
Stan

@siqing No puedo llamar a startActivitForResult desde mi método estático. ¿Alguna solución para eso? Debo necesitar usar activity.startActivityForResult. Por favor, ayúdame en esto
Shreyash Mahajan

270

Opción 1:

Si está llamando startActivityForResult()desde el fragmento, debe llamar startActivityForResult(), no getActivity().startActivityForResult(), ya que dará como resultado el fragmento onActivityResult ().

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

Opcion 2:

Como la actividad obtiene el resultado de onActivityResult(), deberá anular la actividad onActivityResult()y llamar super.onActivityResult()para propagarse al fragmento respectivo para obtener 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á.

Opcion 3:

Una llamada explícita del 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 al siguiente código.

En la clase principal:

@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 infantil:

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

44
Esto funcionó para mí. Es una solución desagradable, pero no tengo una mejor idea para resolver este error idiota ...
Bogdan Zurac

@Vivky, tu respuesta funcionó para mí. Pero hay un problema más al que me enfrento, en lugar de setResult(); finish();cuando presiono hacia atrás desde la segunda actividad, entonces también onActivityResultse me llama con provisto RESULT_CODE.
snehal_penurkar

Excelente respuesta. Implementé la tercera solución para hacerlo.
Sash_KP

Creo que la solución 3 funcionaría para mí, pero la onActivityResult()actividad devuelve un extraño requestCodeque se pasa a mi fragmento y luego se ignora = /
E-Kami

1
@notGeek Estás en lo correcto. El resultado siempre se recibe en Actividad aunque haya llamado desde un fragmento o actividad.
Vinayak

83

En caso de que no conozca fragmentos en su actividad, simplemente enumere todos y envíe argumentos de resultados de 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);
    }
}

3
Maldición, pensé que había encontrado la solución más simple, pero no existe un método como getFragments ().
WindRider

2
@WindRider Hay. Si usa la biblioteca de soporte de Android (AppCompat).
dasar

2
Además, ¡aprendí por las malas que tienes que verificar si el fragmento en la matriz no es una referencia a sí mismo! `if (fragment! = this) {fragment.onActivityResult (requestCode, resultCode, data); `
reubenjohn

Esto no funciona si los fragmentos están anidados, ya que solo el fragmento superior estará en la lista. Creo que super.onActivityResult () ya está llamando aActivityResult () en todos los fragmentos de la lista, por lo que esta idea es redundante.
BeccaP


83

Estoy teniendo el mismo problema con el ChildFragmentManager. El administrador no pasará el resultado al fragmento anidado, debe hacerlo manualmente en su 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);
    }
}

1
Si tiene a su hijo Fragment como miembro privado, úselo Fragment fragment = myChildFragment;para reemplazar la findFragmentByTaglínea de código anterior. El resto puede mantenerse sin cambios.
lcn

77
Supongo que recomendaría encarecidamente no guardar un fragmento como miembro privado. Tienen su propio ciclo de vida, por lo que nunca se sabe si están en un buen estado para interactuar, el gerente sí. También son bastante fuertes y me preocuparían las pérdidas de memoria. El administrador no se habría creado si no necesitaras usarlo.
MinceMan

67

Publicación original

FragmentActivityreemplaza requestCodepor uno modificado. Después de eso, cuando onActivityResult()se invoque, FragmentActivityanaliza los 16 bits superiores y restaura el índice del Fragmento original. Mira este esquema:

Ingrese la descripción de la imagen aquí

Si tiene algunos fragmentos en el nivel raíz, no hay problemas. Pero si tiene fragmentos anidados , por ejemplo, Fragmentcon unas pocas pestañas en el interior ViewPager, garantiza que se enfrentará a un problema (o ya lo enfrentó).

Porque solo un índice se almacena dentro requestCode. Ese es el índice de Fragmentsu interior FragmentManager. Cuando usamos fragmentos anidados, hay elementos secundarios FragmentManager, que tienen su propia lista de fragmentos. Por lo tanto, es necesario guardar toda la cadena de índices, comenzando desde la raíz FragmentManager.

Ingrese la descripción de la imagen aquí

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

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


Tengo el mismo problema que usé un ViewPager en el fragmento principal que contiene otros fragmentos como pestañas. Intenté usar el problema de fragmentos anidados pero terminé con errores de compilación. ¿Me puede sugerir la solución? También planteé
cgr

Respondí en github, así que saquemos esta conversación de aquí github.com/shamanland/nested-fragment-issue/issues/…
Oleksii K.

¡Gracias! Si no es una solución recomendada, sugiero editar la respuesta en consecuencia para que uno no tenga que pasar tiempo intentando esto para saber que tiene errores de compilación.
cgr

44

Este es uno de los temas más populares. Podemos encontrar muchos hilos sobre este tema. Pero ninguno de ellos es útil para mí.

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

Primero entendamos por qué está sucediendo esto.

Podemos llamar startActivityForResultdirectamente desde Fragment, pero en realidad la mecánica detrás está a cargo de Activity.

Una vez que llame startActivityForResultdesde un Fragment, requestCode se cambiará para adjuntar la identidad de Fragment al código. Eso permitirá que Activity pueda rastrear a quienes envían esta solicitud una vez que se recibe el resultado.

Una vez que se navegó de nuevo a Activity, el resultado se enviará a onActivityResult de Activity con el requestCode modificado que se decodificará con la identidad de requestCode + Fragment original. Después de eso, Activity enviará el Resultado de la Actividad a ese Fragmento a través de onActivityResult. Y todo está hecho.

El problema es:

Activity podría enviar el resultado solo al Fragment que se ha adjuntado directamente a Activity pero no al anidado. Esa es la razón por la cual onActivityResult de fragmento anidado nunca se llamaría sin importar qué.

Solución:

1) Comience la intención en su Fragmento con 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 a esto en la actividad principal para que funcione.

3) En su fragmento de llamada:

@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, se podría aplicar a cualquier fragmento individual, esté anidado o no. Y sí, ¡también cubre todo el caso! Además, los códigos también son agradables y limpios.


Estaba solicitando la intención del sistema con 'actividad', solo tenía que usar el fragmento de contexto.
Uzair

18

PARA MUCHOS FRAGMENTOS ANIDADOS (por ejemplo, cuando se usa ViewPager en un fragmento)

En su actividad principal :

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

En tu fragmento:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    for (Fragment fragment : getChildFragmentManager().getFragments()) {
        fragment.onActivityResult(requestCode, resultCode, data);
    }
}

En tu fragmento anidado

Actividad de la llamada

getParentFragment().startActivityForResult(intent, uniqueInstanceInt);

uniqueInstanceInt : reemplácelo con un int que sea único entre los fragmentos anidados para evitar que otro fragmento trate la respuesta.

Recibir respuesta

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == uniqueInstanceInt ) {
        // TODO your code
    }
}

Atención

Es necesario utilizar un número entre 0 y 65536 en uniqueInstanceInt para evitar errores "Solo se pueden usar 16 bits inferiores para requestCode".


Funciona muy bien en Actividad> Fragmento (ViewPager)> Fragmento
Oleksandr Firsov

14

Puedo agregar dos consejos si alguien aún no puede hacerlo. En el archivo Manifest.xml, asegúrese de que la actividad de alojamiento no haya finalizado cuando devuelva la llamada y que la actividad a iniciar tenga el modo de inicio como estándar. Vea los detalles a continuación:

Para la actividad de alojamiento, establezca la propiedad sin historial como falsa si tiene

android:noHistory="false"

Para iniciar la actividad, configure el modo de inicio como estándar si tiene

android:launchMode="standard"

13

También estaba enfrentando el mismo problema una vez que cambié este bloque de código fuera de un Fragmento a una Clase de utilidad , con el argumentoparentActivity pasado ,

Intent intent = new Intent(parentActivity, CameraCaptureActivity.class);
parentActivity.startActivityForResult(intent,requestCode);

Entonces no estaba obteniendo ningún valor en el onActivityResultmétodo de ese Fragmento , luego, cambié el argumento a Fragmento , por lo que la definición revisada del método se veía así,

Intent intent = new Intent(fragment.getContext(), CameraCaptureActivity.class);
fragment.startActivityForResult(intent,requestCode);

Después de eso, pude obtener valor en onActivityResultel Fragmento


10

También me encontré con este problema en un Fragmento. Y llamé startActivityForResulta un DialogFragment.

Pero ahora este problema se ha resuelto:
FragmentClassname.this.startActivityForResult .


Genial, funcionó para mí, porque estaba llamando startActivityForResult(...)desde una clase abstracta dentro del código del fragmento.
Vince

9

PARA FRAGMENTOS ANIDADOS (por ejemplo, cuando se usa un ViewPager)

En su actividad principal:

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

En su fragmento principal de nivel superior (fragmento ViewPager):

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    YourFragment frag = (YourFragment) getChildFragmentManager().getFragments().get(viewPager.getCurrentItem());
    frag.yourMethod(data);  // Method for callback in YourFragment
    super.onActivityResult(requestCode, resultCode, data);
}

En YourFragment (fragmento anidado):

public void yourMethod(Intent data){
    // Do whatever you want with your data
}

8

En mi caso, fue un error de Android ( http://technet.weblineindia.com/mobile/onactivityresult-not-getting-called-in-nested-fragments-android/ ), si usa el soporte FragmentActivity, debe usarlo en getSupportFragmentManagerlugar de getChildFragmentManager:

List<Fragment> fragments = getSupportFragmentManager().getFragments();
if (fragments != null) {
    for (Fragment fragment : fragments) {
        if(fragment instanceof UserProfileFragment) {
            fragment.onActivityResult(requestCode, resultCode, data);
        }
    }
}

6

En breve,

En fragmento, declara Fragment fragment = this;

después de ese uso fragment.startActivityForResult.

El resultado volverá en activityResult.


6

Solución 1:

Llama en startActivityForResult(intent, REQUEST_CODE);lugar de getActivity().startActivityForResult(intent, REQUEST_CODE);.

Solución 2:

Cuando startActivityForResult(intent, REQUEST_CODE);se llama, onActivityResult(requestCode,resultcode,intent)se invoca la actividad , y luego puede llamar fragments onActivityResult()desde aquí, pasando el requestCode, resultCode and intent.


5

Dentro de tu fragmento, llama

this.startActivityForResult(intent, REQUEST_CODE);

donde thisse refiere al fragmento. De lo contrario, haga lo que dijo @Clevester:

Fragment fragment = this;
....
fragment.startActivityForResult(intent, REQUEST_CODE);

También tuve que llamar

super.onActivityResult(requestCode, resultCode, data);

en la actividad de los padres onActivityResultpara que funcione.

(Adapte esta respuesta de la respuesta de @ Clevester).


5

Para aquellos que utilizan Android de navegación de componentes debe utilizar en la actividad de onActivityResult(...)la primaryNavigationFragmentconseguirlo es referencia fragmento y el fragmento de llamada fragment.onActivityResult(...).

Aquí está la actividad onActivityResult(...)

@Override
public void onActivityResult(int requestCode, int resultCode, Intent imageData)
{
    super.onActivityResult(requestCode, resultCode, imageData);

    for (Fragment fragment : getSupportFragmentManager().getPrimaryNavigationFragment().getChildFragmentManager().getFragments())
    {
            fragment.onActivityResult(requestCode, resultCode, imageData);
    }
}

4

La mayoría de estas respuestas siguen diciendo que tienes que llamar super.onActivityResult(...)a tu anfitrión Activitypara tu Fragment. Pero eso no parecía estar funcionando para mí.

Entonces, en su host Activity, debe llamar a su Fragments onActivityResult(...)lugar. Aquí hay un ejemplo.

public class HostActivity extends Activity {

    private MyFragment myFragment;

    protected void onActivityResult(...) {
        super.onActivityResult(...);
        this.myFragment.onActivityResult(...);
    }
}

En algún momento de su HostActivitynecesitará asignar this.myFragmentla Fragmentque está utilizando. O utilice el FragmentManagerpara obtener el en Fragmentlugar de mantener una referencia a él en su HostActivity. Además, verifique nullantes de intentar llamar al this.myFragment.onActivityResult(...);.


3
public class takeimage extends Fragment {

    private Uri mImageCaptureUri;
    private static final int PICK_FROM_CAMERA = 1;
    private static final int PICK_FROM_FILE = 2;
    private String mPath;
    private ImageView mImageView;
    Bitmap bitmap = null;
    View view;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.activity_send_image, container, false);
        final String[] items = new String[] { "From Camera", "From SD Card" };
        mImageView = (ImageView)view.findViewById(R.id.iv_pic);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.select_dialog_item, items);
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle("Select Image");

        builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int item) {
                if (item == 0) {
                    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    File file = new File(Environment.getExternalStorageDirectory(), "tmp_avatar_"
                        + String.valueOf(System.currentTimeMillis())
                        + ".jpg");
                    mImageCaptureUri = Uri.fromFile(file);

                    try {
                        intent.putExtra(
                            android.provider.MediaStore.EXTRA_OUTPUT,
                            mImageCaptureUri);
                        intent.putExtra("return-data", true);

                        getActivity().startActivityForResult(intent,
                            PICK_FROM_CAMERA);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                    dialog.cancel();
                } else {
                    Intent intent = new Intent();

                    intent.setType("image/*");
                    intent.setAction(Intent.ACTION_GET_CONTENT);

                    getActivity().startActivityForResult(
                        Intent.createChooser(intent,
                            "Complete action using"), PICK_FROM_FILE);
                }
            }
        });
        final AlertDialog dialog = builder.create();

        Button show = (Button) view.findViewById(R.id.btn_choose);
        show.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // Switch the tab content to display the list view.
                dialog.show();
            }
        });

    return view;
    }

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

        if (resultCode != Activity.RESULT_OK)
            return;

        if (requestCode == PICK_FROM_FILE) {
            mImageCaptureUri = data.getData();
            // mPath = getRealPathFromURI(mImageCaptureUri); //from Gallery

            if (mPath == null)
                mPath = mImageCaptureUri.getPath(); // from File Manager

            if (mPath != null)
                bitmap = BitmapFactory.decodeFile(mPath);
        } else {
            mPath = mImageCaptureUri.getPath();
            bitmap = BitmapFactory.decodeFile(mPath);
        }
        mImageView.setImageBitmap(bitmap);  
    }

    public String getRealPathFromURI(Uri contentUri) {
        String [] proj = {MediaStore.Images.Media.DATA};
        Cursor cursor = managedQuery(contentUri, proj, null, null,null);

        if (cursor == null) return null;

        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }
} 

3
  1. Simplemente puede anular BaseActivity onActivityResulten el fragmento baseActivity.startActivityForResult.

  2. En BaseActivity agregue la interfaz y anule onActivityResult.

    private OnBaseActivityResult baseActivityResult;
    public static final int BASE_RESULT_RCODE = 111;
    public interface OnBaseActivityResult{
        void onBaseActivityResult(int requestCode, int resultCode, Intent data);
       }
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(getBaseActivityResult() !=null && requestCode == BASE_RESULT_RCODE){
        getBaseActivityResult().onBaseActivityResult(requestCode, resultCode, data);
        setBaseActivityResult(null);
    }
  3. En implementos Fragment OnBaseActivityResult

    @Override
    public void onBaseActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d("RQ","OnBaseActivityResult");
    if (data != null) {
        Log.d("RQ","OnBaseActivityResult + Data");
        Bundle arguments = data.getExtras();
      }
    }

Esta solución alternativa hará el truco.


3

Si el problema anterior se enfrenta al iniciar sesión en Facebook , puede usar el código siguiente en una actividad principal de su fragmento como:

Fragment fragment = getFragmentManager().findFragmentById(android.R.id.tabcontent);
fragment.onActivityResult(requestCode, resultCode, data);

O:

Fragment fragment = getFragmentManager().findFragmentById("fragment id here");
fragment.onActivityResult(requestCode, resultCode, data);

Y agregue la siguiente llamada en su fragmento ...

callbackManager.onActivityResult(requestCode, resultCode, data);

2

Otro caso de uso no descrito en otras respuestas:

onActivityResult()declarado en fragmento no se invoca cuando se usa exception.startResolutionForResult():

if (exception is ResolvableApiException) {
    exception.startResolutionForResult(activity!!, MY_REQUEST_CODE)
}

En este caso, reemplace exception.startResolutionForResult()con fragmentos startIntentSenderForResult():

if (exception is ResolvableApiException) {
    startIntentSenderForResult(exception.resolution.intentSender, MY_REQUEST_CODE, null, 0, 0, 0, null)
}

2

Versión de Kotlin (en su actividad enActivityResult ())

 override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    //add following lines in your activity
    if(supportFragmentManager?.fragments!=null && supportFragmentManager?.fragments!!.size>0)
     for (i in 0..supportFragmentManager?.fragments!!.size-1) {
         val fragment= supportFragmentManager?.fragments!!.get(i)
         fragment.onActivityResult(requestCode, resultCode, data)
    }
 }


1

Tengo una fuerte sospecha de que todas las respuestas aquí no son más que hacks. Los he probado todos y muchos otros, pero sin ninguna conclusión confiable, ya que siempre hay algún tipo de problema estúpido. Por mi parte, no puedo confiar en resultados inconsistentes. Si mira la documentación oficial de la API de Android para Fragments, verá que Google establece claramente lo siguiente:

Llame a startActivityForResult (Intent, int) desde la actividad que contiene el fragmento.

Ver: API de Android Fragment

Por lo tanto, parece que el enfoque más correcto y confiable sería llamar realmente a startActivityForResult () desde la actividad de alojamiento y también manejar el resultado en OnActivityResult () desde allí.


2
No creo que "llamar a startActivityForResult from Activity" sea una recomendación. Si observa la implementación dentro de la clase base Fragment, entonces todo lo que hace es mActivity.startActivityFromFragment(this, intent, requestCode), por lo que no es más que una envoltura conveniente
Anti Veeranna

1

Su código tiene un fragmento anidado. Llamar a super.onActivityForResult no funciona

No desea modificar todas las actividades desde las que se puede llamar a su fragmento ni hacer un trabajo para llamar a cada fragmento de la cadena de fragmentos.

Aquí hay una de las muchas soluciones de trabajo. cree un fragmento sobre la marcha y conéctelo directamente a la actividad con el administrador de fragmentos de soporte. Luego llame a startActivityForResult desde el fragmento recién creado.

private void get_UserEmail() {

    if (view == null) {
        return;
    }
    ((TextView) view.findViewById(R.id.tvApplicationUserName))
            .setText("Searching device for user accounts...");

    final FragmentManager fragManager = getActivity().getSupportFragmentManager();

    Fragment f = new Fragment() {
        @Override
        public void onAttach(Activity activity) {
            super.onAttach(activity);
            startActivityForResult(AccountPicker.newChooseAccountIntent(null, null,
                    new String[]{"com.google"}, false, null, null, null, null), REQUEST_CODE_PICK_ACCOUNT);
        }

        @Override
        public void onActivityResult(int requestCode, int resultCode,
                                     Intent data) {
            if (requestCode == REQUEST_CODE_PICK_ACCOUNT) {
                String mEmail = "";
                if (resultCode == Activity.RESULT_OK) {
                    if (data.hasExtra(AccountManager.KEY_ACCOUNT_NAME)) {
                        mEmail = data
                                .getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
                    }
                }
                if (mActivity != null) {
                    GoPreferences.putString(mActivity, SettingApplication.USER_EMAIL, mEmail);
                }
                doUser();
            }
            super.onActivityResult(requestCode, resultCode, data);
            fragManager.beginTransaction().remove(this).commit();
        }
    };
    FragmentTransaction fragmentTransaction = fragManager
            .beginTransaction();
    fragmentTransaction.add(f, "xx" + REQUEST_CODE_PICK_ACCOUNT);
    fragmentTransaction.commit();
}

Esto realmente funciona y solo tengo un voto para ello. Crea un fragmento sobre la marcha. Demasiado fácil pero es una verdadera solución de trabajo. Alguien incluso intentó editarlo por mí.
danny117

1

Mi problema fue con la actividad del host. Lo encontré con un conjunto, android:launchMode="standard"lo eliminé temporalmente y ¡funciona!


1

Un punto que nadie tiene mentionpara asegurarse de que su modo de inicio de Actividad de host no debe establecerse en singleInstanceo singleTask.

onActivityResult no funcionará si su modo de inicio está establecido en SingleInstance o SingleTask. o llamas a tu actividad usando estos IntentFilters

standardo el singleTopmodo de inicio funcionará bien.


1

Si está utilizando fragmentos anidados, esto también está funcionando:

getParentFragment().startActivityForResult(intent, RequestCode);

Además de esto, debe llamar super.onActivityResultdesde la actividad principal y completar el onActivityResultmétodo del fragmento.


1

He manejado el problema escribiendo una clase base que se extiende Fragment, y en onactivityresultla actividad he identificado el fragmento que se está ejecutando actualmente usando fragmenttag. Luego llamo a un método definido por el usuario en la clase fragmentbase. Esto activará un evento en el fragmento actualmente en ejecución.

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.