Gokul Kulkarni
Gokul Kulkarni

Reputation: 2259

Android Chooser intent in fragment to pic photo

I ran into the following issue,

I have the following structure for my project,

  1. There is a parent activity, which will host fragments (in total 3) inside it, layout as shown below,

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
        <FrameLayout
            android:id="@+id/processContent"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_above="@+id/detSaveNContBtn" />
    
    </RelativeLayout>
    
  2. On the launch of the activity First fragment will be loaded, i.e, the framelayout (processContent) will be replaced by the fragment1, Fragment1 has a button, on click of that button, processContent will be replaced by Fragment2, in the same way Fragment3 gets loaded.

In the Fragment3, I have to upload multiple photos, that will be either with camera or from gallery.

So I am using chooser intent for displaying the choice, code for the same is as shown below,

    final File root = new File(Environment.getExternalStorageDirectory() + File.separator + "MyDir" + File.separator);
    root.mkdirs();
    final String fname = "img_" + System.currentTimeMillis();
    final File sdImageMainDirectory = new File(root, fname);
    outputFileUri = Uri.fromFile(sdImageMainDirectory);

    // Camera.
    SignUpProccessActivity activity = (SignUpProccessActivity) getActivity();
    final List<Intent> cameraIntents = new ArrayList<Intent>();
    final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    final PackageManager packageManager = activity.getPackageManager();
    final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
    Uri fileUri = Uri.fromFile(sdImageMainDirectory);
    activity.setCapturedImageURI(fileUri);
    activity.setCurrentPhotoPath(fileUri.getPath());
    for(ResolveInfo res : listCam) {
        final String packageName = res.activityInfo.packageName;
        final Intent intent = new Intent(captureIntent);
        intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
        intent.setPackage(packageName);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, activity.getCapturedImageURI());
        cameraIntents.add(intent);
    }

    // Filesystem.
    final Intent galleryIntent = new Intent();
    galleryIntent.setType("image/*");
    galleryIntent.setAction(Intent.ACTION_GET_CONTENT);

    // Chooser of filesystem options.
    final Intent chooserIntent = Intent.createChooser(galleryIntent, "Select Source");

    // Add the camera options.
    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[cameraIntents.size()]));
    startActivityForResult(chooserIntent, 1888);

When I choose photo from a gallery all is well, but when I try to get image from camera, the activity's oncreate gets called, and hence again Fragment1 will be displayed.

I got to know that oncreate gets called when camera is called because the orientation gets changes from this question, as answered in the question I added the properties,

android:configChanges="orientation|screenSize"
android:screenOrientation="portrait"

But still the same issue.

what is that I am doing wrong in this.

Any help on this would be greatly appreciated.

UPDATE: I checked with by removing the gallery from the chooser, i.e just calling the camera intent after button click, if just camera is there then onActivityResult of the fragment gets called.

Upvotes: 0

Views: 1020

Answers (1)

dominik4142
dominik4142

Reputation: 576

The problem you observe is caused by the fact that the camera apps of some phones force screen orientation changes (and breaks your app as a side-effect - best at it is Samsung, which can force a couple of rotates at once). I learned that the only way to mitigate it is to save the activity (or fragment) instance state in onSaveInstanceState()

Another possible cause can be that while inflating fragments in activity, you don't check if savedInstanceState is not null. By not doing so, you inflate new fragments (replacing old ones). The result is that, fragment's onActivityResult() is never called. (note though, that nested fragments are not supported).

Upvotes: 1

Related Questions