Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resolving the URI from different sources in Android while opening an image

My Android app opens images and makes manipulations on them. My Activity requests an image to be opened as follows:

Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
                                            "Complete action using"),
                                            PICK_FROM_FILE);

On doing this, it launches a dialog with three to four options, like the ES File Explorer: Files, Gallery, etc.

I wish to read this as a Bitmap using BitmapFactory.decodeFile(path).

When I choose the file from ES File Explorer, the path is computed like this:

String path = imageData.getData().getPath();

However, this does not work for choosing an image from the Gallery or Files, where the value of path is /external/images/media/38 for example.

So I put a check, to convert such a path that begins with external using:

if (path.startsWith("/external")) {
  path = getFilePathFromUri(imageData.getData());
}

private String getFilePathFromUri(Uri uri) {
  Cursor cursor = managedQuery(uri,
                               new String[] { MediaStore.Images.Media.DATA },
                               null, null, null);
  int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
  cursor.moveToFirst();

  return cursor.getString(column_index);
}

This converts the above path to /mnt/sdcard/dcim/Camera/2011-11-13_15-33-24_304.jpg and now this works for BitmapFactory.decodeFile(path).

I understand that hardcoding such a check (/external) is not a good idea, is there a better, perhaps generic way to resolve the format of the URI returned in the Intent?

like image 619
Tanager4 Avatar asked Feb 22 '23 10:02

Tanager4


1 Answers

I understand that hardcoding such a check (/external) is not a good idea, is there a better, perhaps generic way to resolve the format of the URI returned in the intent?

imageData.getData() returns a Uri. If its path starts with file:// (this is what most file managers will return), then the uri represents a file. Another option is uri represents a content item (this is what Gallery will return), in this case its path starts with content:// and you should call ContentProvider for an actual image file path (as you do in your sample). So I think you could go with something like this:

Uri uri = imageData.getData();
String scheme = uri.getScheme();
if ("file".equals(scheme)) {
    // process as a uri that points to a file
} else if ("content".equals(scheme)) {
    // process as a uri that points to a content item
}
like image 151
Vit Khudenko Avatar answered Mar 30 '23 00:03

Vit Khudenko