URI resolution from different sources on Android when opening an image

My Android application opens images and does manipulations with them. My activity requests the image to open 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); 

At the same time, it launches a dialog with three or four parameters, such as ES File Explorer: files, gallery, etc.

I want to read this as a bitmap using BitmapFactory.decodeFile(path) .

When I select a file from ES File Explorer, the path is calculated as follows:

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

However, this does not work to select an image from the gallery or files, where, for example, the path value is /external/images/media/38 .

So, I set a check to convert a path that starts with external use:

 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 will convert the above path to /mnt/sdcard/dcim/Camera/2011-11-13_15-33-24_304.jpg , and now it works for BitmapFactory.decodeFile(path) .

I understand that hard coding such a check (/ external) is not a good idea, is there a better, possibly general way to resolve the URI format returned in Intent?

+4
source share
2 answers

I understand that hard coding such a check (/ external) is not a good idea, is there a better, possibly general way to resolve the URI format returned in the intent?

imageData.getData() returns a Uri . If its path starts with file:// (this is what most file managers will return), then uri represents the file. Another option is uri represents a content element (this is what the Gallery will return), in this case its path starts with content:// , and you should call ContentProvider for the actual path of the image file (as in your example). 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 } 
+8
source

You can ask MediaStore to create a bitmap from Uri:

 Bitmap bmp = MediaStore.Images.Media.getBitmap( getContext().getContentResolver(), uri ); 
0
source

Source: https://habr.com/ru/post/1381036/