Fragment's onActivityResult not called after orientation change
Asked Answered
H

2

11

Please note, this question is not a duplicate of the following:

Also, another similar question was asked before, but that doesn't mention orientation changes (and is unresolved).

My onActivityResult method in the Fragment does get called if I don't switch orientation. However, if I follow these steps, it doesn't get called:

  1. Load fragment in FragmentActivity.
  2. From the fragment: startActivityForResult(new Intent(MediaStore.ACTION_IMAGE_CAPTURE), Constants.REQ_CODE_IMAGE_CAPTURE);
  3. Wait for the camera to load.
  4. Switch orientation.
  5. Take picture and click the checkmark.

onActivityResult still gets called in the parent FragmentActivity. However, due to this warning I am getting:

W/FragmentActivity(4418): Activity result no fragment exists for index: 0x22d73

...my guess is that the parent gets destroyed due to the orientation change, and after having been re-created, can't find the Fragment that called startActivityForResult in the first place.

Is this a framework bug? How can this be worked around?

EDIT: Added more code due to popular demand.

FragmentActivity.java:

...

fragment = new ExampleFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace (R.id.mainContentView, fragment);
if (clearBackStack) {
    // clear the back stack
    while (getSupportFragmentManager().popBackStackImmediate ());
    // add the current transaction to the back stack
    transaction.addToBackStack (null);
}
else {
    transaction.addToBackStack(null);
}
transaction.commit();

...

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

ExampleFragment.java:

Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(takePicture, Constants.REQ_CODE_IMAGE_CAPTURE);

...

@Override
public void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
    super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
    switch (requestCode) {
    case Constants.REQ_CODE_IMAGE_CAPTURE:
        // handle added image
    }
}
Hoseahoseia answered 23/1, 2014 at 8:55 Comment(5)
There is issue in support library. Check this post: shomeser.blogspot.com/2014/01/nested-fragments-for-result.htmlDachia
@shomeser, your post came up when searching for something, but I have no nested fragments, so I don't think it's related.Hoseahoseia
index of your fragment is too big: 0x22d73, it looks like something strange happened. is this issue stable to reproduce? could you show your code?Dachia
@shomeser, there is nothing really special about my code, but see the edit. The issue is always reproducible if you follow the provided steps.Hoseahoseia
Did you try to move invocation of popBackStackImmediate() before beginTransaction() ??Dachia
H
2

Resolved it by moving all of the onActivityResult logic from the Fragment to the Activity.

Do note, however, that the reqCode that gets passed to the Fragment is different than the reqCode that gets delivered to the parent Activity (the one for the Activity is set by the system I think). This meant that I had to also move the original startActivityForResult call from the Fragment to the Activity, and then create a method to call it from the Fragment when needed.

If anyone finds a more elegant way, I would be happy to hear about it.

Hoseahoseia answered 23/1, 2014 at 16:18 Comment(3)
See method FragmentActivity.startActivityFromFragment(), it modifies original request code to store index of Fragment: goo.gl/yuaPWW That's why you got different value. Sad, but currently I can't reproduce this issue.Dachia
That fix worked for me. The issue occurred only on some devices (Galaxy S5 was fine, but I had the error on Sony XPeria)Doubleedged
On my situation, the onActivityResult was on my Activity class already. But I still notice the same behavior.Sooty
C
1

i Have one Solution it is currently Working in my project. follow Step.

--> Create Interface name OnActivityResultListener(or name as you wish).

public interface OnActivityResultListener {

public boolean onActivityResultTest(int request_code, int response_code,
        Intent data);

}

--> Make refrence of intercace in your FragmentActivity like

public OnActivityResultListener activityResultListener;

--> now override OnActivityResult in FragmentActivity. like below.

@Override
public void onActivityResult(int arg0, int arg1, Intent arg2) {
    AppLog.Log(TAG, "onActivityResult");
    try {
        if (activityResultListener != null) {
            activityResultListener.onActivityResultTest(arg0,arg1,arg2);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    super.onActivityResult(arg0, arg1, arg2);
    }

--> now implement interface in your Fragment and override required method.

@Override
public boolean onActivityResultTest(int requestCode, int resultCode,
        Intent data) {
    AppLog.Log(TAG, "onActivityResultTest");
    if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) {
        isHavePhoto = true;
        bitmap = (Bitmap) data.getExtras().get("data");
        userEditPhoto.setImageBitmap(bitmap);
    }
}

--> and the last step is inside OnAttach Method of Fragment class is register your Fragment in activity for the the Activity result. like

@Override
    public void onAttach(Activity activity) {
        this.activity = (YOUR_FRAGMENT_ACTIVITY) activity;
            this.activity.activityResultListener = this;
        super.onAttach(activity);
    }

-->now test and don't forgot to remove it

@Override
public void onDestroyView() {
    activity.activityResultListener = null;
    super.onDestroyView();
}

->it is some what lengthy process but it is working 100% in any orientation.

Cornell answered 23/1, 2014 at 10:34 Comment(4)
Doesn't work on Android 4.4, Nexus 5, revision 19.0.1 of the support library. The fragment gets attached after the Activity's onActivityResult gets called, so at the time it gets called, the listener is null.Hoseahoseia
sorry but it is working with 4.4 i have tested in Nexus 4 and 5 too it is working. you need to tell me i think you have problem with onAttach method.check for the all step again.Cornell
Well, that could be. However, in my current situation, it doesn't work for me.Hoseahoseia
Works fine, just startActivityForResult have to be called from the activity (activity?.startActivityForResult)Brantbrantford

© 2022 - 2024 — McMap. All rights reserved.