onActivityResult is not being called in Fragment
Asked Answered
O

40

992

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);
    }
}
Over answered 27/5, 2011 at 4:35 Comment(6)
check this post, there is problem description and common workaround solution: #6148384Topsyturvydom
Any one else reading this make sure you pass requestCode >= 0!Orchitis
Also make sure your Activity LauchMode must not singleInstance or singleTask. otherwise onActivityResult will not calledSabayon
See this link may help you:androidtutorialonline.com/onactivityresult-in-fragmentEmulsion
We need to redirect the onActivityResult in the Activity to the Fragment. Refer this link: codexpedia.com/android/…Chayachayote
How are you even able to call startActivityForResult(cameraIntent, 1888); from a Fragment. Fragments are pieces of a layout and can't interact with the activity's operation unless you intended to do so. You can call getActivity().startActivityForResult(cameraIntent, 1888); And when the result returns pass it to the fragment fragment.onActivityResult(-,-,-)Erythrite
O
1354

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.

Over answered 27/5, 2011 at 4:42 Comment(22)
I have the same issue but I don't understand how you fixed this?Setzer
In your activity's onActivityResult, call super.onActivityResult()Over
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...Spearman
@Spearman Did you call startActivityForResult() in your fragments? I guess if you call that method in activity, it won't notify its fragments... Just guessing...Passbook
@Spidy: +1 for your answers.. such a small thing but ignored by me. thanksBohman
@Spearman Make sure you call startActivityForResult() and not getActivity().startActivityForResult() from your fragment. See siqing answer below.Adaline
There appears to be a related bug, where the support library is being used code.google.com/p/android/issues/detail?id=15394Laurinda
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.Eiffel
was this issue fixed on newer support library versions?Wundt
it may have been, this question/answer was created in the 3.0 eraOver
I have super.onActivityResult in both Fragment and Activity. Still doesn't work either way :(Vermiculite
@Adaline but then there is the issue with the wrong request code being returned.Caudate
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.Salesin
@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(requestCode, resultCode, data)Conjunction
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.Washbowl
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.Methodius
what to do if I want to call startActivityForResult from static method in my fragment? Please help me in this.Tal
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 !Gastrolith
I believe that if the Activity extends android.app.Activity and not FragmentActivity, the onActivityResult base method does nothing. Even in API 24.Bluestocking
@Over adding super.onActivityResult(requestCode, result, intent) in Activity not working for me.Levinson
Also, note that if you are handling sending the result in onBackPressed() method then you shouldn't call super.onBackPressed()Interlay
I wanted to start intent in my adapter, and i tried every method but didn't work, at last i declared a callback interface in my adapter and i start intent in my fragment and its fixed.Legible
M
359

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

Morelock answered 13/6, 2012 at 9:13 Comment(2)
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().Helainehelali
@Morelock 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 thisTal
P
319

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
}
Propylite answered 12/6, 2013 at 9:17 Comment(10)
This worked for me. It's a nasty workaround, but I don't have a better idea to solve this idiotic bug...Memphis
@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.Rabin
superb answer. I implemented the third solution to get it done.Zillah
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 =/Flapper
@Happy Vicky this means that even when startActivityForResult() is called from a fragment, the result is received and can be handled in the activity?Acarid
@Acarid You are correct . Result is always recived in Activity even though you called from fragment or activity .Propylite
in child class, it should be public void onActivityResult(int requestCode, int resultCode, Intent data) { not protectedLurlenelurline
actually, it depends `@ShylendraMadda, when we call things protected we immediately lookup the concept of scope of access. i think the author here intended protected.Galeiform
If you are using Android Navigation Component you should see this answer #6148384Conscription
This worked for me. It was just change getFragmentManager() to getSupportFragmentManager() in Activity and the fragment wasn't null anymore.Luiseluiza
Z
117

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

//Java

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

//Kotlin

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        for (fragment in supportFragmentManager.fragments) {
            fragment.onActivityResult(requestCode, resultCode, data)
        }
    }
Zilvia answered 27/3, 2014 at 10:40 Comment(9)
Damn, I thought i just found the simpliest solution, but there is no such method as getFragments().Satrap
@Satrap There is. If you use Android support library (AppCompat).Hypophosphate
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); `Showpiece
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.Crenshaw
#27344445Adrenalin
what about "android.app.Fragment" ? how to get all fragments ?Misteach
@RjzSatvara for native fragments implementation I used callbacks, broadcasts and message bussesZilvia
Always check for null fragment in fragmentManager. Learnt this the hard way. Copied this code and crashed the app.Zoril
If you are using Android Navigation Component you should see this answer #6148384Conscription
U
86

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);
    }
}
Unmusical answered 8/5, 2013 at 20:44 Comment(2)
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.Moran
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.Unmusical
T
75

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

