Get/pick an image from Android's built-in Gallery app programmatically
This is a complete solution. I've just updated this example code with the information provided in the answer below by @mad. Also check the solution below from @Khobaib explaining how to deal with picasa images.
Update
I've just reviewed my original answer and created a simple Android Studio project you can checkout from github and import directly on your system.
https://github.com/hanscappelle/SO-2169649
(note that the multiple file selection still needs work)
Single Picture Selection
With support for images from file explorers thanks to user mad.
public class BrowsePictureActivity extends Activity { // this is the action code we use in our intent, // this way we know we're looking at the response from our own action private static final int SELECT_PICTURE = 1; private String selectedImagePath; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); findViewById(R.id.Button01) .setOnClickListener(new OnClickListener() { public void onClick(View arg0) { // in onCreate or any event where your want the user to // select a file Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(intent, "Select Picture"), SELECT_PICTURE); } }); } public void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK) { if (requestCode == SELECT_PICTURE) { Uri selectedImageUri = data.getData(); selectedImagePath = getPath(selectedImageUri); } } } /** * helper to retrieve the path of an image URI */ public String getPath(Uri uri) { // just some safety built in if( uri == null ) { // TODO perform some logging or show user feedback return null; } // try to retrieve the image from the media store first // this will only work for images selected from gallery String[] projection = { MediaStore.Images.Media.DATA }; Cursor cursor = managedQuery(uri, projection, null, null, null); if( cursor != null ){ int column_index = cursor .getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); String path = cursor.getString(column_index); cursor.close(); return path; } // this is our fallback here return uri.getPath(); }}
Selecting Multiple Pictures
Since someone requested that information in a comment and it's better to have information gathered.
Set an extra parameter EXTRA_ALLOW_MULTIPLE
on the intent:
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
And in the Result handling check for that parameter:
if (Intent.ACTION_SEND_MULTIPLE.equals(data.getAction())) && Intent.hasExtra(Intent.EXTRA_STREAM)) { // retrieve a collection of selected images ArrayList<Parcelable> list = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); // iterate over these images if( list != null ) { for (Parcelable parcel : list) { Uri uri = (Uri) parcel; // TODO handle the images one by one here } }}
Note that this is only supported by API level 18+.
Here is an update to the fine code that hcpl posted. but this works with OI file manager, astro file manager AND the media gallery too (tested). so i guess it will work with every file manager (are there many others than those mentioned?). did some corrections to the code he wrote.
public class BrowsePicture extends Activity { //YOU CAN EDIT THIS TO WHATEVER YOU WANT private static final int SELECT_PICTURE = 1; private String selectedImagePath; //ADDED private String filemanagerstring; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ((Button) findViewById(R.id.Button01)) .setOnClickListener(new OnClickListener() { public void onClick(View arg0) { // in onCreate or any event where your want the user to // select a file Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(intent, "Select Picture"), SELECT_PICTURE); } }); } //UPDATED public void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK) { if (requestCode == SELECT_PICTURE) { Uri selectedImageUri = data.getData(); //OI FILE Manager filemanagerstring = selectedImageUri.getPath(); //MEDIA GALLERY selectedImagePath = getPath(selectedImageUri); //DEBUG PURPOSE - you can delete this if you want if(selectedImagePath!=null) System.out.println(selectedImagePath); else System.out.println("selectedImagePath is null"); if(filemanagerstring!=null) System.out.println(filemanagerstring); else System.out.println("filemanagerstring is null"); //NOW WE HAVE OUR WANTED STRING if(selectedImagePath!=null) System.out.println("selectedImagePath is the right one for you!"); else System.out.println("filemanagerstring is the right one for you!"); } } } //UPDATED! public String getPath(Uri uri) { String[] projection = { MediaStore.Images.Media.DATA }; Cursor cursor = managedQuery(uri, projection, null, null, null); if(cursor!=null) { //HERE YOU WILL GET A NULLPOINTER IF CURSOR IS NULL //THIS CAN BE, IF YOU USED OI FILE MANAGER FOR PICKING THE MEDIA int column_index = cursor .getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); return cursor.getString(column_index); } else return null; }
hcpl's methods work perfectly pre-KitKat, but not working with the DocumentsProvider API. For that just simply follow the official Android tutorial for documentproviders: https://developer.android.com/guide/topics/providers/document-provider.html -> open a document, Bitmap section.
Simply I used hcpl's code and extended it: if the file with the retrieved path to the image throws exception I call this function:
private Bitmap getBitmapFromUri(Uri uri) throws IOException { ParcelFileDescriptor parcelFileDescriptor = getContentResolver().openFileDescriptor(uri, "r"); FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor(); Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor); parcelFileDescriptor.close(); return image;}
Tested on Nexus 5.