如何将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 }
问题原因分析
- 查询条件不匹配:原代码用
MediaStore.Video.Media.DATA(文件实际路径)匹配mediaUri.path,但后者是Picker URI的路径片段(/0/com.android.providers.media.photopicker/media/1000192721),并非真实文件路径,导致查询无结果。 - 目标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
相关产品推荐
相关产品推荐