Topsyturvydom answered 19/6, 2014 at 9:34 Comment(3)
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/2Marolda
I answered on github, so let's move this conversation out of here github.com/shamanland/nested-fragment-issue/issues/…Topsyturvydom
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.Marolda
C
24

For those who use Android Navigation Component should use in Activity's onActivityResult(...) the primaryNavigationFragment to get it's fragment reference and call fragment's fragment.onActivityResult(...).

Here's Activity's onActivityResult(...)

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

    for (Fragment fragment : getSupportFragmentManager().getPrimaryNavigationFragment().getChildFragmentManager().getFragments())
    {
            fragment.onActivityResult(requestCode, resultCode, imageData);
    }
}
Conscription answered 22/11, 2019 at 4:44 Comment(1)
This works with Android Navigation Component. Other answers didn't work for me as I also use Android Navigation ComponentHodson
A
18

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".

Acquit answered 22/1, 2016 at 17:17 Comment(1)
Works great in Activity > Fragment (ViewPager) > FragmentEadie
D
16

I was also facing the same problem once I shifted this block of code outside of a Fragment to a Utility Class, with parentActivity passed as argument,

Intent intent = new Intent(parentActivity, CameraCaptureActivity.class);
parentActivity.startActivityForResult(intent,requestCode);

Then I was not getting any value in onActivityResult method of that Fragment, Afterwards, I changed the argument to Fragment, so the revised definition of method looked like,

Intent intent = new Intent(fragment.getContext(), CameraCaptureActivity.class);
fragment.startActivityForResult(intent,requestCode);

After that, I was able to get value in onActivityResult on the Fragment

Detestable answered 7/2, 2018 at 7:5 Comment(0)
F
16

Kotlin version for those who use Android Navigation Component inspired in Mohit Mehta's answer

 override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    supportFragmentManager.primaryNavigationFragment?.childFragmentManager?.fragments?.forEach { fragment ->
        fragment.onActivityResult(requestCode, resultCode, data)
    }
}
Fiveandten answered 7/4, 2020 at 5:20 Comment(4)
This is the correct code override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) activity?.supportFragmentManager?.primaryNavigationFragment?. childFragmentManager?.fragments?.forEach { fragment -> fragment.onActivityResult(requestCode, resultCode, data) } }Dusk
Working for Kotlin Navigation ComponentSeldan
Should I write code (for example if(resultCode != Result_ok)) inside forEach scope or inside the main scope after the forEach scope ?Evvie
It solved my problem , Nav graph fragment onActivityResult . WellDoneDaytoday
E
13

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"
Edging answered 30/12, 2012 at 3:36 Comment(0)
B
11

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
}
Bridle answered 17/11, 2015 at 12:18 Comment(0)
A
10

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.

Accuse answered 24/12, 2014 at 9:55 Comment(1)
Great, worked for me, because I was calling startActivityForResult(...) from an abstract class inside the fragment's code.Advance
G
8

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);
        }
    }
}
Gauge answered 14/12, 2015 at 14:2 Comment(0)
S
7

In short,

In fragment, declare Fragment fragment = this;

after that use fragment.startActivityForResult.

The result will return in activityResult.

Salvatoresalvay answered 18/7, 2014 at 7:24 Comment(0)
L
7

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

Lyricism answered 23/12, 2014 at 8:11 Comment(1)
In my fragment prefixing it with this as in this.startActivityForResult(...) is what triggered the callback. Thanks!Economy
K
6

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.

Karney answered 18/12, 2014 at 9:1 Comment(0)
B
6

With Android's Navigation component, this problem, when you have nested Fragments, could feel like an unsolvable mystery.

Based on knowledge and inspiration from the following answers in this post, I managed to make up a simple solution that works:

In your activity's onActivityResult(), you can loop through the active Fragments list that you get using the FragmentManager's getFragments() method.

Please note that for you to do this, you need to be using the getSupportFragmentManager() or targeting API 26 and above.

The idea here is to loop through the list checking the instance type of each Fragment in the list, using instanceof.

While looping through this list of type Fragment is ideal, unfortunately, when you're using the Android Navigation Component, the list will only have one item, i.e. NavHostFragment.

So now what? We need to get Fragments known to the NavHostFragment. NavHostFragment in itself is a Fragment. So using getChildFragmentManager().getFragments(), we once again get a List<Fragment> of Fragments known to our NavHostFragment. We loop through that list checking the instanceof each Fragment.

Once we find our Fragment of interest in the list, we call its onActivityResult(), passing to it all the parameters that the Activity's onActivityResult() declares.

//  Your activity's onActivityResult()

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

        List<Fragment> lsActiveFragments = getSupportFragmentManager().getFragments();
        for (Fragment fragmentActive : lsActiveFragments) {

            if (fragmentActive instanceof NavHostFragment) {

                List<Fragment> lsActiveSubFragments = fragmentActive.getChildFragmentManager().getFragments();
                for (Fragment fragmentActiveSub : lsActiveSubFragments) {

                    if (fragmentActiveSub instanceof FragWeAreInterestedIn) {
                        fragmentActiveSub.onActivityResult(requestCode, resultCode, data);
                    }

                }

            }

        }

    }
