Android Development
onActivityResult
requestCode
Android Bug
Mobile App Debugging

Wrong requestCode in onActivityResult

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

When onActivityResult receives a different requestCode than the one you passed to startActivityForResult, the cause is almost always that you called startActivityForResult from a Fragment but the result was delivered to the parent Activity, or the requestCode was modified by the framework. In Fragments, the upper 16 bits of the requestCode are used internally to identify the fragment, so only the lower 16 bits (0-65535) are preserved. The modern fix is to use the Activity Result API (registerForActivityResult), which eliminates requestCode management entirely.

The Problem

java
1// In a Fragment
2public class MyFragment extends Fragment {
3    private static final int REQUEST_PICK_IMAGE = 1001;
4
5    void pickImage() {
6        Intent intent = new Intent(Intent.ACTION_PICK);
7        intent.setType("image/*");
8        startActivityForResult(intent, REQUEST_PICK_IMAGE);
9    }
10
11    @Override
12    public void onActivityResult(int requestCode, int resultCode, Intent data) {
13        // requestCode may NOT be 1001!
14        // It might be 66537 (1001 with fragment bits added)
15        Log.d("TAG", "requestCode: " + requestCode);
16    }
17}

Cause 1: Fragment requestCode Mangling

When a Fragment calls startActivityForResult, the hosting Activity adds the fragment's index to the upper 16 bits of the requestCode:

java
// What Android does internally:
// actualRequestCode = ((fragmentIndex + 1) << 16) + (yourRequestCode & 0xFFFF)
// If fragmentIndex = 0: actualRequestCode = (1 << 16) + 1001 = 65536 + 1001 = 66537

If onActivityResult is handled in the Activity instead of the Fragment, you see the modified code. If handled in the Fragment, the framework strips the bits and delivers the original code.

Fix: Let the Fragment Handle the Result

java
1// In the Activity — forward to fragments
2@Override
3protected void onActivityResult(int requestCode, int resultCode, Intent data) {
4    super.onActivityResult(requestCode, resultCode, data);
5    // MUST call super — this dispatches to the fragment
6}
7
8// In the Fragment — receives the original requestCode
9@Override
10public void onActivityResult(int requestCode, int resultCode, Intent data) {
11    if (requestCode == REQUEST_PICK_IMAGE && resultCode == RESULT_OK) {
12        Uri imageUri = data.getData();
13        // Process the image
14    }
15}

The critical line is super.onActivityResult() in the Activity. Without it, the Fragment's onActivityResult is never called.

Cause 2: Using requestCode > 65535

Only the lower 16 bits are available for your request code:

java
1// WRONG: value exceeds 16 bits
2private static final int REQUEST_CODE = 70000;  // > 65535
3
4// CORRECT: use small values
5private static final int REQUEST_PICK_IMAGE = 1;
6private static final int REQUEST_TAKE_PHOTO = 2;
7private static final int REQUEST_PICK_FILE = 3;

Using values above 65535 causes the upper bits to conflict with the fragment index bits.

Cause 3: Calling Activity's startActivityForResult from Fragment

java
1// WRONG: calling the activity's method from within a fragment
2getActivity().startActivityForResult(intent, REQUEST_CODE);
3// Result goes to Activity.onActivityResult, NOT Fragment.onActivityResult
4
5// CORRECT: call the fragment's own method
6startActivityForResult(intent, REQUEST_CODE);
7// Result goes to Fragment.onActivityResult

When you call getActivity().startActivityForResult(), the Activity handles the result directly and the Fragment is bypassed.

Cause 4: Nested Fragments

Nested fragments (fragments inside fragments) have additional complications:

java
1// In a nested fragment (child fragment)
2// WRONG: startActivityForResult does not work correctly in nested fragments
3// on older Android versions (pre-API 24)
4startActivityForResult(intent, REQUEST_CODE);
5
6// The result may go to the parent fragment or the activity
7// instead of the child fragment

Fix for Nested Fragments

java
1// Option 1: Start from the parent fragment
2getParentFragment().startActivityForResult(intent, REQUEST_CODE);
3
4// Option 2: Use the Activity Result API (recommended)
5// See next section

The Activity Result API eliminates requestCode entirely:

