I have a problem with get file path from uri
To get a file path in folder at local storage works well. but it does not work with download folder
Well I can simply use uri?.path but sometimes it could be media id like ~~~:4342 and this is not useful to create file object
this is code is in onActivityResult Method
val uri = data?.data
val filePath = FileManager.getPath(applicationContext, uri)
val validatedPath = filePath?.replace("\n", "")
val file = File(validatedPath!!)
Log.i("File Path", file.path)
if (file.exists()) {
viewModel.hasFile = true
val requestFile =
RequestBody.create(MediaType.parse("multipart/form-data"), file)
val multipartData =
MultipartBody.Part.createFormData("file", file.name, requestFile)
viewModel.file = multipartData
}
}
And this is getPath Mothod (from here the first answer 1)
I converted java code to kotlin code by using android studio code converter
fun getPath(context: Context, uri: Uri): String? {
val isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
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)) {
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)) {
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
} else if ("content".equals(uri.scheme!!, ignoreCase = true)) {
return getDataColumn(context, uri, null, null)
} else if ("file".equals(uri.scheme!!, ignoreCase = true)) {
return uri.path
}
return null
}
if i choose the file from downloads folder, isDownloadsDocument(uri) returns true
private fun isDownloadsDocument(uri: Uri): Boolean {
return "com.android.providers.downloads.documents" == uri.authority
}
the uri -> content://com.android.providers.downloads.documents/document/5472
the contentUri -> content://downloads/public_downloads/5453
And code below work then return getDataColumn(context, contentUri, null, 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 columnIndex = cursor.getColumnIndexOrThrow(column)
return cursor.getString(columnIndex)
}
} finally {
cursor?.close()
}
return null
}
Error occurs at here
cursor = context.contentResolver.query(uri!!, projection, selection, selectionArgs, null)
And this is error message -> Caused by: java.lang.IllegalArgumentException: Unknown URI: content://downloads/public_downloads/5472
In short, method getPath does not works in every time
My Android API number is 24 and I use galaxy s7 for the test device
thank you for your help