Last active
October 20, 2023 16:40
-
-
Save ImaginativeShohag/4e53572141c017369941bbbaac538576 to your computer and use it in GitHub Desktop.
Real Path Utility class for Android. Tested till API 33. Java Version of this: https://gist.github.com/ImaginativeShohag/476a5ba87824f6e036f6bce10e229079
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
import android.content.ContentUris | |
import android.content.Context | |
import android.database.Cursor | |
import android.net.Uri | |
import android.os.Environment | |
import android.provider.DocumentsContract | |
import android.provider.MediaStore | |
/** | |
* Real Path Utility class for Android. | |
* | |
* Updated by @ImaginativeShohag | |
* | |
* Source: https://gist.github.com/ImaginativeShohag/4e53572141c017369941bbbaac538576 | |
*/ | |
object RealPathUtil { | |
fun getRealPath(context: Context, uri: Uri): String? { | |
// ---------------------------------------------------------------- | |
// DocumentProvider | |
// ---------------------------------------------------------------- | |
if (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] | |
// ---------------------------------------------------------------- | |
// This is for checking Main Memory | |
// ---------------------------------------------------------------- | |
return if ("primary".equals(type, ignoreCase = true)) { | |
if (split.size > 1) { | |
Environment.getExternalStorageDirectory().toString() + "/" + split[1] | |
} else { | |
Environment.getExternalStorageDirectory().toString() + "/" | |
} | |
} else { | |
// ---------------------------------------------------------------- | |
// This is for checking SD Card | |
// ---------------------------------------------------------------- | |
"storage" + "/" + docId.replace(":", "/") | |
} | |
} else if (isDownloadsDocument(uri)) { | |
// ---------------------------------------------------------------- | |
// DownloadsProvider | |
// ---------------------------------------------------------------- | |
val fileName = getFilePath(context, uri) | |
if (fileName != null) { | |
return Environment.getExternalStorageDirectory() | |
.toString() + "/Download/" + fileName | |
} | |
val id = DocumentsContract.getDocumentId(uri) | |
val contentUri = ContentUris.withAppendedId( | |
Uri.parse("content://downloads/public_downloads"), | |
java.lang.Long.valueOf(id) | |
) | |
return getDataColumn(context, contentUri, null, null) | |
} else if (isMediaDocument(uri)) { | |
// ---------------------------------------------------------------- | |
// MediaProvider | |
// ---------------------------------------------------------------- | |
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) | |
} | |
} else if ("content".equals(uri.scheme, ignoreCase = true)) { | |
// ---------------------------------------------------------------- | |
// MediaStore (and general) | |
// ---------------------------------------------------------------- | |
// Return the remote address | |
return if (isGooglePhotosUri(uri)) { | |
uri.lastPathSegment | |
} else { | |
getDataColumn( | |
context, | |
uri, | |
null, | |
null | |
) | |
} | |
} else if ("file".equals(uri.scheme, ignoreCase = true)) { | |
// ---------------------------------------------------------------- | |
// File | |
// ---------------------------------------------------------------- | |
return uri.path | |
} | |
return null | |
} | |
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 | |
} | |
private fun getFilePath(context: Context, uri: Uri): String? { | |
var cursor: Cursor? = null | |
val projection = arrayOf(MediaStore.MediaColumns.DISPLAY_NAME) | |
try { | |
cursor = context.contentResolver.query(uri, projection, null, null, null) | |
if (cursor != null && cursor.moveToFirst()) { | |
val index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DISPLAY_NAME) | |
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