-
-
Save MeNiks/947b471b762f3b26178ef165a7f5558a to your computer and use it in GitHub Desktop.
| import android.annotation.SuppressLint | |
| import android.content.ContentUris | |
| import android.content.Context | |
| import android.content.CursorLoader | |
| 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.text.TextUtils | |
| 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") | |
| 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") | |
| 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 | |
| } | |
| } |
| // Extension on intent | |
| fun Intent?.getFilePath(context: Context): String { | |
| return this?.data?.let { data -> RealPathUtil.getRealPath(context, data) ?: "" } ?: "" | |
| } | |
| fun Uri?.getFilePath(context: Context): String { | |
| return this?.let { uri -> RealPathUtil.getRealPath(context, uri) ?: "" } ?: "" | |
| } | |
| fun ClipData.Item?.getFilePath(context: Context): String { | |
| return this?.uri?.getFilePath(context) ?: "" | |
| } | |
| // Usage | |
| val selectedPath = intent.getFilePath(context) |
It works (I have tested this till 8.1), Thanks
Good job! Thanks!!!
this doesnt work when opening a file from google chrome downloads on api > 19 with a uri of something like this content://com.android.chrome.FileProvider/downloads/<some_file_name>
Works for me too. Thanks!
What's context? How do I get it?
thanx works for me in android 8 i love you :3
What's context? How do I get it?
you pass the application context
This is not working if we are selecting a file from the download folder and if that file is downloaded from google drive. I am getting the path from the below code if the file does not exist.
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
}
I created a library to facilitate the handling of Intent (Uri) received. It can be found here.
thanks for the code,
if i want to retrieve an audio file and use it on a media player how can i pass the audio to mediaPlayer.create?
Below is the code i have where i create and initiate the player
`
private fun controlSound(id: Uri){
fab_play.setOnClickListener{
if (mp == null){
mp = MediaPlayer.create(this, id)
Log.d("MediaPlayer", "ID: ${mp!!.audioSessionId}")
initialiseSeekBar()
}
mp?.start()
Log.d("MediaPlayer", "Duration: ${mp!!.duration/1000} seconds")
}`
package com.vakilsearch.libra.Common;
import android.annotation.SuppressLint;
import android.content.ContentUris;
import android.content.Context;
import android.content.CursorLoader;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
public class RealPathUtil {
}