Borough answered 13/3, 2020 at 12:49 Comment(0)
S
4

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

Salesin answered 8/6, 2014 at 15:4 Comment(0)
N
4

Another use case not already described in other answers:

onActivityResult() declared in fragment is not invoked when using exception.startResolutionForResult():

if (exception is ResolvableApiException) {
    exception.startResolutionForResult(activity!!, MY_REQUEST_CODE)
}

In this case replace exception.startResolutionForResult() with fragment's startIntentSenderForResult():

if (exception is ResolvableApiException) {
    startIntentSenderForResult(exception.resolution.intentSender, MY_REQUEST_CODE, null, 0, 0, 0, null)
}
Neuromuscular answered 18/8, 2019 at 9:17 Comment(0)
E
3

ADD this

public void onClick(View v) {   
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT,MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(intent, 1);
}

when you will replace your code with this above code then automatically your this

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

Method will Start working

//No Need to write this code in onclick method
    Intent intent=new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT)
    startActivityForResult(intent,1);
    Toast.makeText(getContext(), "image"+intent, Toast.LENGTH_SHORT).show();
Edisonedit answered 20/2, 2012 at 11:5 Comment(0)
M
3
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);
    }
} 
Myth answered 8/4, 2013 at 8:31 Comment(0)
B
3
  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.

Balderas answered 31/3, 2015 at 12:54 Comment(0)
S
3

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);
Shirleeshirleen answered 27/10, 2015 at 13:25 Comment(0)
V
3

Kotlin version (In your activity onActivityResult())

 override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    //add following lines in your activity
    if(supportFragmentManager?.fragments!=null && supportFragmentManager?.fragments!!.size>0)
     for (i in 0..supportFragmentManager?.fragments!!.size-1) {
         val fragment= supportFragmentManager?.fragments!!.get(i)
         fragment.onActivityResult(requestCode, resultCode, data)
    }
 }
Villada answered 27/8, 2019 at 11:4 Comment(0)
D
3

With getting help from @Mohit Mehta if you are using Navigation Component this may help you as well. It Worked For me..

In the onActivityResult method of MainActivity paste below code:

for (Fragment fragment : navHostFragment.getChildFragmentManager().getFragments()){
        if (fragment != null){
            Log.d(TAG, "onResult Has Been Sent!");
            fragment.onActivityResult(requestCode, resultCode, data);
        }
    }

and in onActivityResult method of YOUR FRAGMENT you can get the result. Hope this helps you.

Deangelis answered 2/8, 2022 at 6:25 Comment(0)
L
2

first of all you need to override this code in Activity;

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

and after, in your fragment,

startActivityForResult(intent,GALLERY_REQUEST_CODE);

and again than in your fragment,

@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    // Result code is RESULT_OK only if the user selects an Image
    if (resultCode == Activity.RESULT_OK) {

    }

}
Leyte answered 12/11, 2019 at 13:36 Comment(0)
W
1

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.

Woodsia answered 9/6, 2014 at 21:59 Comment(0)
P
1

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.

Patrick answered 15/9, 2014 at 12:47 Comment(1)
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 wrapperUnsex
S
1

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();
}
Sugary answered 23/11, 2014 at 9:25 Comment(1)
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.Sugary
D
1

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.

Defluxion answered 16/11, 2015 at 16:54 Comment(0)
C
1

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

Congregationalist answered 23/6, 2016 at 2:13 Comment(0)
S
1

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.

Sabayon answered 4/8, 2016 at 6:36 Comment(0)
R
1

In my case, in developer options I have turned on "Do not keep activities", which was causing this issue.

In case it helps someone.

Result answered 22/6, 2020 at 10:37 Comment(0)
W
0

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;
}
Wholewheat answered 6/11, 2013 at 9:40 Comment(2)
Why make a work around method when the framework already supports it?Over
For example Facebook -> Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);Wholewheat
H
0

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.

Humpbacked answered 26/12, 2014 at 9:30 Comment(0)
S
0

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.

Scantling answered 4/5, 2016 at 21:40 Comment(0)
M
0

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.
}
Melanie answered 30/5, 2016 at 9:21 Comment(0)
B
0

onActivityResult is deprecated now. You can use follow code:

   registerForActivityResult(ActivityResultContracts.StartActivityForResult()){ result->
    // here you can handle result, result.data and result.resultCode
   }

For start activity

    val intent = Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE)
    launcher.launch(intent)
Brightwork answered 15/6, 2021 at 5:8 Comment(0)
G
-7

Just simply call:

startActivityForResult(intent, "1");
Glantz answered 23/11, 2015 at 10:47 Comment(1)
Can You please explain in details?Wagram

© 2022 - 2024 — McMap. All rights reserved.