ChatGPT解决这个技术问题 Extra ChatGPT

片段中未调用 onActivityResult

当相机 Activity 返回时,托管此片段的 Activity 会调用其 onActivityResult

我的片段启动了一个结果活动,目的是发送给相机拍照。图片应用程序加载正常,拍照并返回。但是,onActivityResult 永远不会被击中。我设置了断点,但没有触发任何东西。片段可以有 onActivityResult 吗?我会这么认为,因为它是一个提供的功能。为什么不触发这个?

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);
    }
}
检查这篇文章,有问题描述和常见的解决方法:stackoverflow.com/questions/6147884/…
其他阅读本文的人请确保您通过了 requestCode >= 0
还要确保您的 Activity LauchMode 不能是 singleInstance 或 singleTask。否则不会调用 onActivityResult
查看此链接可能会对您有所帮助:androidtutorialonline.com/onactivityresult-in-fragment
我们需要将Activity中的onActivityResult重定向到Fragment。请参阅此链接:codexpedia.com/android/…

P
Pankaj Lilan

托管活动覆盖 onActivityResult(),但它没有为未处理的结果代码调用 super.onActivityResult()。显然,即使片段是发出 startActivityForResult() 调用的片段,活动也会首先处理结果。当您考虑片段的模块化时,这是有道理的。一旦我为所有未处理的结果实现了 super.onActivityResult(),片段就可以处理结果。

还有来自@siqing 的回答:

要在片段中获取结果,请确保在片段中调用 startActivityForResult(intent,111); 而不是 getActivity().startActivityForResult(intent,111);


在您的活动的 onActivityResult 中,调用 super.onActivityResult()
@StErMi 确保从片段中调用 startActivityForResult() 而不是 getActivity().startActivityForResult() 。请参阅下面的四清答案。
似乎有一个相关的错误,其中正在使用支持库 code.google.com/p/android/issues/detail?id=15394
另请注意,如果您使用嵌套片段,则子片段应调用 getParentFragment().startActivityForResult,以便父片段将调用其 onActivityResult 方法。
@EricBrynsvold 是对的, startActivityForResult 在嵌套片段中不起作用。为此,您最好调用getParentFragment().startActivityForResult(),然后在该父片段中实现onActivityResult(),并在该方法中将结果传递给子片段,即:childFragment.getParentFragment()。 onActivityResult(请求代码,结果代码,数据)
P
Peter Mortensen

我想你打电话给 getActivity().startActivityForResult(intent,111);。您应该调用 startActivityForResult(intent,111);


我对位于 PreferenceFragmentRingtonePreference 也有同样的问题。不幸的是,RingtonePreference 调用了 getActivity().startActivityForResult(),即使我在 Activity 的 onActivityResult 中调用了 super.onActivityResult,我也没有得到结果。我不得不创建一个派生自 RingtonePreference 的类,该类将自身绑定到 PreferenceFragment 并调用 fragment.startActivityForResult()
@siqing 我无法从我的静态方法调用 startActivitForResult。有什么解决办法吗?我必须需要使用activity.startActivityForResult。请帮助我
V
Vinayak

选项1:

如果您从片段调用 startActivityForResult(),那么您应该调用 startActivityForResult(),而不是 getActivity().startActivityForResult(),因为它会导致片段 onActivityResult()。

如果您不确定在 startActivityForResult() 上调用的位置以及调用方法的方式。

选项 2:

由于 Activity 获得 onActivityResult() 的结果,因此您需要覆盖 Activity 的 onActivityResult() 并调用 super.onActivityResult() 以传播到相应的片段以获取未处理的结果代码或全部。

如果以上两个选项都不起作用,那么请参考选项 3,因为它肯定会起作用。

选项 3:

从 fragment 到 onActivityResult 函数的显式调用如下。

在父 Activity 类中,重写 onActivityResult() 方法,甚至在 Fragment 类中重写,并调用如下代码。

在父类中:

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

在子类中:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // In fragment class callback
}

这对我有用。这是一个令人讨厌的解决方法,但我没有更好的主意来解决这个愚蠢的错误......
@Vivky,您的回答对我有用。但是我还面临另一个问题,而不是 setResult(); finish(); 当我从第二个活动中按下时,onActivityResult 也会被提供的 RESULT_CODE 调用。
极好的答案。我实施了第三个解决方案来完成它。
我认为解决方案 3 对我有用,但活动的 onActivityResult() 返回一个奇怪的 requestCode,它被传递给我的片段然后被忽略 =/
@notGeek你是对的。即使您从 fragment 或 activity 调用,结果也总是在 Activity 中接收。
V
Vladislav Varslavans

