The activity hosting this fragment has its onActivityResult called when the camera activity returns.

My fragment starts an activity for a result with the intent sent for the camera to take a picture. The picture application loads fine, takes a picture, and returns. The onActivityResult however is never hit. I've set breakpoints, but nothing is triggered. Can a fragment have onActivityResult? I'd think so since it's a provided function. Why isn't this being triggered?

ImageView myImage = (ImageView)inflatedView.findViewById(R.id.image);
myImage.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        startActivityForResult(cameraIntent, 1888);
    }
});

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if( requestCode == 1888 ) {
        Bitmap photo = (Bitmap) data.getExtras().get("data");
        ((ImageView)inflatedView.findViewById(R.id.image)).setImageBitmap(photo);
    }
}
2 upvote
  flag
check this post, there is problem description and common workaround solution: //allinonescript.com/questions/6147884/… – Oleksii K.
4 upvote
  flag
Any one else reading this make sure you pass requestCode >= 0! – Muhammad Babar
3 upvote
  flag
Also make sure your Activity LauchMode must not singleInstance or singleTask. otherwise onActivityResult will not called – Nepster

31 Answers 11

up vote 936 down vote accepted

The hosting activity overrides onActivityResult(), but it did not make a call to super.onActivityResult() for unhandled result codes. Apparently, even though the fragment is the one making the startActivityForResult() call, the activity gets the first shot at handling the result. This makes sense when you consider the modularity of fragments. Once I implemented super.onActivityResult() for all unhandled results, the fragment got a shot at handling the result.

And also from @siqing answer:

To get the result in your fragment make sure you call startActivityForResult(intent,111); instead of getActivity().startActivityForResult(intent,111); inside your fragment.

2 upvote
  flag
I have the same issue but I don't understand how you fixed this? – Codejoy
19 upvote
  flag
In your activity's onActivityResult, call super.onActivityResult() – Spidy
upvote
  flag
Sorry but it's nor working for me... @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); } wont send onActivityResult to my fragments... – StErMi
upvote
  flag
@StErMi Did you call startActivityForResult() in your fragments? I guess if you call that method in activity, it won't notify its fragments... Just guessing... – user942821
upvote
  flag
@Spidy: +1 for your answers.. such a small thing but ignored by me. thanks – Zoombie
129 upvote
  flag
@StErMi Make sure you call startActivityForResult() and not getActivity().startActivityForResult() from your fragment. See siqing answer below. – OferR
7 upvote
  flag
There appears to be a related bug, where the support library is being used code.google.com/p/android/issues/detail?id=15394 – Ollie C
upvote
  flag
very nice catch :) – kishu27
71 upvote
  flag
Also note that if you are using nested fragments, the child fragment should call getParentFragment().startActivityForResult so that the parent fragment will have its onActivityResult method called. – Eric Brynsvold
upvote
  flag
Better explanation than in the other questions – QED
upvote
  flag
was this issue fixed on newer support library versions? – android developer
upvote
  flag
it may have been, this question/answer was created in the 3.0 era – Spidy
5 upvote
  flag
I have super.onActivityResult in both Fragment and Activity. Still doesn't work either way :( – AimanB
2 upvote
  flag
@OferR but then there is the issue with the wrong request code being returned. – user1940676
upvote
  flag
This got me close to solving my problem, but i already had super.onActivityResult() in my host activity. Please view my answer below for another solution that is working. – prolink007
6 upvote
  flag
@EricBrynsvold was right, startActivityForResult doesn't work in nested fragments. For this, you'd better call getParentFragment().startActivityForResult(), and in that parent fragment, then, you can implement onActivityResult() and in that method deliver the result to the child fragmen, ie: childFragment.getParentFragment().onActivityResult(requestCo‌​de, resultCode, data) – edrian
1 upvote
  flag
I find that calling startActivityForResult() from my Fragment then having super.onActivityResult() in my FragmentActivity makes ALL fragments in the getFragmentManager() have their onActivityResult() called. Ensuring that ALL requestCodes are unique. – Losin' Me
upvote
  flag
