1

I am taking picture using camera intent in a fragment. On some devices it works perfect but on some devices my fragment get closed after taking picture.

Here is my code of calling camera intent:

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

Here is my MainActivity's 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);
        }
    }
}

When I select picture from gallery it works fine but when I take picture from camera frag is null. What cause the problem here and how to solve it?

Mian Azhar
  • 57
  • 2
  • 10
  • Are you using the ChildFragmentManager? Because on some device onActivityResult not work correctly if the fragment is a ChildFragment and the onActivityResult are catched by the main Activity closing your fragment – Dario Picco Sep 29 '15 at 11:25
  • protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK) { Bitmap photo = (Bitmap) data.getExtras().get("data"); imageView.setImageBitmap(photo); } } – impathuri Sep 29 '15 at 11:26
  • I am using SupportFragmentManager. As fragment has on 1 parent activity i.e. MainActivity. On selecting picture from gallery I am able to find fragment tag but on taking picture from camera findFragmentByTag return null. @DarioPicco – Mian Azhar Sep 29 '15 at 11:32
  • This is but another example of *[Activity getting Destroyed after calling Camera Intent](http://stackoverflow.com/questions/16014930/android-activity-getting-destroyed-after-calling-camera-intent)* phenomenon. This may happen sometimes, on some devices more often than on others. The fix is to implement save/restore of instance state. See [this answer](http://stackoverflow.com/a/26708283/192373) for code snippets. – Alex Cohn Sep 29 '15 at 20:32
  • @MianAzhar Hi, did you got any solution? M facing same issue. – Nitish Jan 08 '16 at 12:25
  • @Nitish Yes I got solution. I have added it to answer of this post. – Mian Azhar Jan 09 '16 at 16:12

4 Answers4

2

In addition to @Mina Azhar answer, you have to handle when system kill background activities on low memory.

fragment.startActivityForResult(picIntent, Constants.TAKE_PICTURE_SIGN_UP);
  • You need to save fragment state,

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

Restoring Fragment State Fragment Life Cycle

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    if (savedInstanceState !=null && savedInstanceState.containsKey("cameraMediaOutputUri"))
        mImageCaptureUri = savedInstanceState.getParcelable("cameraMediaOutputUri");
}
Khaled Lela
  • 7,831
  • 6
  • 45
  • 73
1

I use the following coe and it worked for me

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);
Mian Azhar
  • 57
  • 2
  • 10
0

Use a method like this to make sure your fragment is attached and displayed:

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

Then adjust your onActivityResult like this:

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);
    }
}
JoeyJubb
  • 2,341
  • 1
  • 12
  • 19
  • I have 3 fragments A, B and C. From MainActivity I go to fragment A and from there I go to fragment B and then finally I move to fragment C where I am taking picture. Then how am I supposed to keep reference of fragment C? – Mian Azhar Sep 29 '15 at 11:36
  • I've taken a new approach based on you having three fragments - you can have three methods like the one in my answer, one for each fragment. Then you'll know it's always there and available – JoeyJubb Sep 29 '15 at 12:53
0

Problem : is that the Camera activity destroys your activity and fragments. Now the proper solution is implementing onSaveInstanceState methods of all fragments and activities.

Last Resort Quick Solution : is to set activity to not destroy on orientation changes and screen re-size etc. For this in your manifest file for the main activity or the activity having that particular fragment add this line

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

Read here about android:configChanges

ahmadalibaloch
  • 5,851
  • 2
  • 50
  • 59