如果您不知道活动中的片段,只需枚举它们并发送活动结果参数:

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

//科特林

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        for (fragment in supportFragmentManager.fragments) {
            fragment.onActivityResult(requestCode, resultCode, data)
        }
    }

该死的,我以为我只是找到了最简单的解决方案,但是没有像 getFragments() 这样的方法。
@WindRider 有。如果您使用 Android 支持库 (AppCompat)。
另外,我学到了必须检查数组中的片段是否不是对自身的引用的艰难方法! ` if(fragment!=this) { fragment.onActivityResult(requestCode, resultCode, data); `
如果片段是嵌套的,这不起作用,因为只有顶部片段会在列表中。我相信 super.onActivityResult() 已经在列表中的所有片段上调用 onActivityResult() ,所以这个想法是多余的。
这就像魅力男,你救了我的命。非常感谢你,伙计。
P
Piyush

我在使用 ChildFragmentManager 时遇到了同样的问题。管理器不会将结果传递给嵌套片段,您必须在基本片段中手动执行此操作。

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

如果您有您的子 Fragment 作为私有成员,则使用 Fragment fragment = myChildFragment; 替换上面的 findFragmentByTag 行代码。其余的可以保持不变。
我想我强烈建议不要将片段保留为私有成员。他们有自己的生命周期,所以你永远不知道他们是否处于良好的互动状态,经理知道。它们也很重,我会担心内存泄漏。如果您不需要使用管理器,则不会创建管理器。
P
Peter Mortensen

Original post.

FragmentActivityrequestCode 替换为修改后的。之后,当 onActivityResult() 将被调用时,FragmentActivity 解析高 16 位并恢复原始 Fragment 的索引。看看这个方案:

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

如果您在根级别有一些片段,则没有问题。但是,如果您有嵌套片段,例如 FragmentViewPager 中有几个选项卡,您保证会遇到问题(或已经遇到问题)。

因为只有一个索引存储在 requestCode 中。那是其 FragmentManager 内的 Fragment 的索引。当我们使用嵌套片段时,有子 FragmentManager,它们有自己的片段列表。因此,有必要保存从根 FragmentManager 开始的整个索引链。

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

我们如何解决此问题? 有常见的解决方法 in this post

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


我有同样的问题,因为我在父片段中使用了 ViewPager,它将其他片段保存为选项卡。尝试使用嵌套片段问题,但最终出现编译错误。你能建议我解决方案吗?在这里也提出了问题github.com/shamanland/nested-fragment-issue/issues/2
我在 github 上回答了,所以让我们把这个对话移出这里github.com/shamanland/nested-fragment-issue/issues/…
谢谢!如果它不是推荐的解决方案,我建议相应地编辑答案,这样人们就不必花时间尝试这个就知道它有编译错误。
K
KishuDroid

这是最受欢迎的问题之一。我们可以找到很多关于这个问题的线程。但它们都对我没有用。

所以我已经使用这个解决方案解决了这个问题。

让我们首先了解为什么会发生这种情况。

我们可以直接从 Fragment 调用 startActivityForResult,但实际上背后的机制都是由 Activity 处理的。

从 Fragment 调用 startActivityForResult 后,requestCode 将更改为将 Fragment 的身份附加到代码中。这将使 Activity 能够在收到结果后追踪发送此请求的人。

一旦 Activity 被导航回来,结果将被发送到 Activity 的 onActivityResult 以及修改后的 requestCode 将被解码为原始 requestCode + Fragment 的身份。之后,Activity 会通过 onActivityResult 将 Activity Result 发送到该 Fragment。这一切都完成了。

问题是:

Activity 只能将结果发送到直接附加到 Activity 的 Fragment,但不能发送到嵌套的 Fragment。这就是为什么无论如何都不会调用嵌套片段的 onActivityResult 的原因。

解决方案:

1)通过以下代码在您的片段中启动意图:

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

2) 现在在您的父活动覆盖中**onActivityResult():**

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

您必须在父活动中调用它才能使其工作。

3)在您的片段调用中:

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

       }
}

而已。使用此解决方案,它可以应用于任何单个片段,无论它是否嵌套。是的,它也涵盖了所有情况!此外,代码也很干净。


我用“活动”请求系统意图,我只需要使用片段上下文。
这应该是公认的解决方案,它解释了发生的事情,而不仅仅是婴儿喂食代码
M
Mohit Mehta

使用 Android Navigation Component 的人应该在 Activity 的 onActivityResult(...) 中使用 primaryNavigationFragment 来获取它的片段引用并调用片段的 fragment.onActivityResult(...)

