当相机活动返回时,承载这个片段的活动有它的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);
    }
}

当前回答

在我的情况下,这是一个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);
        }
    }
}

其他回答

对于Android的导航组件,当你嵌套fragment时,这个问题就像一个无法解决的谜。

基于以下回答的知识和灵感,我想出了一个简单的解决方案:

在这篇文章中回答 在这篇文章中回答

在你的活动的onActivityResult()中,你可以循环使用FragmentManager的getFragments()方法获得的活动片段列表。

请注意,要做到这一点,您需要使用getSupportFragmentManager()或目标API 26及以上。

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

虽然循环这个Fragment类型的列表是理想的,但不幸的是,当你使用Android导航组件时,列表将只有一个项目,即NavHostFragment。

现在怎么办?我们需要让碎片知道NavHostFragment。NavHostFragment本身就是一个Fragment。因此,使用getChildFragmentManager(). getfragments(),我们再次得到一个List<Fragment>的片段已知我们的NavHostFragment。我们循环遍历这个列表,检查每个Fragment的实例。

一旦我们在列表中找到我们感兴趣的片段,我们就调用它的onActivityResult(),将活动的onActivityResult()声明的所有参数传递给它。

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

只需使用下面的代码片段。

@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将调用而不调用它的父类。

最简单的方法之一是从你的片段开始一个活动。

startActivity(ActivityName);

然后,添加你调用startActivityForResult(intent,"1");在你的Activity中添加onActivityResult

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

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

所以我用这个方法解决了这个问题。

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

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

一旦你从一个Fragment中调用startActivityForResult, requestCode将会被改变以附加Fragment的标识到代码中。这将使Activity能够在收到结果后跟踪发送此请求的人。

一旦Activity被导航回来,结果将被发送到Activity的onActivityResult和修改后的requestCode,它将被解码为原始的requestCode + Fragment的标识。之后,Activity会通过onActivityResult将ActivityResult发送给那个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);
    }

你必须在parent activity中调用它才能使它工作。

3)在你的片段调用中:

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

       }
}

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

选项1:

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

如果你不确定你在哪里调用startActivityForResult()和你将如何调用方法。

选项2:

由于Activity获得onActivityResult()的结果,您将需要覆盖活动的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
}