onActivityResult not called in nested Fragment

For Android developers, we are very familiar with method onActivityResult. Activty A want to call activity B and receive a result back. For example, your app can start a camera app and receive the captured photo as a result. Or, you might start the People app in order for the user to select a contact and you’ll receive the contact details as a result.

In this article, I want to share with you an issue, that encountered.

  • I have a activity with name is MainActivity
  • In MainActivity has a fragment with name LevelOneFragment
  • In LevelOneFragment has a fragment with name LevelTwoFragment.
  • startActivityForResult method called in LevelTwoFragment to start activity WorkerActivity

[![android_nested_fragmom/content/images/2015/08/android_nested_fragment.png)

In my case, I can get result by onActivityResult in MainActivity and LevelOneFragment but I can’t get result by onActivityResult method in LevelTwoFragment. Why?

In fragment, when startActivityForResult with a requestCode, the parent activity control the progress. The activity will add an identity for requestCode to define fragment that send the request. When activity receive the result, requestCode decoded to define fragment which send request. But activity just can send results to fragment that direct attach to activity. In my case, LevelTwoFragment isn’t a direct child of the activity.

Solution?

Have a solution for issue.When activity received result, it will send a message(broadcast) to the fragment that send request. In Android, you can use LocalBroadcastManager to do. I user EventBus instead LocalBroadcastManager. Now I will show you how to do it.

Add EventBus library to your build.gradle.

compile 'de.greenrobot:eventbus:2.4.0'

In LevelTwoFragment, you must call startActivityForResult with MainActivity:

getActivity().startActivityForResult(new Intent(getActivity(), WorkerActivity.class), 222);

In MainActivity, when receive a result we will use EventBus to post a message to LevelTwoFragment:

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
 super.onActivityResult(requestCode, resultCode, data);
 Log.d("haint", "onActivityResult in MainActivity, request Code: " + requestCode);
 EventBus.getDefault().post(new ActivityResultEvent(requestCode, resultCode, data));
}

You must register LevelTwoFragment with EventBus to listen message from MainActivity:

EventBus.getDefault().register(this);

And you add a callback method to handle message from MainActivity:

public void onEvent(ActivityResultEvent event) {
  Log.d("haint", "Message from MainActivity via EvenBus: request code = " + event.getRequestCode());
}

When run project, I can show the log:

[![android_onActivityReom/content/images/2015/08/android_onActivityResult_eventbus.jpg)

Complete, you can get comple source code in here.