这是 Activity 的 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);
    }
}

这适用于 Android 导航组件。其他答案对我不起作用,因为我也使用 Android Navigation Component
P
Peter Mortensen

对于许多嵌套片段(例如,在片段中使用 ViewPager 时)

在您的主要活动中:

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

在您的片段中:

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

在您的嵌套片段中

通话活动

getParentFragment().startActivityForResult(intent, uniqueInstanceInt);

uniqueInstanceInt - 用嵌套片段中唯一的 int 替换它,以防止另一个片段处理答案。

收到回复

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

注意力

需要在 uniqueInstanceInt 中使用 0 到 65536 之间的数字以避免错误“只能将低 16 位用于 requestCode”。


在 Activity > Fragment (ViewPager) > Fragment 中效果很好
S
Shamsul Arefin Sajib

当我将这段代码从 Fragment 转移到 Utility Class 时,我也面临同样的问题,parentActivity 作为 argument,

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

然后我在那个 FragmentonActivityResult 方法中没有得到任何值,之后,我将 argument 更改为 Fragment,所以修改后的定义的方法看起来像,

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

之后,我能够在 Fragment 上的 onActivityResult 中获得价值


j
jowett

如果有人仍然无法做到,我可以添加两个建议。在 Manifest.xml 文件中,确保在回调时托管活动未完成,并且要启动的活动以启动模式为标准。请参阅以下详细信息:

对于托管活动,如果有,则将无历史记录属性设置为 false

android:noHistory="false"

对于要启动的 Activity,如果有,请将启动模式设置为标准

android:launchMode="standard"

O
Oscar Emilio Perez Martinez

Kotlin 版本适用于那些使用受 Mohit Mehta 回答启发的 Android 导航组件的人

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

这是正确的代码覆盖 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) } }
为 Kotlin 导航组件工作
我应该在 forEach 范围内还是在 forEach 范围之后的主范围内编写代码(例如 if(resultCode != Result_ok))?
它解决了我的问题,导航图片段 onActivityResult 。做得好
C
Community

FOR NESTED FRAGMENTS(例如,当使用 ViewPager 时)

在您的主要活动中:

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

在您的主要顶级片段(ViewPager 片段)中:

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

在 YourFragment (嵌套片段)中:

public void yourMethod(Intent data){
    // Do whatever you want with your data
}

P
Peter Mortensen

我也在片段中遇到了这个问题。我在 DialogFragment 中调用了 startActivityForResult

但是现在这个问题已经解决了:
FragmentClassname.this.startActivityForResult


太好了,对我有用,因为我从片段代码中的抽象类调用 startActivityForResult(...)
P
Piyush

