Android Pick/Select Image from Gallery with Intents

Sometimes in your Android application you’ll want the user to choose an image from the gallery that’ll be displayed by the application (and even uploaded to your servers) after the selection is made. In this article we’ll see how to invoke a single interface from which the user is able to select images across all his apps (like Gallery, Photos, ES File Explorer, etc.) and folders (Google Drive, Recent, Downloads, etc.) using Intents.

Launch the Gallery Image Chooser

Triggering the following Intent from your Activity/Fragment, you can allow the user to select an image.

What's the one thing every developer wants? More screens! Enhance your coding experience with an external monitor to increase screen real estate.

Intent intent = new Intent();
// Show only images, no videos or anything else
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
// Always show the chooser (if there are multiple options available)
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);

PICK_IMAGE_REQUEST is the request code defined as an instance variable.

private int PICK_IMAGE_REQUEST = 1;

More on Android Intents here (if you don’t know much). If you’re wondering why I used ACTION_GET_CONTENT and not ACTION_PICK, then the answer lies here.

Show Up the Selected Image in the Activity/Fragment

Now once the selection has been made, we’ll show up the image in the Activity/Fragment user interface, using an ImageView. For this, we’ll have to override onActivityResult():

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {

        Uri uri = data.getData();

        try {
            Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
            // Log.d(TAG, String.valueOf(bitmap));

            ImageView imageView = (ImageView) findViewById(R.id.imageView);
            imageView.setImageBitmap(bitmap);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Your layout will need to have an ImageView like this:

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/imageView" />

Voila! you’re ready to test the code and see how the selected photo shows up in your UI when you pick from your gallery.

Getting the Absolute File Path from Content URI

The Content URI returned can be different depending upon where the selection has been made from. Especially since Kitkat (API level 19) which introduces the Storage Access Framework (SAF) you get to see all your document storage providers while selecting a photo. The content URIs can different basis each provider and then if you try to use that to get the file path with a piece of code like this (used to generally work pre-Kitkat):

Uri uri = data.getData();
String[] projection = { MediaStore.Images.Media.DATA };

Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
cursor.moveToFirst();

Log.d(TAG, DatabaseUtils.dumpCursorToString(cursor));

int columnIndex = cursor.getColumnIndex(projection[0]);
String picturePath = cursor.getString(columnIndex); // returns null
cursor.close();

Then you’ll notice that the value of MediaStore.Images.Media.DATA returned in the cursor is null.

This issue (and fixes for it) has been addressed in the following StackOverflow threads:

Let’s see the different types of Content URIs returned when making a selection of images from various sections (in the navigation drawer) in the app that is invoked by the Intent. This is what you’d get from a selection in the Gallery (app) section:

content://media/external/images/media/3753

From Recents (or generally I guess), you get this:

content://com.android.providers.media.documents/document/image:2505

and when selecting something from Google Drive, this is the URI:

content://com.google.android.apps.docs.storage/document/acc=1;doc=22

Also from Photos (app) section, you get this (url encoded):

content://com.google.android.apps.photos.content/0/https%3A%2F%2Flh5.googleusercontent.com%2F-H7yZgZCQmFF1zec-_uU0aiyCfol1TH-b9QBWnFZ7rU%3Ds0-d

Hope that’s useful!

Author: Rishabh

Rishabh is a full stack web and mobile developer from India. Follow me on Twitter.

4 thoughts on “Android Pick/Select Image from Gallery with Intents”

  1. Hey, the way you set up your Intent doesn’t work for me. It says cannot find a suitable application in a popup.

    However, this does work:
    Intent pickPhotoIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    startActivityForResult(pickPhotoIntent, PICK_IMAGE_REQUEST);

    With the onActivityResult() remaining the same.

  2. Hey. It’s great you put this up here, but since you mentioned fragment in your post beware that onActivityResult will never get called in fragment. You’ll have to do it manually.

Leave a Reply

Your email address will not be published. Required fields are marked *

*