If you are using ViewPager, apart from doing what this answer says, you also need to do what @Oleksii Kropachov says. Combining both approaches solved my problem. – Tiago
upvote
  flag
@EricBrynsvold is my life saver. – Sash_KP
upvote
  flag
thankyouthankyouthankyouthankyouthankyouthankyou – user49557
upvote
  flag
what to do if I want to call startActivityForResult from static method in my fragment? Please help me in this. – iDroid Explorer
upvote
  flag
Thanks, Spidy. This problem certainly could have cost me hours. No doubt that this answer will get you a ton of points on stackoverflow for many years to come ! – Someone Somewhere
upvote
  flag
you saved my day – Maher Abuthraa
upvote
  flag
I believe that if the Activity extends android.app.Activity and not FragmentActivity, the onActivityResult base method does nothing. Even in API 24. – user3175580
upvote
  flag
good work dude :) – Ashu Kumar
upvote
  flag
Dude, you saved my life :) – Twometer
upvote
  flag
@Spidy adding super.onActivityResult(requestCode, result, intent) in Activity not working for me. – Nishant Bhakta

I have handled the issue by writing a base class that extends Fragment, and in onactivityresult of the activity I have identified the currently running fragment using the fragmenttag, and called a user-defined method in fragmentbase class. This will fire an event in the currently running fragment.

I think you called getActivity().startActivityForResult(intent,111);. You should call startActivityForResult(intent,111);.

3 upvote
  flag
I also had the same problem with RingtonePreference located in PreferenceFragment. Unfortunately, RingtonePreference calls getActivity().startActivityForResult(), and I did not get results even though I call super.onActivityResult in the activity's onActivityResult. I was compelled to create a derived from RingtonePreference class, which binds itself to the PreferenceFragment and calls fragment.startActivityForResult(). – Stan
upvote
  flag
@siqing I am not able to call startActivitForResult from my static method. Any solution for that? I must need to use activity.startActivityForResult. Please help me in this – iDroid Explorer

I can add two advices if someone still cannot make it. In Manifest.xml file, make sure the hosting activity didn't finish when call back and the activity to be started has the launch mode as standard. See details as below:

For Hosting activity, set the no history property as false if have

android:noHistory="false"

For Activity to be started, set the launch mode as standard if have

android:launchMode="standard"
public class takeimage extends Fragment {

    private Uri mImageCaptureUri;
    private static final int PICK_FROM_CAMERA = 1;
    private static final int PICK_FROM_FILE = 2;
    private String mPath;
    private ImageView mImageView;
    Bitmap bitmap = null;
    View view;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.activity_send_image, container, false);
        final String[] items = new String[] { "From Camera", "From SD Card" };
        mImageView = (ImageView)view.findViewById(R.id.iv_pic);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.select_dialog_item, items);
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle("Select Image");

        builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int item) {
                if (item == 0) {
                    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    File file = new File(Environment.getExternalStorageDirectory(), "tmp_avatar_"
                        + String.valueOf(System.currentTimeMillis())
                        + ".jpg");
                    mImageCaptureUri = Uri.fromFile(file);

                    try {
                        intent.putExtra(
                            android.provider.MediaStore.EXTRA_OUTPUT,
                            mImageCaptureUri);
                        intent.putExtra("return-data", true);

                        getActivity().startActivityForResult(intent,
                            PICK_FROM_CAMERA);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                    dialog.cancel();
                } else {
                    Intent intent = new Intent();

                    intent.setType("image/*");
                    intent.setAction(Intent.ACTION_GET_CONTENT);

                    getActivity().startActivityForResult(
                        Intent.createChooser(intent,
                            "Complete action using"), PICK_FROM_FILE);
                }
            }
        });
        final AlertDialog dialog = builder.create();

        Button show = (Button) view.findViewById(R.id.btn_choose);
        show.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // Switch the tab content to display the list view.
                dialog.show();
            }
        });

    return view;
    }

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

        if (resultCode != Activity.RESULT_OK)
            return;

        if (requestCode == PICK_FROM_FILE) {
            mImageCaptureUri = data.getData();
            // mPath = getRealPathFromURI(mImageCaptureUri); //from Gallery

            if (mPath == null)
                mPath = mImageCaptureUri.getPath(); // from File Manager

            if (mPath != null)
                bitmap = BitmapFactory.decodeFile(mPath);
        } else {
            mPath = mImageCaptureUri.getPath();
            bitmap = BitmapFactory.decodeFile(mPath);
        }
        mImageView.setImageBitmap(bitmap);  
    }

    public String getRealPathFromURI(Uri contentUri) {
        String [] proj = {MediaStore.Images.Media.DATA};
        Cursor cursor = managedQuery(contentUri, proj, null, null,null);

        if (cursor == null) return null;

        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }
} 
upvote
  flag
