120

I'm trying to get image from gallery.

Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(intent, "Select picture"), resultCode ); 

After I returned from this activity I have a data, which contains Uri. It looks like:

content://media/external/images/1 

How can I convert this path to real one (just like '/sdcard/image.png') ?

Thanks

3
  • 1
    This is obviously a very late comment, but I just wanted to point out that the startActivityForResultCode method takes a request code as an argument, not a result code. Commented Apr 8, 2015 at 22:17
  • did uri.getPath() did not give you real path? Commented Jul 9, 2015 at 5:49
  • #Try This Still, if you are getting the problem to get the real path, you can try my answers. Above answers didn't help me. Explanation:- This method gets the URI and then check the API level of your Android device after that according to API level it will generate the Real path. Code for generating real path is different according to API levels. Here is my Answer Commented Apr 6, 2018 at 7:36

9 Answers 9

207

This is what I do:

Uri selectedImageURI = data.getData(); imageFile = new File(getRealPathFromURI(selectedImageURI)); 

and:

private String getRealPathFromURI(Uri contentURI) { String result; Cursor cursor = getContentResolver().query(contentURI, null, null, null, null); if (cursor == null) { // Source is Dropbox or other similar local file path result = contentURI.getPath(); } else { cursor.moveToFirst(); int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); result = cursor.getString(idx); cursor.close(); } return result; } 

NOTE: managedQuery() method is deprecated, so I am not using it.

Last edit: Improvement. We should close cursor!!

Sign up to request clarification or add additional context in comments.

16 Comments

Hi @m3n0R, In Moto G, MediaStore.Images.ImageColumns.DATA column does not exists at all. How to get image without this column?
ERROR Make sure the Cursor is initialized correctly before accessing data from it.. checking in API 19
Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
Crash: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
MediaStore.Images.ImageColumns.DATA is deprecated
|
59

Is it really necessary for you to get a physical path?
For example, ImageView.setImageURI() and ContentResolver.openInputStream() allow you to access the contents of a file without knowing its real path.

4 Comments

Its exactly what I've looked for, but couldn't find. Thanks.
Sorry and If I want to convert this image to file , without getting the real path how to do it ?
The physical path gives access to the filename and the extension. In case of file uploads.
How to store in a database?
27

@Rene Juuse - above in comments... Thanks for this link !

. the code to get the real path is a bit different from one SDK to another so below we have three methods that deals with different SDKs.

getRealPathFromURI_API19(): returns real path for API 19 (or above but not tested) getRealPathFromURI_API11to18(): returns real path for API 11 to API 18 getRealPathFromURI_below11(): returns real path for API below 11

public class RealPathUtil { @SuppressLint("NewApi") public static String getRealPathFromURI_API19(Context context, Uri uri){ String filePath = ""; String wholeID = DocumentsContract.getDocumentId(uri); // Split at colon, use second item in the array String id = wholeID.split(":")[1]; String[] column = { MediaStore.Images.Media.DATA }; // where id is equal to String sel = MediaStore.Images.Media._ID + "=?"; Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, column, sel, new String[]{ id }, null); int columnIndex = cursor.getColumnIndex(column[0]); if (cursor.moveToFirst()) { filePath = cursor.getString(columnIndex); } cursor.close(); return filePath; } @SuppressLint("NewApi") public static String getRealPathFromURI_API11to18(Context context, Uri contentUri) { String[] proj = { MediaStore.Images.Media.DATA }; String result = null; CursorLoader cursorLoader = new CursorLoader( context, contentUri, proj, null, null, null); Cursor cursor = cursorLoader.loadInBackground(); if(cursor != null){ int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); result = cursor.getString(column_index); } return result; } public static String getRealPathFromURI_BelowAPI11(Context context, Uri contentUri){ String[] proj = { MediaStore.Images.Media.DATA }; Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null); int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); return cursor.getString(column_index); } 

font: http://hmkcode.com/android-display-selected-image-and-its-real-path/


UPDATE 2016 March

To fix all problems with path of images i try create a custom gallery as facebook and other apps. This is because you can use just local files ( real files, not virtual or temporary) , i solve all problems with this library.

https://github.com/nohana/Laevatein (this library is to take photo from camera or choose from galery , if you choose from gallery he have a drawer with albums and just show local files)

8 Comments

@Clocker on Samsung S4 neither
Im really its hard to manage all types of source images in android. If you upload, or take choose from galery, the best solution is create as a galery from facebook. Its a custom gallery with just real images in device , no virtual or temporary. I fix all problems in my app using this library . github.com/nohana/Laevatein Its really good library. To customize is not simple, but you can open code and made your changes. I hope this can help you.
Broken on my Samsung S2 with 4.4.1
I need to get the files like pdf or doc, I am unable to get the path. Can you please help me?
Awesome! Finally something that really works. Was looking for this for a long time. Thanks.
|
18

Note This is an improvement in @user3516549 answer and I have check it on Moto G3 with Android 6.0.1
I have this issue so I have tried answer of @user3516549 but in some cases it was not working properly. I have found that in Android 6.0(or above) when we start gallery image pick intent then a screen will open that shows recent images when user select image from this list we will get uri as

content://com.android.providers.media.documents/document/image%3A52530 

while if user select gallery from sliding drawer instead of recent then we will get uri as

content://media/external/images/media/52530 

So I have handle it in getRealPathFromURI_API19()

public static String getRealPathFromURI_API19(Context context, Uri uri) { String filePath = ""; if (uri.getHost().contains("com.android.providers.media")) { // Image pick from recent String wholeID = DocumentsContract.getDocumentId(uri); // Split at colon, use second item in the array String id = wholeID.split(":")[1]; String[] column = {MediaStore.Images.Media.DATA}; // where id is equal to String sel = MediaStore.Images.Media._ID + "=?"; Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, column, sel, new String[]{id}, null); int columnIndex = cursor.getColumnIndex(column[0]); if (cursor.moveToFirst()) { filePath = cursor.getString(columnIndex); } cursor.close(); return filePath; } else { // image pick from gallery return getRealPathFromURI_BelowAPI11(context,uri) } } 

EDIT1 : if you are trying to get image path of file in external sdcard in higher version then check my question

EDIT2 Here is complete code with handling virtual files and host other than com.android.providers I have tested this method with content://com.adobe.scan.android.documents/document/

2 Comments

Hi Friend, yes thats true. but this is happening because now google have a default format to upload all photos from your phone to google docs. And just save thumbinal in your phone. If you get this uri from google docs, you need download the photo before you use this. This is not good in general. So, To fix all problems here, now im using this library. (this library just use local files , and with this solution your problems will be solved) , or you can extract the code from library and improve yourself to attend your problem. github.com/nohana/Laevatein I hope this can help you.
1+, Its work perfect for me. As @JaiprakasSoni said in his answer that i have faced same problem when i run my app in Moto G4 play but when i use above code it works fine for me. Thanks you. You save my time
11

EDIT: Use this Solution here: https://stackoverflow.com/a/20559175/2033223 Works perfect!

First of, thank for your solution @luizfelipetx

I changed your solution a little bit. This works for me:

public static String getRealPathFromDocumentUri(Context context, Uri uri){ String filePath = ""; Pattern p = Pattern.compile("(\\d+)$"); Matcher m = p.matcher(uri.toString()); if (!m.find()) { Log.e(ImageConverter.class.getSimpleName(), "ID for requested image not found: " + uri.toString()); return filePath; } String imgId = m.group(); String[] column = { MediaStore.Images.Media.DATA }; String sel = MediaStore.Images.Media._ID + "=?"; Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, column, sel, new String[]{ imgId }, null); int columnIndex = cursor.getColumnIndex(column[0]); if (cursor.moveToFirst()) { filePath = cursor.getString(columnIndex); } cursor.close(); return filePath; } 

Note: So we got documents and image, depending, if the image comes from 'recents', 'gallery' or what ever. So I extract the image ID first before looking it up.

Comments

9

One easy and best method copy file to the real path and then get their path I checked it 10 devices on android API-16 to API-30 working fine.

@Nullable public static String createCopyAndReturnRealPath( @NonNull Context context, @NonNull Uri uri) { final ContentResolver contentResolver = context.getContentResolver(); if (contentResolver == null) return null; // Create file path inside app's data dir String filePath = context.getApplicationInfo().dataDir + File.separator + "temp_file"; File file = new File(filePath); try { InputStream inputStream = contentResolver.openInputStream(uri); if (inputStream == null) return null; OutputStream outputStream = new FileOutputStream(file); byte[] buf = new byte[1024]; int len; while ((len = inputStream.read(buf)) > 0) outputStream.write(buf, 0, len); outputStream.close(); inputStream.close(); } catch (IOException ignore) { return null; } return file.getAbsolutePath(); } 

3 Comments

EASILY the best solution there is. Absolutely perfect for my use case where I need to get the path for a small file. No need for an file picking library or some other complicated solution to getting the real path. Best part is, it worked on all my devices. Thanks for sharing
for some reason, when I used this, the file is not created on the app folder and then I get it does not exist
@YakirMalka created with the name of temp_file but with no extension like jpg, png .... etc
1

Hii here is my complete code for taking image from camera or galeery

//My variable declaration

protected static final int CAMERA_REQUEST = 0; protected static final int GALLERY_REQUEST = 1; Bitmap bitmap; Uri uri; Intent picIntent = null; 

//Onclick

if (v.getId()==R.id.image_id){ startDilog(); } 

//method body

private void startDilog() { AlertDialog.Builder myAlertDilog = new AlertDialog.Builder(yourActivity.this); myAlertDilog.setTitle("Upload picture option.."); myAlertDilog.setMessage("Where to upload picture????"); myAlertDilog.setPositiveButton("Gallery", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { picIntent = new Intent(Intent.ACTION_GET_CONTENT,null); picIntent.setType("image/*"); picIntent.putExtra("return_data",true); startActivityForResult(picIntent,GALLERY_REQUEST); } }); myAlertDilog.setNegativeButton("Camera", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { picIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(picIntent,CAMERA_REQUEST); } }); myAlertDilog.show(); } 

//And rest of things

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode==GALLERY_REQUEST){ if (resultCode==RESULT_OK){ if (data!=null) { uri = data.getData(); BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; try { BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options); options.inSampleSize = calculateInSampleSize(options, 100, 100); options.inJustDecodeBounds = false; Bitmap image = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options); imageofpic.setImageBitmap(image); } catch (FileNotFoundException e) { e.printStackTrace(); } }else { Toast.makeText(getApplicationContext(), "Cancelled", Toast.LENGTH_SHORT).show(); } }else if (resultCode == RESULT_CANCELED) { Toast.makeText(getApplicationContext(), "Cancelled", Toast.LENGTH_SHORT).show(); } }else if (requestCode == CAMERA_REQUEST) { if (resultCode == RESULT_OK) { if (data.hasExtra("data")) { bitmap = (Bitmap) data.getExtras().get("data"); uri = getImageUri(YourActivity.this,bitmap); File finalFile = new File(getRealPathFromUri(uri)); imageofpic.setImageBitmap(bitmap); } else if (data.getExtras() == null) { Toast.makeText(getApplicationContext(), "No extras to retrieve!", Toast.LENGTH_SHORT) .show(); BitmapDrawable thumbnail = new BitmapDrawable( getResources(), data.getData().getPath()); pet_pic.setImageDrawable(thumbnail); } } else if (resultCode == RESULT_CANCELED) { Toast.makeText(getApplicationContext(), "Cancelled", Toast.LENGTH_SHORT).show(); } } } private String getRealPathFromUri(Uri tempUri) { Cursor cursor = null; try { String[] proj = { MediaStore.Images.Media.DATA }; cursor = this.getContentResolver().query(tempUri, proj, null, null, null); int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); return cursor.getString(column_index); } finally { if (cursor != null) { cursor.close(); } } } public static int calculateInSampleSize( BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of image final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { final int halfHeight = height / 2; final int halfWidth = width / 2; // Calculate the largest inSampleSize value that is a power of 2 and keeps both // height and width larger than the requested height and width. while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) { inSampleSize *= 2; } } return inSampleSize; } private Uri getImageUri(YourActivity youractivity, Bitmap bitmap) { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream); String path = MediaStore.Images.Media.insertImage(youractivity.getContentResolver(), bitmap, "Title", null); return Uri.parse(path); } 

1 Comment

How you know is 100 in this line options.inSampleSize = calculateInSampleSize(options, 100, 100);
1

This helped me to get uri from Gallery and convert to a file for Multipart upload

File file = FileUtils.getFile(this, fileUri); 

https://github.com/iPaulPro/aFileChooser/blob/master/aFileChooser/src/com/ipaulpro/afilechooser/utils/FileUtils.java

Comments

1

This code work for me in android 11 and 12

private static String getRealPathFromURI(Uri uri, Context context) { Uri returnUri = uri; Cursor returnCursor = context.getContentResolver().query(returnUri, null, null, null, null); int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE); returnCursor.moveToFirst(); String name = (returnCursor.getString(nameIndex)); String size = (Long.toString(returnCursor.getLong(sizeIndex))); File file = new File(context.getFilesDir(), name); try { InputStream inputStream = context.getContentResolver().openInputStream(uri); FileOutputStream outputStream = new FileOutputStream(file); int read = 0; int maxBufferSize = 1 * 1024 * 1024; int bytesAvailable = inputStream.available(); //int bufferSize = 1024; int bufferSize = Math.min(bytesAvailable, maxBufferSize); final byte[] buffers = new byte[bufferSize]; while ((read = inputStream.read(buffers)) != -1) { outputStream.write(buffers, 0, read); } Log.e("File Size", "Size " + file.length()); inputStream.close(); outputStream.close(); Log.e("File Path", "Path " + file.getPath()); Log.e("File Size", "Size " + file.length()); } catch (Exception e) { Log.e("Exception", e.getMessage()); } return file.getPath(); } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.