Android | Get File Path From URI | Real File Path Solution for Nougat (7.0, 7.1), Oreo, Pie | Real File Path Issue for Pie with file provider for Download location
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.technophilegeek.myapplication; | |
import android.annotation.SuppressLint; | |
import android.content.ContentUris; | |
import android.content.Context; | |
import android.database.Cursor; | |
import android.net.Uri; | |
import android.os.Build; | |
import android.os.Environment; | |
import android.provider.DocumentsContract; | |
import android.provider.MediaStore; | |
import android.support.annotation.RequiresApi; | |
import android.text.TextUtils; | |
/** | |
* Created by rjt on 28/11/18. | |
*/ | |
public class RealFilePathUtil { | |
@SuppressLint("NewApi") | |
public static String getPath(final Context context, final Uri uri) { | |
//check for KITKAT or above | |
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]; | |
} | |
} | |
// DownloadsProvider | |
else if (isDownloadsDocument(uri)) { | |
return getDownloadFilePath(context, uri); | |
} | |
// 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; | |
} | |
@RequiresApi(api = Build.VERSION_CODES.KITKAT) | |
public static String getDownloadFilePath(Context context, Uri uri){ | |
Cursor cursor = null; | |
final String[] projection = { | |
MediaStore.MediaColumns.DISPLAY_NAME | |
}; | |
try { | |
cursor = context.getContentResolver().query(uri, projection, null, null, null); | |
if (cursor != null && cursor.moveToFirst()) { | |
String fileName=cursor.getString(0); | |
String path =Environment.getExternalStorageDirectory().toString() + "/Download/" + fileName; | |
if (!TextUtils.isEmpty(path)){ | |
return path; | |
} | |
} | |
} finally { | |
cursor.close(); | |
} | |
String id = DocumentsContract.getDocumentId(uri); | |
if (id.startsWith("raw:")) { | |
return id.replaceFirst("raw:", ""); | |
} | |
Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads"), java.lang.Long.valueOf(id)); | |
return getDataColumn(context, contentUri, null, null); | |
} | |
public static boolean isExternalStorageDocument(Uri uri) { | |
return "com.android.externalstorage.documents".equals(uri.getAuthority()); | |
} | |
public static boolean isDownloadsDocument(Uri uri) { | |
return "com.android.providers.downloads.documents".equals(uri.getAuthority()); | |
} | |
public static boolean isMediaDocument(Uri uri) { | |
return "com.android.providers.media.documents".equals(uri.getAuthority()); | |
} | |
public static boolean isGooglePhotosUri(Uri uri) { | |
return "com.google.android.apps.photos.content".equals(uri.getAuthority()); | |
} | |
} |
Hi,
ReplyDeletethanks for this code, I'm converting it to C# (Xamarin).
I'm just wondering, in this line of code:
cursor.getColumnIndexOrThrow(column);
What is the column value? I don't see it set it anywhere and I don't have any example of a file that will go through this code so that I could debug it.
Thanks again.
Hi Luis,
DeleteSorry for the late response.
column is a String variable with value -> "_data"
i.e final String column = "_data";
I have updated the post as well.
Cheers
Thanks for the information :)
Deletecursor.getColumnIndexOrThrow(column);
ReplyDeleteWhat is column value??
Hi Navneet,
DeleteSorry for the late response.
column is a String variable with value -> "_data"
i.e final String column = "_data";
I have updated the post as well.
Let me know is you need any further details.
Cheers
thanks. a customer ask I should build him page eiyh his own picked image on it. that viewer can view soccer football tennis, hocky, ice ball. e.t.c. live score I build him one, he said he did not like it. please post code, I will like to learn.
ReplyDeleteHi User,
DeleteThanks for your time to write here.
I am not able to understand whats your requirement. Kindly provide some further information. You can also write me at tech.rajat.singh@gmail.com.
Super, works fine.
ReplyDeletecheers :)
DeleteGot an error
ReplyDeletejava.lang.IllegalArgumentException: column '_data' does not exist. Available columns: []
at
final int index = cursor.getColumnIndexOrThrow(column);
i am using android 9, while trying to share an image from another app (sharechat)
Hi Binu,
DeleteHope you are doing great!
On which device are you testing? Please share more details about device you are using. Also, share the steps to reproduce it.
Thanks