0

I have read through the related posts. In every quaestion I see that onActivityResult() of activity gets called at least..the problem is how to carry the result to the fragments or nested fragments. But issue I am facing is different.
I am implementing Settings page that will have tabs with TabLayout from new Design Support library. In my app I have a single Activity which holds other Fragments...so I added a SettingsTabFragment which has ViewPager and a FragmentPagerAdapter to it.This adapter holds fragments for each tab.
One of the tab is User Profile settings where user can add his profile pic. And I called startActivityResult() from child fragment with ACTION_PICK intent. I overriden the onActivityResult() in Activity, in parent fragment (that holds view pager) and in SettingsTabFragment too. But none of them get called when I chose the pic from gallery.

None of onActivityResult() get called when startActivityResult() called from:
- child fragment.
- parent fragment. I did this from child frag getParentFragment().startActivityResult() AND also from within the parent fragment itself which is attached to activity directly (not nested).
- called using activity from child fragment with getParentFragment().getActivity().startActivityResult().

None of them lead to call onActivityResult() of, at least, activity.

When I called startActivityResult() from fragment I made sure I called just startActivityResult()..not getActivity().startActivityResult().

I follwed onActivityResult is not being called in Fragment and tried the github lib suggested in one of the answers but seems owner told it is not recommended now. Also it has got compilation errors.

Nay thoughts on it ?

Community
  • 1
  • 1
cgr
  • 4,578
  • 2
  • 28
  • 52
  • 1
    This is a known limitation. Call `startActivityForResult()` on the `Activity`, or possibly on the parent fragment, and have the activity/parent fragment pass the results down to the child fragment. – CommonsWare Nov 13 '15 at 17:20
  • I have done that using the callbacks. from child fragment callBackToActivity.launchImagePicker() but no result. I tried from parent fragment too but of no use. – cgr Nov 13 '15 at 17:23
  • i agree with @CommonsWare initially onActivityResult of the parent activity will be called. You need to override the onActivityResult of both parent fragment and the parent activity – Preethi Rao Nov 13 '15 at 17:27
  • That is what the issue is : onActivityResult() of activity itself is not being called. If I get that I can somehow move that results to any other components. – cgr Nov 13 '15 at 17:29
  • I have the same issue did you find any solution for that?? – Baqir Dec 09 '15 at 09:49
  • This is my code in child fragment in view pager.. I used getParentFrag().getActivity().startActRes(). This made onActivityResult() of activity hit where I have super.onActivityResult() due to which onActivityResult() of parent fragment is hit where I passed the result to child fragment. Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
getParentFragment().getActivity().startActivityForResult(i, BaseActivity.REQUEST_CODE_LOAD_IMAGE); – cgr Dec 09 '15 at 10:27

4 Answers4

1

In my case i was picking up the mobile number from the contact by using intent in my child fragment class i.e. one of tab of view pager.

calling the parent fragment from MainActivity:

// Home is my parent fragment which contains Tab Layout and View Pager. I am calling Home Fragment by specifying tag, i will use this tag later on.

Fragment fragment = new Home();
fragmentManager.beginTransaction()
               .replace(R.id.main_content, fragment, "MobileTag")
               .addToBackStack(null)
               .commit();

In My child Fragment class:

Intent intent = new Intent(Intent.ACTION_PICK, 
                           ContactsContract.Contacts.CONTENT_URI);
intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);
startActivityForResult(intent, 1);

Now it will call the onActivityResult method of MainActivity class In Main Activity:

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

By Calling super in onActivityResult of MainActivity will make a call to Parent fragment's i.e. Home Fragment's onActivityResult method.

In Parent Fragment i.e. Home Fragment:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    Fragment fragment = getFragmentManager()
        .findFragmentByTag("MobileTag")
        .getChildFragmentManager()
        .getFragments()
        .get(0);
    fragment.onActivityResult(requestCode, resultCode, data);
}

here I am getting the 0th Child of parent fragment e.g. In View Pager Adapter if Fragment are added like:

@Override
public Fragment getItem(int position) {
    switch (position){
        case 0 :return new ChildFragment0();
        case 1 : return new ChildFragment1();
        case 2 : return new ChildFragment2();
    }
    return null;
}

Then

getFragmentManager()
   .findFragmentByTag("MobileTag")
   .getChildFragmentManager()
   .getFragments()
   .get(0); // will return ChildFragment0

After this Make a call to child fragment's onActivityResult method:

And Finally In Child Fragment:

public void onActivityResult(int reqCode, int resultCode, Intent data) {
    Cursor cursor = null;
    String contactNumber = "";           
    Uri result = data.getData();
    // get the result here
}
JJD
  • 50,076
  • 60
  • 203
  • 339
Baqir
  • 717
  • 1
  • 7
  • 20
0

Currently, it's a known Android bug. Until this is solved a workaround can be used:

public class HackForResultFragment extends Fragment {

    private static Fragment _callingFragment;

    private Intent _intent;
    private int _requestCode;


    public static HackForResultFragment newInstance(int _requestCode, Intent _intent){

        HackForResultFragment fragment = new HackForResultFragment();
        Bundle bundle = new Bundle(2);
        bundle.putInt("_requestCode", _requestCode);
        bundle.putParcelable("_intent", _intent);
        fragment.setArguments(bundle);
        return fragment;
    }

    public HackForResultFragment() {
    }

    public void setCallingFragment(Fragment callingFragment){
        _callingFragment = callingFragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Bundle arguments = getArguments();
        if (arguments == null) {
            //Error handling
            LogUtil.Error("arguments should have been passed to HackForResultFragment");
        }
        else {
            _requestCode = arguments.getInt("_requestCode");
            _intent = arguments.getParcelable("_intent");
        }

        if (savedInstanceState == null) { //first time only
            startActivityForResult(_intent, _requestCode);
        }
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
    }

    @Override
    public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
        if (_requestCode == requestCode) {

            if (_callingFragment != null) {
                _callingFragment.onActivityResult(requestCode, resultCode, data);
                _callingFragment = null;
            }
        }
        getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit();

    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        outState.putBoolean("startActivityForResultAlreadyCalled",true);
    }
}

In your calling fragment override startActivityForResult:

@Override
public void startActivityForResult(final Intent _intent, final int _requestCode) {
    FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
    HackForResultFragment f = HackForResultFragment.newInstance(_requestCode,_intent);
    f.setCallingFragment(this);
    fragmentManager.beginTransaction().add(f, null).commit();
}
JJD
  • 50,076
  • 60
  • 203
  • 339
Borg972
  • 1
  • 2
0

This bug is now resolved in support library version 23.2.0, so the best way to solve this now is to upgrade the support library.

Source: https://code.google.com/p/android/issues/detail?id=40537#c40

Borg972
  • 1
  • 2
  • But I think my previous answer has value too - some people may not want to upgrade their support library for various reasons – Borg972 Apr 25 '16 at 00:45
  • In that case, you can combine the answer which will be even more useful..I think so. – cgr Apr 25 '16 at 08:13
0

if FragmentActivity contain fragment1, fragment1 contain fragment2. Android can only handle fragment1.startActivityForResult,fragment2.startActivityForResultwill not working.

For more detail and solution, watch the this answer answer

Community
  • 1
  • 1
leikaiyi
  • 41
  • 2