Single intent to let user take picture OR pick image from gallery in Android

UPDATE: The other answer, using EXTRA_INITIAL_INTENTS, is a better one at this point. At the time I wrote my answer, EXTRA_INITIAL_INTENTS did not yet exist, as it was added in API Level 5.

So is there a way to combine both or am I going to have to offer a menu to do one or the other from within my application?

Write your own gallery that has the features you desire.

I would think a menu would be simpler.

Seems like it would be a common use case...surely I'm missing something?

The developer next to you will think the gallery should allow you to pick from the local gallery or else hop out to Flickr to make a selection from there. Another developer will think the camera should not only allow to "take a picture" via the camera but to "take a picture" via choosing something from the gallery, inverting things from the way you envision it. Yet another developer will think that the gallery should allow picking from the local gallery, or Flickr, or the camera, or a network-attached webcam. Still another developer will think that the gallery is stupid and users should just pick files via a file explorer. And so on.

All of this in an environment (mobile phones) where flash for the OS is at a premium.

Hence, IMHO, it is not completely shocking that the core Android team elected to provide building blocks for you to assemble as you see fit, rather than trying to accommodate every possible pattern.


You can proceed in this way in your Activity:

private static final int REQUEST_CODE_PICTURE= 1;

    /**
     * Click on View to change photo. Sets into View of your layout, android:onClick="clickOnPhoto"
     * @param view View
     */
    public void clickOnPhoto(View view) {
        Intent pickIntent = new Intent();
        pickIntent.setType("image/*");
        pickIntent.setAction(Intent.ACTION_GET_CONTENT);
        Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        String pickTitle = "Take or select a photo";
        Intent chooserIntent = Intent.createChooser(pickIntent, pickTitle);
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] { takePhotoIntent });
        startActivityForResult(chooserIntent, REQUEST_CODE_PICTURE);
    }

Then, add always in your Activity the method onActivityResult:

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_PICTURE && resultCode == Activity.RESULT_OK) {
            if (data == null) {
                return;
            }
            try {
                InputStream inputStream = getContentResolver().openInputStream(data.getData());
                Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                imgPhoto.setImageBitmap(bitmap);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

You can try doing something like this:

// ...
// Within your enclosing Class
// ...
private static final int SELECT_PICTURE = 1;

// ... 

Intent pickIntent = new Intent();
pickIntent.setType("image/*");
pickIntent.setAction(Intent.ACTION_GET_CONTENT);

Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

String pickTitle = "Select or take a new Picture"; // Or get from strings.xml
Intent chooserIntent = Intent.createChooser(pickIntent, pickTitle);
chooserIntent.putExtra
(
  Intent.EXTRA_INITIAL_INTENTS, 
  new Intent[] { takePhotoIntent }
);

startActivityForResult(chooserIntent, SELECT_PICTURE);

To see how to handle the activitiy's result, please refer to this question


Note: a critical point is how to determine whether the camera or gallery was used. That is shown in this code example: https://stackoverflow.com/a/12347567/294884