就我而言,这是一个 Android 错误 (http://technet.weblineindia.com/mobile/onactivityresult-not-getting-called-in-nested-fragments-android/),如果您使用受支持的 FragmentActivity,则必须使用 getSupportFragmentManager 而不是 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

简而言之,

在片段中,声明 Fragment fragment = this;

之后使用 fragment.startActivityForResult

结果将在activityResult中返回。


P
Peter Mortensen

解决方案1:

调用 startActivityForResult(intent, REQUEST_CODE); 而不是 getActivity().startActivityForResult(intent, REQUEST_CODE);

解决方案2:

当调用 startActivityForResult(intent, REQUEST_CODE); 时,将调用 Activity 的 onActivityResult(requestCode,resultcode,intent),然后您可以从这里调用 fragments onActivityResult(),并传递 requestCode, resultCode and intent


P
Peter Mortensen

在您的片段中,调用

this.startActivityForResult(intent, REQUEST_CODE);

其中 this 指的是片段。否则按照@Clevester 所说的那样做:

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

我也不得不打电话

super.onActivityResult(requestCode, resultCode, data);

在父 Activity 的 onActivityResult 中使其工作。

(我根据@Clevester 的回答改编了这个答案。)


E
Edward Quixote

使用 Android 的 Navigation 组件,当您嵌套了 Fragments 时,这个问题可能会让人感觉像是一个无法解开的谜团。

根据本文中以下答案的知识和灵感,我设法制定了一个有效的简单解决方案:

在这个帖子里回答

在这个帖子里回答

在您的 Activity 的 onActivityResult() 中,您可以循环访问您使用 FragmentManagergetFragments() 方法获得的活动片段列表。

请注意,要执行此操作,您需要使用 getSupportFragmentManager() 或定位 API 26 及更高版本。

这里的想法是使用 instanceof 在列表中循环检查列表中每个 Fragment 的实例类型。

虽然循环浏览此 Fragment 类型的列表是理想的,但不幸的是,当您使用 Android 导航组件时,该列表将只有一项,即 NavHostFragment

那么现在怎么办?我们需要让 NavHostFragment 知道 Fragments。 NavHostFragment 本身就是一个片段。因此,使用 getChildFragmentManager().getFragments(),我们再次获得了 NavHostFragment 已知的 List<Fragment> 个片段。我们遍历该列表,检查每个片段的 instanceof

在列表中找到我们感兴趣的 Fragment 后,我们调用它的 onActivityResult(),将 Activity 的 onActivityResult() 声明的所有参数传递给它。

// 你的活动的 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

这些答案中的大多数一直说您必须在您的主机 Activity 中为您的 Fragment 调用 super.onActivityResult(...)。但这似乎对我不起作用。

因此,在您的主机 Activity 中,您应该调用您的 Fragments onActivityResult(...)。这是一个例子。

public class HostActivity extends Activity {

    private MyFragment myFragment;

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

在您的 HostActivity 中的某个时间点,您需要为 this.myFragment 分配您正在使用的 Fragment。或者,使用 FragmentManager 获取 Fragment 而不是在 HostActivity 中保留对它的引用。此外,请在尝试调用 this.myFragment.onActivityResult(...); 之前检查 null


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

您可以简单地在片段 baseActivity.startActivityForResult 上覆盖 BaseActivity onActivityResult 。在 BaseActivity 添加接口并覆盖 onActivityResult。私人 OnBaseActivityResult baseActivityResult;公共静态最终 int BASE_RESULT_RCODE = 111;公共接口 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 实现 OnBaseActivityResult @Override public void onBaseActivityResult(int requestCode, int resultCode, Intent data) { Log.d("RQ","OnBaseActivityResult"); if (data != null) { Log.d("RQ","OnBaseActivityResult + Data");捆绑参数 = data.getExtras(); } }

这种解决方法可以解决问题。


P
Peter Mortensen

如果在 Facebook 登录时遇到上述问题,那么您可以在片段的父活动中使用以下代码,例如:

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

或者:

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

并在您的片段中添加以下调用...

callbackManager.onActivityResult(requestCode, resultCode, data);

d
dominik

其他答案中尚未描述的另一个用例:

使用 exception.startResolutionForResult() 时不调用片段中声明的 onActivityResult()

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

在这种情况下,将 exception.startResolutionForResult() 替换为片段的 startIntentSenderForResult()

if (exception is ResolvableApiException) {
    startIntentSenderForResult(exception.resolution.intentSender, MY_REQUEST_CODE, null, 0, 0, 0, null)
}

R
Ranjithkumar

Kotlin 版本(在您的活动 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

添加这个

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

当你用上面的代码替换你的代码然后自动你的这个

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

方法将开始工作

//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

正如 Ollie C 所提到的,当您使用嵌套片段时,使用返回值到 onActivityResult 的支持库存在一个活动错误。我刚刚击中它:-(。

请参阅 Fragment.onActivityResult not called when requestCode != 0


P
Peter Mortensen

我强烈怀疑这里的所有答案只不过是黑客。我已经尝试了所有这些方法和许多其他方法,但没有任何可靠的结论,因为总是存在某种愚蠢的问题。我不能依赖不一致的结果。如果您查看 Fragments 的官方 Android API 文档,您会看到 Google 清楚地说明了以下内容:

从包含片段的 Activity 调用 startActivityForResult(Intent, int)。

请参阅:Android Fragment API

因此,似乎最正确和最可靠的方法是从托管活动中实际调用 startActivityForResult() 并从那里处理生成的 onActivityResult() 。


我不认为“从 Activity 调用 startActivityForResult”是一个建议。如果您查看 Fragment 基类中的实现,那么它所做的就是 mActivity.startActivityFromFragment(this, intent, requestCode) - 所以它只不过是一个方便的包装器
d
danny117

您的代码有一个嵌套片段。调用 super.onActivityForResult 不起作用

您不想修改可以从中调用您的片段的每个活动,或者绕过调用片段链中的每个片段的工作。

这是许多可行的解决方案之一。动态创建一个片段并使用支持片段管理器将其直接连接到活动。然后从新创建的片段中调用 startActivityForResult。

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

这实际上有效,我只有一票。即时创建片段。太容易了,但它真正的工作解决方案。甚至有人试图为我编辑它。
N
NotCool

我的问题是主机活动,我用一组 android:launchMode="standard" 找到了它,我暂时删除了它,它可以工作!


关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