1

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

HyeonSeok
  • 589
  • 1
  • 5
  • 18
  • I asked similar question like this before but it has difference between using of uri?.path and custom getPath method – HyeonSeok Oct 24 '19 at 12:20

0 Answers0