Created
March 3, 2021 09:57
-
-
Save Farhandroid/784239cef5576ae2ab0d4a981edabb46 to your computer and use it in GitHub Desktop.
This file contains 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
object RealPathUtil { | |
fun getRealPath(context: Context, fileUri: Uri): String? { | |
// SDK >= 11 && SDK < 19 | |
return if (Build.VERSION.SDK_INT < 19) { | |
getRealPathFromURIAPI11to18(context, fileUri) | |
} else { | |
getRealPathFromURIAPI19(context, fileUri) | |
}// SDK > 19 (Android 4.4) and up | |
} | |
@SuppressLint("NewApi") | |
private fun getRealPathFromURIAPI11to18(context: Context, contentUri: Uri): String? { | |
val proj = arrayOf(MediaStore.Images.Media.DATA) | |
var result: String? = null | |
val cursorLoader = CursorLoader(context, contentUri, proj, null, null, null) | |
val cursor = cursorLoader.loadInBackground() | |
if (cursor != null) { | |
val columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA) | |
cursor.moveToFirst() | |
result = cursor.getString(columnIndex) | |
cursor.close() | |
} | |
return result | |
} | |
/** | |
* Get a file path from a Uri. This will get the the path for Storage Access | |
* Framework Documents, as well as the _data field for the MediaStore and | |
* other file-based ContentProviders. | |
* | |
* @param context The context. | |
* @param uri The Uri to query. | |
* @author Niks | |
*/ | |
@SuppressLint("NewApi") | |
private fun getRealPathFromURIAPI19(context: Context, uri: Uri): String? { | |
val isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT | |
// DocumentProvider | |
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { | |
// ExternalStorageProvider | |
if (isExternalStorageDocument(uri)) { | |
val docId = DocumentsContract.getDocumentId(uri) | |
val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() | |
val type = split[0] | |
if ("primary".equals(type, ignoreCase = true)) { | |
return Environment.getExternalStorageDirectory().toString() + "/" + split[1] | |
} | |
} else if (isDownloadsDocument(uri)) { | |
var cursor: Cursor? = null | |
try { | |
cursor = context.contentResolver.query( | |
uri, | |
arrayOf(MediaStore.MediaColumns.DISPLAY_NAME), | |
null, | |
null, | |
null | |
) | |
cursor!!.moveToNext() | |
val fileName = cursor.getString(0) | |
val path = Environment.getExternalStorageDirectory() | |
.toString() + "/Download/" + fileName | |
if (!TextUtils.isEmpty(path)) { | |
return path | |
} | |
} finally { | |
cursor?.close() | |
} | |
val id = DocumentsContract.getDocumentId(uri) | |
if (id.startsWith("raw:")) { | |
return id.replaceFirst("raw:".toRegex(), "") | |
} | |
val contentUri = ContentUris.withAppendedId( | |
Uri.parse("content://downloads"), | |
java.lang.Long.valueOf(id) | |
) | |
return getDataColumn(context, contentUri, null, null) | |
} else if (isMediaDocument(uri)) { | |
val docId = DocumentsContract.getDocumentId(uri) | |
val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() | |
val type = split[0] | |
var contentUri: Uri? = null | |
when (type) { | |
"image" -> contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI | |
"video" -> contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI | |
"audio" -> contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI | |
} | |
val selection = "_id=?" | |
val selectionArgs = arrayOf(split[1]) | |
return getDataColumn(context, contentUri, selection, selectionArgs) | |
}// MediaProvider | |
// DownloadsProvider | |
} else if ("content".equals(uri.scheme!!, ignoreCase = true)) { | |
// Return the remote address | |
return if (isGooglePhotosUri(uri)) uri.lastPathSegment else getDataColumn( | |
context, | |
uri, | |
null, | |
null | |
) | |
} else if ("file".equals(uri.scheme!!, ignoreCase = true)) { | |
return uri.path | |
}// File | |
// MediaStore (and general) | |
return null | |
} | |
/** | |
* Get the value of the data column for this Uri. This is useful for | |
* MediaStore Uris, and other file-based ContentProviders. | |
* | |
* @param context The context. | |
* @param uri The Uri to query. | |
* @param selection (Optional) Filter used in the query. | |
* @param selectionArgs (Optional) Selection arguments used in the query. | |
* @return The value of the _data column, which is typically a file path. | |
* @author Niks | |
*/ | |
private fun getDataColumn( | |
context: Context, uri: Uri?, selection: String?, | |
selectionArgs: Array<String>? | |
): String? { | |
var cursor: Cursor? = null | |
val column = "_data" | |
val projection = arrayOf(column) | |
try { | |
cursor = | |
context.contentResolver.query(uri!!, projection, selection, selectionArgs, null) | |
if (cursor != null && cursor.moveToFirst()) { | |
val index = cursor.getColumnIndexOrThrow(column) | |
return cursor.getString(index) | |
} | |
} finally { | |
cursor?.close() | |
} | |
return null | |
} | |
/** | |
* @param uri The Uri to check. | |
* @return Whether the Uri authority is ExternalStorageProvider. | |
*/ | |
private fun isExternalStorageDocument(uri: Uri): Boolean { | |
return "com.android.externalstorage.documents" == uri.authority | |
} | |
/** | |
* @param uri The Uri to check. | |
* @return Whether the Uri authority is DownloadsProvider. | |
*/ | |
private fun isDownloadsDocument(uri: Uri): Boolean { | |
return "com.android.providers.downloads.documents" == uri.authority | |
} | |
/** | |
* @param uri The Uri to check. | |
* @return Whether the Uri authority is MediaProvider. | |
*/ | |
private fun isMediaDocument(uri: Uri): Boolean { | |
return "com.android.providers.media.documents" == uri.authority | |
} | |
/** | |
* @param uri The Uri to check. | |
* @return Whether the Uri authority is Google Photos. | |
*/ | |
private fun isGooglePhotosUri(uri: Uri): Boolean { | |
return "com.google.android.apps.photos.content" == uri.authority | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment