如何从uri获取文件路径

时间:2019-10-24 11:48:57

标签: android kotlin android-intent

我从uri获取文件路径有问题

要在本地存储的文件夹中获取文件路径,效果很好。但不适用于下载文件夹

好吧,我可以简单地使用uri?.path,但是有时它可能是~~~:4342之类的媒体ID,这对创建文件对象没有帮助

这是代码在onActivityResult方法中

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
    }
}

这是getPath Mothod(这里是第一个答案1

我通过使用android studio代码转换器将java代码转换为kotlin代码

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
}

如果我从下载文件夹中选择文件,则isDownloadsDocument(uri)返回true

private fun isDownloadsDocument(uri: Uri): Boolean {
    return "com.android.providers.downloads.documents" == uri.authority
}    

uri-> content://com.android.providers.downloads.documents/document/5472

contentUri-> content:// downloads / public_downloads / 5453

下面的代码工作,然后返回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
}

此处发生错误

cursor = context.contentResolver.query(uri!!, projection, selection, selectionArgs, null)

这是错误消息->原因:java.lang.IllegalArgumentException:未知URI:content:// downloads / public_downloads / 5472

简而言之,方法getPath并非每次都有效

我的Android API编号为24,并且我将galaxy s7用于测试设备

感谢您的帮助

0 个答案:

没有答案