352

I'm starting a new Activity from my Fragment with

startActivityForResult(intent, 1);

and want to handle the result in the Fragment's parent Activity:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d(TAG, "onActivityResult, requestCode: " + requestCode + ", resultCode: " + resultCode);
    if (requestCode == 1) {
        // bla bla bla
    }
}

The problem is that I never got the requestCode I've just posted to startActivityForResult().

I got something like 0x40001, 0x20001 etc. with a random higher bit set. The docs don't say anything about this. Any ideas?

David Rawson
  • 20,912
  • 7
  • 88
  • 124
Dimanoid
  • 6,999
  • 4
  • 40
  • 55
  • possible duplicate of [onActivityResult not being called in Fragment](http://stackoverflow.com/questions/6147884/onactivityresult-not-being-called-in-fragment) – PhoneixS May 01 '14 at 20:31

6 Answers6

917

You are calling startActivityForResult() from your Fragment. When you do this, the requestCode is changed by the Activity that owns the Fragment.

If you want to get the correct resultCode in your activity try this:

Change:

startActivityForResult(intent, 1);

To:

getActivity().startActivityForResult(intent, 1);
mbm29414
  • 11,558
  • 6
  • 56
  • 87
Changwei Yao
  • 13,051
  • 3
  • 25
  • 22
  • 1
    Result do delivered to activity and I want it to be delivered there it's just has wrong requestCode – Dimanoid May 12 '12 at 14:17
  • 48
    Because it should decide which fragment will deliver the result to . So when The Fragment call StartActivityForResult. the requestCode will be changed by the Activity, so it will know how to deliver the result to which fragment. if you really want to get the result in the Activiy. just call getActivity().startActivityForResult(). – Changwei Yao May 12 '12 at 14:18
  • Great answer. Also, I'm not 100% but it appears that this may be a bug with the support package only: [https://code.google.com/p/android/issues/detail?id=40537](https://code.google.com/p/android/issues/detail?id=40537) – matt Mar 14 '13 at 21:07
  • 33
    Just a note: if you use `startActivityForResult` in a fragment and expect the result from `onActivityResult` in that fragment, just make sure you call `super.onActivityResult` in the host activity (in case you override that method there). This is because the activity's `onActivityResult` seems to call the fragment's `onActivityResult`. Also, note that the request code, when it travels through the activity's `onActivityResult`, is altered as explained in the link that Dimanoid posted in his answer below. You might not need to know that but you never know... – Ferran Maylinch Mar 22 '14 at 00:30
  • I've raised it with the Android Team as it's either an error in the documentation or a bug in the implementation: https://code.google.com/p/android/issues/detail?id=78260 – Urboss Oct 27 '14 at 10:42
  • @ChangweiYao ok! so, basically the Activity acts as a NAT. – Gonzalo Jul 23 '15 at 02:20
  • 41
    "the requestCode is changed by the Activity that owns the Fragment" - Gotta love the Android design... – Bitcoin Cash - ADA enthusiast Feb 22 '16 at 20:03
  • 21
    Such an important information, that you can't find anywhere clear in the docs. Gotta love the android design designed to make your life a hell. – Driss Bounouar Mar 21 '16 at 15:24
  • 1
    You also can call `super.onActivityResult(arg1,arg2,arg3)` before call `fragment.onActivityResult(arg1,arg2,arg3)` in your FragementActivity – wqycsu Mar 29 '16 at 03:35
  • 1
    when i am calling getActivity().startActivityResult() ->request code is came but not calling onActivityResult() in fragment,only calling activity method – Ashik Azeez Aug 07 '19 at 12:04
45

The request code is not wrong. When using v4 support library fragments, fragment index is encoded in the top 16 bits of the request code and your request code is in the bottom 16 bits. The fragment index is later used to find the correct fragment to deliver the result.

Hence for Activities started form fragment object, handle onActivityResult requestCode like below:

originalRequestCode = changedRequestCode - (indexOfFragment << 16)
      6             =      196614        -       (3 << 16)
Ashlesha Sharma
  • 949
  • 7
  • 15
39

Easier:

Java: int unmaskedRequestCode = requestCode & 0x0000ffff

Kotlin: val unmaskedRequestCode = requestCode and 0x0000ffff

Check for the lower 16 bits, just unmask it doing a logical AND with the upper 16 bits zeroed

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

    final int unmaskedRequestCode = requestCode & 0x0000ffff

    if(unmaskedRequestCode == ORIGINAL_REQUEST_CODE){
      //Do stuff

    }
}
Demigod
  • 5,073
  • 3
  • 31
  • 49
Jaime Agudo
  • 8,076
  • 4
  • 30
  • 35
6

If you are providing constant make it public and then use in startActivityResult

example:

public static final int REQUEST_CODE =1;
getActivity().startActivityForresult(intent, REQUEST_CODE);
Mi-Creativity
  • 9,554
  • 10
  • 38
  • 47
Nilesh Tiwari
  • 194
  • 2
  • 7
2

You can also define
super.onActivityResult(requestCode, resultCode, data)
in Activity (if you overrideonActivityResult) at this

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

        ...

        default:
            super.onActivityResult(requestCode, resultCode, data);
    }
}

and call startActivityForResult(intent, requestCode) inside your Fragment

TarikW
  • 359
  • 4
  • 12
0

in Fragment

  getActivity().startActivityForResult(builder.build(getActivity()), PLACE_PICKER_REQUEST);

in Main Activity:

if (requestCode == PLACE_PICKER_REQUEST) {
            if (resultCode == RESULT_OK) {    
     //what ever you want to do
            }