35

I currently have a base activity which is hosting a single fragment. Inside the fragment I have a method which starts the contact chooser.

private void chooseContacts() {
    Intent pickContactIntent = new Intent(Intent.ACTION_PICK,      ContactsContract.Contacts.CONTENT_URI);
    pickContactIntent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);
    startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
}

When this activity returns how should I capture the results. I have tried adding a

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    //Handle Code
}

to both my base Activity and the fragment but neither method are being triggered. If possible I would like to have the fragment handle the return so as not to muddy up the activity.

Please let me know what the best practice is in this situation.

Update:

if I change:

startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);

to

getActivity().startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);

then it works, but other posts have made me think that is incorrect.

abatishchev
  • 98,240
  • 88
  • 296
  • 433
Nath5
  • 1,665
  • 5
  • 28
  • 46
  • Also make sure your hostActivity launch mode not set to singleTask or singleInstance http://stackoverflow.com/a/38760091/3496570 – Zar E Ahmer Aug 04 '16 at 06:38

4 Answers4

55

I think you should still use the call startActivityForResult() directly in fragment, no use getActivity().startActivityForResult().

I call the startActivityForResult() in Fragment and implement the onActivityResult in Fragment, the onActivityResult() is called correctly.

you can not call startActivityForResult() in activity, otherwise the onActivityResult() in Fragment will not be called.

Dhaval Parmar
  • 18,812
  • 8
  • 82
  • 177
Zephyr
  • 6,123
  • 34
  • 33
5

In my case I did this in my Parent 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);
    }
}
SK16
  • 623
  • 8
  • 17
  • getSupportFragmentManager().getFragments() is not a public method available to apps. Here look at documentation : https://developer.android.com/reference/android/support/v4/app/FragmentManager.html – Pramod Garg May 09 '17 at 10:23
  • 1
    this answer should definitely NOT be upvoted. You can directly call startActivityForResult from within your fragment and implement onActivityResult inside your fragment. It will be called. If you also have to override the onActivityResult in your parent activity, you just have to make sure you call super.onActivityResult to make sure your fragments onActivityResult get called as well. Your current solution is based on methods that are not meant to be called by developer's code and is basically redoing what the support library is already doing for you. – Simon Ninon Jun 22 '17 at 01:16
1

The onActivityCreated of the fragment serves another purpose:

Called when the fragment's activity has been created and this fragment's view hierarchy instantiated. It can be used to do final initialization once these pieces are in place, such as retrieving views or restoring state. It is also useful for fragments that use setRetainInstance(boolean) to retain their instance, as this callback tells the fragment when it is fully associated with the new activity instance. This is called after onCreateView(LayoutInflater, ViewGroup, Bundle) and before onViewStateRestored(Bundle).

This is extracted from the documentation

Mainly with a fragment you will inflate and return the view in the onCreateView, do the view operations (like set an ListAdapter in a ListView) in the onViewCreated. And perform the initialization operations (like show a welcome dialog or something like that) in the onActivityCreated.

You have, several choices, I'm not pretty sure about wich is better for your problem:

  • What I would do will'be do a findFragmentById in the onActivityResult of the activity, and if the fragment isn't null, execute a method that handles the come back from the contact list in the fragment.

  • Another way of do it is fire a BroadCastReceiver in the onActivityResult of the activity, and register you fragment to listen that broadcast. But I think that this is too messy for something so simple.

  • Finally, like the first one, if you don't have a fragment with an id, you can instantiate the fragment in your activity, save a reference, and send it a message when the onActivityResult of the activity is executed.

I hope that something of this helps you.

PacificSky
  • 3,422
  • 2
  • 25
  • 24
4gus71n
  • 3,717
  • 3
  • 39
  • 66
  • I tried to implement the your first solution, the problem is that the onActivityResult in the main activity isn't being called. Any ideas? – Nath5 Nov 18 '13 at 03:10
  • I was able to get it to work by doing: getActivity().startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST); but I have read that that is not the correct method. – Nath5 Nov 18 '13 at 03:14
1

This will help you onActivityResult in Fragments

PlacePicker.IntentBuilder builder = new PlacePicker.IntentBuilder();
startActivityForResult(builder.build(getActivity()), PLACE_PICKER_REQUEST);

And

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

        if (requestCode == PLACE_PICKER_REQUEST) {
            if (resultCode == Activity.RESULT_OK) {
                Place place = PlacePicker.getPlace(data, getActivity());
             }
         }
}