Last active
October 4, 2021 05:17
-
-
Save WSAyan/e684c06b0a4cbfa2c34df14f61f6d05e to your computer and use it in GitHub Desktop.
Android 11(api level 30) get real file path from uri
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
<?xml version="1.0" encoding="utf-8"?> | |
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:tools="http://schemas.android.com/tools" | |
package="com.example.example"> | |
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />> | |
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> | |
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> | |
<application | |
android:name=".MyApplication" | |
android:requestLegacyExternalStorage="true" > | |
</application> | |
</manifest> |
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.wsayan.util | |
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 androidx.loader.content.CursorLoader | |
import java.io.File | |
object FilePathUtils { | |
fun getRealPath(context: Context, fileUri: Uri): String? { | |
return when { | |
Build.VERSION.SDK_INT < 11 -> getRealPathFromURI_BelowAPI11(context, fileUri) | |
Build.VERSION.SDK_INT < 19 -> getRealPathFromURI_API11to18(context, fileUri) | |
else -> getRealPathFromURI_API19(context, fileUri) | |
} | |
} | |
@SuppressLint("NewApi") | |
fun getRealPathFromURI_API11to18(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 | |
} | |
fun getRealPathFromURI_BelowAPI11(context: Context, contentUri: Uri): String { | |
val proj = arrayOf(MediaStore.Images.Media.DATA) | |
val cursor = context.contentResolver.query(contentUri, proj, null, null, null) | |
var columnIndex = 0 | |
var result = "" | |
if (cursor != null) { | |
columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA) | |
cursor.moveToFirst() | |
result = cursor.getString(columnIndex) | |
cursor.close() | |
return result | |
} | |
return result | |
} | |
@SuppressLint("NewApi") | |
fun getRealPathFromURI_API19(context: Context, uri: Uri): String? { | |
val isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT | |
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { | |
// ExternalStorageProvider | |
when { | |
isExternalStorageDocument(uri) -> { | |
val docId = DocumentsContract.getDocumentId(uri) | |
val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() | |
val type = split[0] | |
return if ("primary".equals(type, ignoreCase = true)) { | |
if (split.size > 1) { | |
Environment.getExternalStorageDirectory().toString() + "/" + split[1] | |
} else { | |
Environment.getExternalStorageDirectory().toString() + "/" | |
} | |
} else { | |
"storage" + "/" + docId.replace(":", "/") | |
} | |
} | |
isDownloadsDocument(uri) -> { | |
val fileName = getFilePath(context, uri) | |
if (fileName != null) { | |
return Environment.getExternalStorageDirectory().toString() + "/Download/" + fileName | |
} | |
var id = DocumentsContract.getDocumentId(uri) | |
if (id.startsWith("raw:")) { | |
id = id.replaceFirst("raw:".toRegex(), "") | |
val file = File(id) | |
if (file.exists()) | |
return id | |
} | |
val contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), java.lang.Long.valueOf(id)) | |
return getDataColumn(context, contentUri, null, null) | |
} | |
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 | |
else -> contentUri = MediaStore.Files.getContentUri("external") | |
} | |
val selection = "_id=?" | |
val selectionArgs = arrayOf(split[1]) | |
return getDataColumn(context, contentUri, selection, selectionArgs) | |
} | |
} | |
} else if ("content".equals(uri.scheme!!, ignoreCase = true)) { | |
return if (isGooglePhotosUri(uri)) uri.lastPathSegment else getDataColumn(context, uri, null, null) | |
} else if ("file".equals(uri.scheme!!, ignoreCase = true)) { | |
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 | |
} | |
private fun isExternalStorageDocument(uri: Uri): Boolean { | |
return "com.android.externalstorage.documents" == uri.authority | |
} | |
private fun isDownloadsDocument(uri: Uri): Boolean { | |
return "com.android.providers.downloads.documents" == uri.authority | |
} | |
private fun isMediaDocument(uri: Uri): Boolean { | |
return "com.android.providers.media.documents" == uri.authority | |
} | |
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
All credit goes to @ishtiaque-pial . I just copied from him shamelessly.