This worked for me , i added @Override – Lutaaya Huzaifah Idris

I'm having this same problem with the ChildFragmentManager. The manager will not pass the result to the nested fragment, you have to do that manually in your base fragment.

public void onActivityResult(int requestCode, int resultCode, Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);
    Fragment fragment = (Fragment) getChildFragmentManager().findFragmentByTag(childTag);
    if (fragment != null) {
        fragment.onActivityResult(requestCode, resultCode, intent);
    }
}
1 upvote
  flag
If you have your child Fragment as a private member, then use Fragment fragment = myChildFragment; to replace the above findFragmentByTag line of code. The rest can be kept unchanged. – lcn
7 upvote
  flag
I guess I would strongly recommend against keeping a fragment as a private member. They have their own lifecycle so you never know if their in a good state to interact with, the manager does. Also they're pretty hefty and I would be concerned about memory leaks. The manager wouldn't have been created if you didn't need to use it. – MinceMan

Option 1:

If you're calling startActivityForResult() from the fragment then you should call startActivityForResult(), not getActivity().startActivityForResult(), as it will result in fragment onActivityResult().

If you're not sure where you're calling on startActivityForResult() and how you will be calling methods.

Option 2:

Since Activity gets the result of onActivityResult(), you will need to override the activity's onActivityResult() and call super.onActivityResult() to propagate to the respective fragment for unhandled results codes or for all.

If above two options do not work, then refer to option 3 as it will definitely work.

Option 3:

An explicit call from fragment to the onActivityResult function is as follows.

In the parent Activity class, override the onActivityResult() method and even override the same in the Fragment class and call as the following code.

In the parent class:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.dualPane);
    fragment.onActivityResult(requestCode, resultCode, data);
}

In the child class:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // In fragment class callback
}
3 upvote
  flag
This worked for me. It's a nasty workaround, but I don't have a better idea to solve this idiotic bug... – Bogdan Zurac
upvote
  flag
@Vicky... Hello vicky... can you explain your answer in detail? – Anil Bhatiya
upvote
  flag
@Anil answered ur query – Happy Vicky
upvote
  flag
@Vivky, Your answer worked for me. But there is one more issue I am facing, instead of setResult(); finish(); when I press back from second activity then also onActivityResult gets called with provided RESULT_CODE. – snehal_penurkar
upvote
  flag
superb answer. I implemented the third solution to get it done. – Sash_KP
upvote
  flag
I think the solution 3 would work for me but the onActivityResult() of the activity returns a weird requestCode which is passed to my fragment and then ignored =/ – E-Kami
upvote
  flag
thank you very much, the solution 3 worked for me ;) – Clyky
upvote
  flag
there is lots of improvements happened .Welcome – Happy Vicky

I just make a workaround method:

public static Fragment _tempFragment = null;
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(_tempFragment != null)
        _tempFragment.onActivityResult(requestCode, resultCode, data);
}

In your Fragment, before startActivityResult, set

MainActivity._tempFragment = this;

After onActivityResult <-- in Fragment

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

     // Do your job
     {

     }
     MainActivity._tempFragment = null;
}
upvote
  flag
Why make a work around method when the framework already supports it? – Spidy
upvote
  flag
For example Facebook -> Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data); – Ah Lam

In case you don't know fragments in your activity just enumerate them all and send activity result arguments:

// In your 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);
    }
}
2 upvote
  flag
Damn, I thought i just found the simpliest solution, but there is no such method as getFragments(). – WindRider
1 upvote
  flag
@WindRider There is. If you use Android support library (AppCompat). – dasar
2 upvote
  flag
Also, I learned the hard way that you have to check if the fragment in the array is not a reference to itself! ` if(fragment!=this) { fragment.onActivityResult(requestCode, resultCode, data); ` – reubenjohn
upvote
  flag
Is above code a good approach? – Rethinavel Pillai
upvote
  flag
This doesn't work if the fragments are nested, as only the top fragment will be in the list. I believe that super.onActivityResult() is already calling onActivityResult() on all of the fragments in the list, so this idea is redundant. – BeccaP
1 upvote
  flag
This approach works for me thnaks man. – Umar
upvote
  flag
I don't know why it didn't work for me. – Anshul Tyagi
upvote
  flag
upvote
  flag
what about "android.app.Fragment" ? how to get all fragments ? – Rjz Satvara
upvote
  flag
@RjzSatvara for native fragments implementation I used callbacks, broadcasts and message busses – ruX
upvote
  flag
@ruX thank you , any link or Examples of it ??? – Rjz Satvara
upvote
  flag
Always check for null fragment in fragmentManager. Learnt this the hard way. Copied this code and crashed the app. – VipulKumar
upvote
  flag
nice one thanks – Syed Raza Mehdi

Most of these answers keep saying that you have to call super.onActivityResult(...) in your host Activity for your Fragment. But that did not seem to be working for me.

So, in your host Activity you should call your Fragments onActivityResult(...) instead. Here is an example.

public class HostActivity extends Activity {

    private MyFragment myFragment;

    protected void onActivityResult(...) {
        super.onActivityResult(...);
        this.myFragment.onActivityResult(...);
    }
}

At some point in your HostActivity you will need to assign this.myFragment the Fragment you are using. Or, use the FragmentManager to get the Fragment instead of keeping a reference to it in your HostActivity. Also, check for null before you try to call the this.myFragment.onActivityResult(...);.

As Ollie C mentioned, there is an active bug for the support library using returned values to onActivityResult when you are using nested fragments. I just hit it :-(.

See Fragment.onActivityResult not called when requestCode != 0.

Original post.

FragmentActivity replaces requestCode by a modified one. After that, when onActivityResult() will be invoked, FragmentActivity parses the higher 16 bits and restores the index of the original Fragment. Look at this scheme:

Enter image description here

If you have a few fragments at the root level there are no problems. But if you have nested fragments, for example Fragment with a few tabs inside ViewPager, you guaranteed will face with a problem (or already faced it).

Because only one index is stored inside requestCode. That is index of Fragment inside its FragmentManager. When we are using nested fragments, there are child FragmentManagers, which have their own list of Fragments. So, it's necessary to save the whole chain of indices, starting from root FragmentManager.

Enter image description here

How do we resolve this issue? There is common workaround solution in this post.

GitHub: https://github.com/shamanland/nested-fragment-issue

upvote
  flag
I have same issue as I used a ViewPager in parent fragment which holds other fragments as tabs. Tried using the nested-fragment-issue but ended up with compilation erros. Can you suggest me the solution ? Raised an issues too here github.com/shamanland/nested-fragment-issue/issues/2 – cgr
upvote
  flag
I answered on github, so let's move this conversation out of here github.com/shamanland/nested-fragment-issue/issues/… – Oleksii K.
upvote
  flag
Thanks! If it is not a recommended solution, I suggest edit the answer accordingly so that one need not to spend time trying this to know it has compilation erros. – cgr

In short,

In fragment, declare Fragment fragment = this;

after that use fragment.startActivityForResult.

The result will return in activityResult.

I have a strong suspicion that all of the answers here are nothing more than hacks. I've tried them all and many others, but without any reliable conclusion as there is always some sort of stupid issue. I for one cannot rely on inconsistent results. If you look at the official Android API documentation for Fragments you will see Google clearly states the following:

Call startActivityForResult(Intent, int) from the fragment's containing Activity.

See: Android Fragment API

So, it would seem that the most correct and reliable approach would be to actually call startActivityForResult() from the hosting activity and also handle the resulting onActivityResult() from there.

2 upvote
  flag
I dont think "call startActivityForResult from Activity" is a recommendation. If you look at the implementation inside Fragment base class, then all it does is mActivity.startActivityFromFragment(this, intent, requestCode) - so it is nothing else but a convenience wrapper – Anti Veeranna
upvote
  flag
I put a real hack out just for you @Chris. – danny117

Your code has a nested fragment. Calling super.onActivityForResult doesn't work

You don't want to modify every activity that your fragment can be called from and or make a work around calling every fragment in the fragment chain.

Here is one of many working solutions. create a fragment on the fly and wire it directly to the activity with the support fragment manager. Then call startActivityForResult from the newly created fragment.

private void get_UserEmail() {

    if (view == null) {
        return;
    }
    ((TextView) view.findViewById(R.id.tvApplicationUserName))
            .setText("Searching device for user accounts...");

    final FragmentManager fragManager = getActivity().getSupportFragmentManager();

    Fragment f = new Fragment() {
        @Override
        public void onAttach(Activity activity) {
            super.onAttach(activity);
            startActivityForResult(AccountPicker.newChooseAccountIntent(null, null,
                    new String[]{"com.google"}, false, null, null, null, null), REQUEST_CODE_PICK_ACCOUNT);
        }

        @Override
        public void onActivityResult(int requestCode, int resultCode,
                                     Intent data) {
            if (requestCode == REQUEST_CODE_PICK_ACCOUNT) {
                String mEmail = "";
                if (resultCode == Activity.RESULT_OK) {
                    if (data.hasExtra(AccountManager.KEY_ACCOUNT_NAME)) {
                        mEmail = data
                                .getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
                    }
                }
                if (mActivity != null) {
                    GoPreferences.putString(mActivity, SettingApplication.USER_EMAIL, mEmail);
                }
                doUser();
            }
            super.onActivityResult(requestCode, resultCode, data);
            fragManager.beginTransaction().remove(this).commit();
        }
    };
    FragmentTransaction fragmentTransaction = fragManager
            .beginTransaction();
    fragmentTransaction.add(f, "xx" + REQUEST_CODE_PICK_ACCOUNT);
    fragmentTransaction.commit();
}
upvote
  flag
This actually works and I've only got one vote for it. Create a fragment on the fly. Too easy but its true working solution. Someone even tried to edit it for me. – danny117

Solution 1:

Call startActivityForResult(intent, REQUEST_CODE); instead of getActivity().startActivityForResult(intent, REQUEST_CODE);.

Solution 2:

When startActivityForResult(intent, REQUEST_CODE); is called the activity's onActivityResult(requestCode,resultcode,intent) is invoked, and then you can call fragments onActivityResult() from here, passing the requestCode, resultCode and intent.

upvote
  flag
You ought to provide some sample code. – W.K.S

Inside your fragment, call

this.startActivityForResult(intent, REQUEST_CODE);

where this is referring to the fragment. Otherwise do as @Clevester said:

Fragment fragment = this;
....
fragment.startActivityForResult(intent, REQUEST_CODE);

I also had to call

super.onActivityResult(requestCode, resultCode, data);

in the parent activity's onActivityResult to make it work.

(I adapted this answer from @Clevester's answer.)

I also met this problem in a Fragment. And I called startActivityForResult in a DialogFragment.

But now this problem has been resolved:
FragmentClassname.this.startActivityForResult.

upvote
  flag
Great, worked for me, because I was calling startActivityForResult(...) from an abstract class inside the fragment's code. – Vince

Simply use the below code for the fragment.

@Override
public void onOtherButtonClick(ActionSheet actionSheet, int index) {

    if (index == 1)
    {
        Intent intent = new Intent(Intent.ACTION_PICK,
                                   android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        intent.setType("image/*");
        startActivityForResult(Intent.createChooser(intent,
                                                    "Select Picture"), 1);
     }
}

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == 1) {
        if (requestCode == 1) {
            Uri selectedImageUri = data.getData();
            //selectedImagePath = getPath(selectedImageUri);
        }
    }
}

onActivityResult will call without calling its parent.

  1. You can simply override BaseActivity onActivityResult on fragment baseActivity.startActivityForResult .

  2. On BaseActivity add interface and override onActivityResult.

    private OnBaseActivityResult baseActivityResult;
    public static final int BASE_RESULT_RCODE = 111;
    public interface OnBaseActivityResult{
        void onBaseActivityResult(int requestCode, int resultCode, Intent data);
       }
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(getBaseActivityResult() !=null && requestCode == BASE_RESULT_RCODE){
        getBaseActivityResult().onBaseActivityResult(requestCode, resultCode, data);
        setBaseActivityResult(null);
    }
    
  3. On Fragment implements OnBaseActivityResult

    @Override
    public void onBaseActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d("RQ","OnBaseActivityResult");
    if (data != null) {
        Log.d("RQ","OnBaseActivityResult + Data");
        Bundle arguments = data.getExtras();
      }
    }
    

