ChatGPT解决这个技术问题 Extra ChatGPT

onActivityResult is not being called in Fragment

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);
    }
}
check this post, there is problem description and common workaround solution: stackoverflow.com/questions/6147884/…
Any one else reading this make sure you pass requestCode >= 0!
Also make sure your Activity LauchMode must not singleInstance or singleTask. otherwise onActivityResult will not called
We need to redirect the onActivityResult in the Activity to the Fragment. Refer this link: codexpedia.com/android/…

P
Pankaj Lilan

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.


In your activity's onActivityResult, call super.onActivityResult()
@StErMi Make sure you call startActivityForResult() and not getActivity().startActivityForResult() from your fragment. See siqing answer below.
There appears to be a related bug, where the support library is being used code.google.com/p/android/issues/detail?id=15394
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.
@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)
P
Peter Mortensen

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


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().
@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
V
Vinayak

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
}

This worked for me. It's a nasty workaround, but I don't have a better idea to solve this idiotic bug...
@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.
superb answer. I implemented the third solution to get it done.
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 =/
@notGeek You are correct . Result is always recived in Activity even though you called from fragment or activity .
V
Vladislav Varslavans

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

Damn, I thought i just found the simpliest solution, but there is no such method as getFragments().
@WindRider There is. If you use Android support library (AppCompat).
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); `
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.
This works like charm man, You saved my day. Thank you so much buddy.
P
Piyush

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

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.
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.
P
Peter Mortensen

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:

https://i.stack.imgur.com/F92yr.png

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.

https://i.stack.imgur.com/qgcFV.png

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

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


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
I answered on github, so let's move this conversation out of here github.com/shamanland/nested-fragment-issue/issues/…
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.
K
KishuDroid

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.


I was requesting the system intent with 'activity' i just had to use fragment context.
this should be the accepted solution, it explains whats happening not just baby feed the code
M
Mohit Mehta

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

This works with Android Navigation Component. Other answers didn't work for me as I also use Android Navigation Component
P
Peter Mortensen

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


Works great in Activity > Fragment (ViewPager) > Fragment
S
Shamsul Arefin Sajib

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


j
jowett

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"

O
Oscar Emilio Perez Martinez

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

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) } }
Working for Kotlin Navigation Component
Should I write code (for example if(resultCode != Result_ok)) inside forEach scope or inside the main scope after the forEach scope ?
It solved my problem , Nav graph fragment onActivityResult . WellDone
C
Community

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
}

P
Peter Mortensen

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.


Great, worked for me, because I was calling startActivityForResult(...) from an abstract class inside the fragment's code.
P
Piyush

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

G
Graham Savage

In short,

In fragment, declare Fragment fragment = this;

after that use fragment.startActivityForResult.

The result will return in activityResult.


P
Peter Mortensen

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.


P
Peter Mortensen

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


E
Edward Quixote

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:

Answer in this post

Answer in this post

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 lsActiveFragments = getSupportFragmentManager().getFragments(); for (Fragment fragmentActive : lsActiveFragments) { if (fragmentActive instanceof NavHostFragment) { List lsActiveSubFragments = fragmentActive.getChildFragmentManager().getFragments(); for (Fragment fragmentActiveSub : lsActiveSubFragments) { if (fragmentActiveSub instanceof FragWeAreInterestedIn) { fragmentActiveSub.onActivityResult(requestCode, resultCode, data); } } } } }


p
prolink007

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


K
Ken Herbert
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);
    }
} 

K
Khaled Lela

You can simply override BaseActivity onActivityResult on fragment baseActivity.startActivityForResult . 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); } 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.


P
Peter Mortensen

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

d
dominik

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

R
Ranjithkumar

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

K
Karan Negi

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

P
Peter Mortensen

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.


P
Peter Mortensen

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.


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
d
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();
}

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.
N
NotCool

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