Wednesday, January 25, 2012

Android API quirks - getting an image from gallery

Here's the recommended intent to get an image from gallery

final Intent i = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, REQUEST_GALLERY);

And then, uri can be retrieved from Intent in onActivityResult:

final Uri imageUri = data.getData();
final String[] columns = { MediaColumns.DATA }
final Cursor cursor = activity.getContentResolver().query(imageUri, columns, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(MediaColumns.DATA);
String filePath = cursor.getString(columnIndex);

However, on never OS's, 3.x and 4.x, images may come from picassa with the following urls: "content://com.google.android.gallery3d.provider/picasa/item/", and then MediaColumns.DATA cannot be used to retrieve file path.

There is an unresolved issue in google issue tracker. I found a way to support picassa urls. Namely, just use the following columns when querying provider (second one is supported by picassa):

final String[] columns = { MediaColumns.DATA, MediaColumns.DISPLAY_NAME };

and then, put it all together to get the actual data (using openInputStream for picassa provider):

int columnIndex = cursor.getColumnIndex(MediaColumns.DATA);
if (columnIndex != -1) {
//regular processing for gallery files
String fileName = cursor.getString(columnIndex);
} else {
// this is not gallery provider
columnIndex = cursor.getColumnIndex(MediaColumns.DISPLAY_NAME);
if (columnIndex != -1) {
final InputStream is = getContentResolver().openInputStream(imageUri);
}
}

I think that API is a bit quirky here, so this is more of a workaround, not real solution. If anyone knows a better solution, please post.