This workaround will do the trick.

If the above problem is faced at Facebook login then you can use the below code in a parent activity of your fragment like:

Fragment fragment = getFragmentManager().findFragmentById(android.R.id.tabcontent);
fragment.onActivityResult(requestCode, resultCode, data);

Or:

Fragment fragment = getFragmentManager().findFragmentById("fragment id here");
fragment.onActivityResult(requestCode, resultCode, data);

And add the below call in your fragment...

callbackManager.onActivityResult(requestCode, resultCode, data);

If you are using nested fragments, this is also working:

getParentFragment().startActivityForResult(intent, RequestCode);

In addition to this, you have to call super.onActivityResult from parent activity and fill the onActivityResult method of the fragment.

FOR NESTED FRAGMENTS (for example, when using a ViewPager)

In your main activity:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
}

In your main top level fragment(ViewPager fragment):

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    YourFragment frag = (YourFragment) getChildFragmentManager().getFragments().get(viewPager.getCurrentItem());
    frag.yourMethod(data);  // Method for callback in YourFragment
    super.onActivityResult(requestCode, resultCode, data);
}

In YourFragment (nested fragment):

public void yourMethod(Intent data){
    // Do whatever you want with your data
}
upvote
  flag
This what i was searching for – V. Kalyuzhnyu

Just simply call:

startActivityForResult(intent, "1");
upvote
  flag
Can You please explain in details? – Ronak Gadhia

In my case it was an Android bug (http://technet.weblineindia.com/mobile/onactivityresult-not-getting-called-in-nested-fragments-android/), if you use supported FragmentActivity you have to use getSupportFragmentManager instead of getChildFragmentManager:

List<Fragment> fragments = getSupportFragmentManager().getFragments();
if (fragments != null) {
    for (Fragment fragment : fragments) {
        if(fragment instanceof UserProfileFragment) {
            fragment.onActivityResult(requestCode, resultCode, data);
        }
    }
}

FOR MANY NESTED FRAGMENTS (for example, when using a ViewPager in a fragment)

In your main activity:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
}

In your fragment:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    for (Fragment fragment : getChildFragmentManager().getFragments()) {
        fragment.onActivityResult(requestCode, resultCode, data);
    }
}

In your nested fragment

Call activity

