Skip to content

Instantly share code, notes, and snippets.

@asifmujteba
Created April 22, 2015 06:31
Show Gist options
  • Save asifmujteba/d89ba9074bc941de1eaa to your computer and use it in GitHub Desktop.
Save asifmujteba/d89ba9074bc941de1eaa to your computer and use it in GitHub Desktop.
Get Real Path from Uri
@TargetApi(Build.VERSION_CODES.KITKAT)
public static String getPath(final Context context, final Uri uri) {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
// TODO handle non-primary volumes
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[] {
split[1]
};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
// Return the remote address
if (isGooglePhotosUri(uri))
return uri.getLastPathSegment();
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
public static String getDataColumn(Context context, Uri uri, String selection,
String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {
column
};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
null);
if (cursor != null && cursor.moveToFirst()) {
final int index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is ExternalStorageProvider.
*/
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is DownloadsProvider.
*/
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is MediaProvider.
*/
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is Google Photos.
*/
public static boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}
@VannesEventurers
Copy link

Hi,
I'm getting the below issue when invoking

getDataColumn(context, uri, null, null)

i'm passing the below uri:

"content://com.google.android.apps.docs.editors.kix.file_content/0yDd-Q1KaMbunyUXHmvNntSrYnskcw4SlLRTp9YWSfNBrq6DUgPHIizZzluaixjYS2YR7-vyEDRE%0Am5tv2CJM4Uby2R6a0j0-O_yWgTljX7SkZrLA88a5YKQwIDDl8E52S50Fzw%3D%3D%0A"

My App get crashed, and i'm getting the below error.

FATAL EXCEPTION: main
Process: MYPACKAGENAME, PID: 26711
java.lang.RuntimeException: Unable to start activity ComponentInfo{MYPACKAGENAME/MYPACKAGENAME.home.HomeActivity}: java.lang.UnsupportedOperationException: Unsupported column: _data
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.UnsupportedOperationException: Unsupported column: _data
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:169)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:137)
at android.content.ContentProviderProxy.query(ContentProviderNative.java:420)
at android.content.ContentResolver.query(ContentResolver.java:478)
at android.content.ContentResolver.query(ContentResolver.java:422)
at MYPACKAGENAME.media.FileUtils2.getRealPathFromURI(FileUtils2.java:310)
at MYPACKAGENAME.media.FileUtils2.getPath(FileUtils2.java:412)
at MYPACKAGENAME.home.ShareIntentHandler.getPath(ShareIntentHandler.java:87)
at MYPACKAGENAME.home.ShareIntentHandler.handleSendIntent(ShareIntentHandler.java:114)
at MYPACKAGENAME.home.ShareIntentHandler.onReceiveIntent(ShareIntentHandler.java:60)
at MYPACKAGENAME.home.HomeActivity.handleShareIntent(HomeActivity.java:214)
at MYPACKAGENAME.feeds.MyLaneFragment.onCreate(MyLaneFragment.java:282)
at android.support.v4.app.Fragment.performCreate(Fragment.java:1766)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:917)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1138)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:740)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1501)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:551)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1220)
at android.app.Activity.performStart(Activity.java:5949)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2261)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360) 
at android.app.ActivityThread.access$800(ActivityThread.java:144) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:135) 
at android.app.ActivityThread.main(ActivityThread.java:5221) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) 

Could you please suggest me an idea?

@PraveenGaur1987
Copy link

This code is working fine when i select image from gallery but when i select image from download folder it give me error [java.lang.NullPointerException: Attempt to invoke virtual method 'char[] java.lang.String.toCharArray()' on a null object reference]
please help me to resolved this issue.

@Spikatrix
Copy link

return Environment.getExternalStorageDirectory() + "/" + split[1]; might throw an ArrayOutOfBoundsException. Change it to

try {
        return Environment.getExternalStorageDirectory() + "/" + split[1];
} catch (ArrayIndexOutOfBoundsException e) {
        return Environment.getExternalStorageDirectory() + "/";
}

@Spikatrix
Copy link

By the way, Could you please fill in // TODO handle non-primary volumes so that I can get the path from external storage (SD Card is what I'm after) as well?

@jma5terj
Copy link

Would you be willing to apply the Apache 2.0 license to this, like you have to several of your repositories?

@Yuumirin
Copy link

@avijitcse
Copy link

public static final String EXTERNAL_STORAGE_AUTHORITY = "com.android.externalstorage.documents";

if ("primary".equalsIgnoreCase(type)) {
    return Environment.getExternalStorageDirectory() + "/" + split[1];
} else if(EXTERNAL_STORAGE_AUTHORITY.equalsIgnoreCase(uri.getAuthority())){
    return "/storage/" + split[0] + "/" + split[1];
} else return "";

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment