You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Media URI转换为Document URI?现有实现返回null

问题描述

我的文件选择器返回的URI为content://media/picker/0/com.android.providers.media.photopicker/media/1000192721,但我需要将其转换为content://com.android.providers.media.documents/document/video%3A1000192721。尝试了以下Kotlin代码,但返回值为null,请问该如何解决?

尝试的代码

fun getDocumentUriFromMediaUri(context: Context, mediaUri: Uri): Uri? {
    val projection = arrayOf(MediaStore.Video.Media._ID)
    val selection = "${MediaStore.Video.Media.DATA} = ?"
    val selectionArgs = arrayOf(mediaUri.path)

    val cursor = context.contentResolver.query(
        MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
        projection,
        selection,
        selectionArgs,
        null
    )

    if (cursor != null && cursor.moveToFirst()) {
        val idColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID)
        val id = cursor.getLong(idColumn)
        cursor.close()
        return ContentUris.withAppendedId(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, id)
    }

    return null
}
问题原因分析
  1. 查询条件不匹配:原代码用MediaStore.Video.Media.DATA(文件实际路径)匹配mediaUri.path,但后者是Picker URI的路径片段(/0/com.android.providers.media.photopicker/media/1000192721),并非真实文件路径,导致查询无结果。
  2. 目标URI类型错误:原代码返回的是MediaStore标准内容URI,而需求是documents类型的URI,格式规则为content://com.android.providers.media.documents/document/<类型>:<ID>。
解决方案

方法一:直接提取Picker URI中的媒体ID(简洁高效)

PhotoPicker返回的URI路径最后一段就是媒体ID,直接提取后拼接目标URI即可:

fun convertPickerUriToDocumentUri(pickerUri: Uri): Uri? {
    val pathSegments = pickerUri.pathSegments
    // 检查URI结构是否符合PhotoPicker返回格式
    if (pathSegments.size >= 2 && pathSegments[pathSegments.size - 2] == "media") {
        val mediaId = pathSegments.last()
        return Uri.parse("content://com.android.providers.media.documents/document/video:$mediaId")
    }
    return null
}

方法二:通过ContentResolver查询(兼容性更强)

若Picker URI格式存在版本差异,或需要自动识别媒体类型(视频/图片),可通过查询Picker URI本身获取信息:

fun getDocumentUriFromPickerUri(context: Context, pickerUri: Uri): Uri? {
    val projection = arrayOf(
        MediaStore.MediaColumns._ID,
        MediaStore.MediaColumns.MIME_TYPE
    )

    context.contentResolver.query(
        pickerUri,
        projection,
        null,
        null,
        null
    )?.use { cursor ->
        if (cursor.moveToFirst()) {
            val mediaId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns._ID))
            val mimeType = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.MIME_TYPE))
            
            val documentType = when {
                mimeType.startsWith("video/") -> "video"
                mimeType.startsWith("image/") -> "image"
                else -> return null // 不处理其他类型
            }
            
            return Uri.parse("content://com.android.providers.media.documents/document/${documentType}:${mediaId}")
        }
    }
    return null
}
参考资料
  • Android:将文件Uri转换为内容Uri
  • 将Uri转换为文件Uri(file:////)
  • Android:将文件Uri转换为内容Uri

内容的提问来源于stack exchange,提问作者Rahul R

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 04:45:32