Wrong requestCode in onActivityResult

AndroidAndroid FragmentsOnactivityresult

Android Problem Overview


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?

Android Solutions


Solution 1 - Android

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);

Solution 2 - Android

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)

Solution 3 - Android

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

    }
}

Solution 4 - Android

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);

Solution 5 - Android

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

Solution 6 - Android

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
            }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDimanoidView Question on Stackoverflow
Solution 1 - AndroidChangwei YaoView Answer on Stackoverflow
Solution 2 - AndroidAshlesha SharmaView Answer on Stackoverflow
Solution 3 - AndroidJaime AgudoView Answer on Stackoverflow
Solution 4 - AndroidNilesh TiwariView Answer on Stackoverflow
Solution 5 - AndroidTarikWView Answer on Stackoverflow
Solution 6 - AndroidNull Pointer ExceptionView Answer on Stackoverflow