java
1// In Fragment or Activity
2public class MyFragment extends Fragment {
3    private final ActivityResultLauncher<Intent> pickImageLauncher =
4        registerForActivityResult(
5            new ActivityResultContracts.StartActivityForResult(),
6            result -> {
7                if (result.getResultCode() == Activity.RESULT_OK) {
8                    Intent data = result.getData();
9                    Uri imageUri = data.getData();
10                    // Process the image
11                }
12            }
13        );
14
15    void pickImage() {
16        Intent intent = new Intent(Intent.ACTION_PICK);
17        intent.setType("image/*");
18        pickImageLauncher.launch(intent);
19    }
20}

Common Activity Result Contracts

java
1// Pick image
2ActivityResultLauncher<String> pickImage = registerForActivityResult(
3    new ActivityResultContracts.GetContent(),
4    uri -> {
5        if (uri != null) {
6            imageView.setImageURI(uri);
7        }
8    }
9);
10pickImage.launch("image/*");
11
12// Take photo
13ActivityResultLauncher<Uri> takePhoto = registerForActivityResult(
14    new ActivityResultContracts.TakePicture(),
15    success -> {
16        if (success) {
17            // Photo saved to the provided URI
18        }
19    }
20);
21Uri photoUri = createImageUri();
22takePhoto.launch(photoUri);
23
24// Request permission
25ActivityResultLauncher<String> requestPermission = registerForActivityResult(
26    new ActivityResultContracts.RequestPermission(),
27    isGranted -> {
28        if (isGranted) {
29            openCamera();
30        }
31    }
32);
33requestPermission.launch(Manifest.permission.CAMERA);

Kotlin Example

kotlin
1class MyFragment : Fragment() {
2
3    private val pickImageLauncher = registerForActivityResult(
4        ActivityResultContracts.GetContent()
5    ) { uri: Uri? ->
6        uri?.let { imageView.setImageURI(it) }
7    }
8
9    private val takePhotoLauncher = registerForActivityResult(
10        ActivityResultContracts.TakePicture()
11    ) { success: Boolean ->
12        if (success) {
13            // Photo was taken successfully
14        }
15    }
16
17    fun pickImage() {
18        pickImageLauncher.launch("image/*")
19    }
20}

Debugging requestCode Issues

java
1@Override
2protected void onActivityResult(int requestCode, int resultCode, Intent data) {
3    super.onActivityResult(requestCode, resultCode, data);
4
5    // Log the raw requestCode to identify mangling
6    Log.d("DEBUG", String.format(
7        "requestCode: %d (0x%X), resultCode: %d",
8        requestCode, requestCode, resultCode
9    ));
10
11    // Extract the original code (lower 16 bits)
12    int originalCode = requestCode & 0xFFFF;
13    Log.d("DEBUG", "Original code: " + originalCode);
14}

Common Pitfalls

  • Not calling super.onActivityResult() in the Activity: If the Activity overrides onActivityResult without calling super, the result is never forwarded to the Fragment. Always call super.onActivityResult(requestCode, resultCode, data) first.
  • Calling getActivity().startActivityForResult() from a Fragment: This bypasses the Fragment's result dispatch. The result goes to the Activity's onActivityResult, not the Fragment's. Always call startActivityForResult() directly from the Fragment.
  • Using requestCode values greater than 65535: The upper 16 bits are reserved for the fragment index. Using large request codes causes bit collisions and delivers wrong codes. Keep values between 0 and 65535.
  • Comparing the mangled requestCode in the Activity: If you handle the result in the Activity instead of the Fragment, the requestCode includes fragment index bits. Either handle the result in the Fragment or mask with requestCode & 0xFFFF (not recommended — use the Activity Result API instead).
  • Not migrating to the Activity Result API: startActivityForResult and onActivityResult are deprecated since AndroidX Activity 1.2.0. The Activity Result API is type-safe, eliminates requestCode management, and works correctly with Fragments and nested Fragments.

Summary

  • The wrong requestCode in onActivityResult is usually caused by Fragment requestCode bit mangling (upper 16 bits store the fragment index)
  • Always call super.onActivityResult() in the Activity to forward results to Fragments
  • Use startActivityForResult() from the Fragment, not getActivity().startActivityForResult()
  • Keep requestCode values below 65536 (16 bits)
  • Migrate to registerForActivityResult() (Activity Result API) to avoid requestCode issues entirely

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.