【问题标题】:Fragment get closed after Camera Intent相机意图后片段关闭
【发布时间】:2015-09-29 11:22:48
【问题描述】:

我正在使用片段中的相机意图拍照。在某些设备上它可以完美运行,但在某些设备上,我的片段在拍照后会关闭。

这是我调用相机意图的代码:

Intent picIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
getActivity().startActivityForResult(picIntent, Constants.TAKE_PICTURE_SIGN_UP);

这是我的 MainActivity 的 onActivityResult:

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(requestCode == Constants.TAKE_PICTURE_SIGN_UP || requestCode == Constants.SELECT_PICTURE_SIGN_UP)
    {
        SignUpFragment frag = (SignUpFragment)getSupportFragmentManager().findFragmentByTag(Constants.SignUpFragmentTag);
        if(frag != null && frag.isVisible())
        {
            frag.onActivityResult(requestCode, resultCode, data);
        }
    }
}

当我从图库中选择图片时,它可以正常工作,但是当我从相机碎片中拍照时,它是空的。是什么原因导致这里出现问题以及如何解决?

【问题讨论】:

  • 您在使用 ChildFragmentManager 吗?因为在某些设备上,如果片段是 ChildFragment 并且 onActivityResult 被关闭片段的主 Activity 捕获,则 onActivityResult 无法正常工作
  • protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK) { Bitmap photo = (Bitmap) data.getExtras().get("数据”); imageView.setImageBitmap(照片); } }
  • 我正在使用 SupportFragmentManager。由于片段有 1 个父活动,即 MainActivity。在从图库中选择图片时,我能够找到片段标签,但在从相机拍照时 findFragmentByTag 返回 null。 @DarioPicco
  • 这只是 Activity getting Destroyed after calling Camera Intent 现象的另一个例子。这有时可能会发生,在某些设备上比在其他设备上更频繁。修复是实现实例状态的保存/恢复。有关代码 sn-ps,请参阅 this answer
  • @MianAzhar 嗨,你有什么解决办法吗? M 面临同样的问题。

标签: android android-fragments android-intent camera


【解决方案1】:

除了@Mina Azhar answer, 当系统杀死低内存的后台活动时,您必须处理。

fragment.startActivityForResult(picIntent, Constants.TAKE_PICTURE_SIGN_UP);
  • 你需要保存片段状态,

    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
       outState.putParcelable("cameraMediaOutputUri", mImageCaptureUri);
      super.onSaveInstanceState(outState);
    }
    

恢复片段状态 Fragment Life Cycle

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    if (savedInstanceState !=null && savedInstanceState.containsKey("cameraMediaOutputUri"))
        mImageCaptureUri = savedInstanceState.getParcelable("cameraMediaOutputUri");
}

【讨论】:

  • 这行得通,但片段的状态经常会丢失
【解决方案2】:

我使用以下 coe,它对我有用

Intent picIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

File f = new File(android.os.Environment.getExternalStorageDirectory(), "temp1.jpg");
Uri mImageCaptureUri = Uri.fromFile(f);

picIntent.putExtra(MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
getActivity().startActivityForResult(picIntent, Constants.TAKE_PICTURE_SIGN_UP);

【讨论】:

    【解决方案3】:

    您已致电:getActivity().startActivityForResult(intent,111);

    您应该致电:startActivityForResult(intent,111);

    也试试

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

    【讨论】:

    • 我试过了,但这样相机不会将结果返回给 MainActivity 的 onActivityResult。
    • 摄像头的结果被 MainActivity 捕获,我们无法在活动中访问 getChildFragmentManager()。而且我无法在相机结果后按标签获取片段。
    【解决方案4】:

    使用这样的方法来确保您的片段已附加并显示:

    private MyFragmentA switchToFragmentA(){
    
        FragmentManager fm = getSupportFragmentManager();
        MyFragmentA fragment = (MyFragmentA) fm.findFragmentByTag(TAG_A);
    
        if(fragment == null){
            fragment = MyFragmentA.newInstance();
        }
    
        fm.beginTransaction().replace(R.id.fragment_container, fragment, TAG_A).commit();
    
        return fragment;
    }
    

    然后像这样调整你的 onActivityResult:

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(requestCode == Constants.TAKE_PICTURE_SIGN_UP || requestCode == Constants.SELECT_PICTURE_SIGN_UP){
            switchToFragmentA().onActivityResult(requestCode, resultCode, data);
        }
    }
    

    【讨论】:

    • 我有 3 个片段 A、B 和 C。从 MainActivity 我转到片段 A,然后从那里转到片段 B,最后我移动到我正在拍照的片段 C。那我应该如何保持对片段 C 的引用?
    • 我采用了一种基于您拥有三个片段的新方法-您可以使用三种方法,例如我的答案中的方法,每个片段一个。然后您就会知道它始终存在且可用
    【解决方案5】:

    问题:是相机活动破坏了您的活动和片段。现在正确的解决方案是实现所有片段和活动的onSaveInstanceState 方法。

    不得已的快速解决方案:将活动设置为不破坏方向更改和屏幕重新大小等。为此,在您的清单文件中为主活动或具有该特定片段的活动添加这一行

    <activity
            android:name=".MainActivity_"
            android:configChanges="orientation|keyboardHidden|screenSize"
    </activity>
    

    在这里阅读android:configChanges

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-30
      相关资源
      最近更新 更多