getParentFragment().startActivityForResult(intent, uniqueInstanceInt);

uniqueInstanceInt - replace it with an int that is unique among the nested fragments to prevent another fragment treat the answer.

Receive response

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == uniqueInstanceInt ) {
        // TODO your code
    }
}

Attention

A number between 0 and 65536 need be used in uniqueInstanceInt for error avoid "Can only use lower 16 bits for requestCode".

upvote
  flag
Works great in Activity > Fragment (ViewPager) > Fragment – Oleksandr Firsov
upvote
  flag
You are a life saver, thanks a lot !! – varunkr
upvote
  flag
Thanks your code save my day... – Rana

If there is trouble with the method onActivityResult that is inside the fragment class, and you want to update something that's is also inside the fragment class, use:

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

    if(resultCode == Activity.RESULT_OK)
    {
        // If the user had agreed to enabling Bluetooth,
        // populate the ListView with all the paired devices.
        this.arrayDevice = new ArrayAdapter<String>(this.getContext(), R.layout.device_item);
        for(BluetoothDevice bd : this.btService.btAdapater.getBondedDevices())
        {
            this.arrayDevice.add(bd.getAddress());
            this.btDeviceList.setAdapter(this.arrayDevice);
        }
    }
    super.onActivityResult(requestCode, resultCode, data);
}

Just add the this.variable as shown in the code above. Otherwise the method will be called within the parent activity and the variable will not updated of the current instance.

I tested it also by putting this block of code into the MainActivity, replacing this with the HomeFragment class and having the variables static. I got results as I expected.

So if you want to have the fragment class having its own implementation of onActivityResult, the code example above is the answer.

One of the simplest way is to start an activity from your fragment.

startActivity(ActivityName);

Then, add you call startActivityForResult(intent,"1"); from your Activity and add onActivityResult in your activity

startActivityForResult(intent,"1");

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.dualPane);
    fragment.onActivityResult(requestCode, resultCode, data);
// perform other activity result like fetching from Uris or handling cursors

finish(); // finish the activity will  get to back to your fragment.
}

My Problem was with the Host activity I found it with a set android:launchMode="standard" I removed it temporary an it work !

One point no one has mention that make sure your Host Activity launch mode must not set to singleInstance or singleTask.

onActivityResult will not work if your launch mode set to SingleInstance or SingleTask. or you call your activity using these IntentFilters

standard or singleTop launch mode will work fine.

This is one of the most popular issue. We can found lots of thread regarding this issue. But none of them is useful for ME.

So I have solved this problem using this solution.

Let's first understand why this is happening.

We can call startActivityForResult directly from Fragment but actually mechanic behind are all handled by Activity.

Once you call startActivityForResult from a Fragment, requestCode will be changed to attach Fragment's identity to the code. That will let Activity be able to track back that who send this request once result is received.

Once Activity was navigated back, the result will be sent to Activity's onActivityResult with the modified requestCode which will be decoded to original requestCode + Fragment's identity. After that, Activity will send the Activity Result to that Fragment through onActivityResult. And it's all done.

The problem is:

Activity could send the result to only the Fragment that has been attached directly to Activity but not the nested one. That's the reason why onActivityResult of nested fragment would never been called no matter what.

Solution:

1) Start Intent in your Fragment by below code:

       /** Pass your fragment reference **/
       frag.startActivityForResult(intent, REQUEST_CODE); // REQUEST_CODE = 12345

2) Now in your Parent Activity override **onActivityResult() :**

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
    }

You have to call this in parent activity to make it work.

3) In your fragment call:

@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {

       }
}

That's it. With this solution, it could be applied for any single fragment whether it is nested or not. And yes, it also covers all the case! Moreover, the codes are also nice and clean.

1 upvote
  flag
Best answer for me! and why not use this.startActivityForResult in Fragment? – AndrewS
upvote
  flag
Thanks its works. Very good answer. – Hiren

Not the answer you're looking for? Browse other questions tagged or ask your own question.