Wrong requestCode in onActivityResult
Asked Answered
A

6

354

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?

Armyn answered 12/5, 2012 at 14:11 Comment(1)
possible duplicate of onActivityResult not being called in FragmentMenticide
B
919

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);
Bein answered 12/5, 2012 at 14:13 Comment(10)
Result do delivered to activity and I want it to be delivered there it's just has wrong requestCodeArmyn
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().Bein
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=40537Turbojet
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...Marrissa
I've raised it with the Android Team as it's either an error in the documentation or a bug in the implementation: code.google.com/p/android/issues/detail?id=78260Godgiven
@ChangweiYao ok! so, basically the Activity acts as a NAT.Furl
"the requestCode is changed by the Activity that owns the Fragment" - Gotta love the Android design...Dermott
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.Bethel
You also can call super.onActivityResult(arg1,arg2,arg3) before call fragment.onActivityResult(arg1,arg2,arg3) in your FragementActivityOliy
when i am calling getActivity().startActivityResult() ->request code is came but not calling onActivityResult() in fragment,only calling activity methodKaph
W
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)
Wolves answered 15/6, 2016 at 13:20 Comment(4)
Great info that explains the exact cause to this issueTedtedd
quick question: what is indexOfFragment?Anthracosilicosis
indexOfFragment is the index that the getSupportFragmentManager().getFragments () producesPlanetoid
Morale: Don't mix activity/fragment startActivityForResult() and onActivityResult(). When started from an activity, process the result in the activity. When started from a fragment, process the result in the fragment.Reichel
M
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

    }
}
Macruran answered 9/3, 2017 at 17:57 Comment(4)
Can you tell me the reason why it not give the original request code?Liberec
Cause the requestCode is changed by the Activity that owns the Fragment. See Ashlesha Sharma answerMacruran
thank you, this is the answer I was looking for. I dont see why Android shouldnt return the original request code though.Frasquito
This was immensely helpful for me today and actually explains the problem really nicely. Thanks!Coverup
K
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);
Keyhole answered 26/2, 2016 at 21:22 Comment(0)
S
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

Smalt answered 6/8, 2016 at 13:52 Comment(0)
C
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
            }
Casement answered 15/2, 2018 at 13:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.