Android 11系统如何获取从图库选中视频的完整路径
Android 11 从图库选中视频获取完整路径解决方案
背景说明
Android 11(API 30)强制启用了分区存储机制,收紧了公共存储的访问权限,这是低版本可正常获取路径、Android 11 适配失败的核心原因。以下是两种可行的解决方案:
方案1:优先推荐 - 复制视频到应用私有目录使用
- 适用场景:所有常规非文件管理类应用,无需申请特殊权限,无应用市场审核风险
- 实现逻辑:拿到图库返回的Uri后,将视频内容拷贝到应用专属私有目录,私有目录的完整路径可直接获取
// Kotlin 示例代码:从Uri拷贝视频到私有目录,返回私有目录完整路径 fun copyVideoToPrivateDir(context: Context, videoUri: Uri): String? { val fileName = "temp_video_${System.currentTimeMillis()}.mp4" val destFile = File(context.getExternalFilesDir(Environment.DIRECTORY_MOVIES), fileName) return runCatching { context.contentResolver.openInputStream(videoUri)?.use { inputStream -> FileOutputStream(destFile).use { outputStream -> inputStream.copyTo(outputStream) } } destFile.absolutePath }.getOrNull() }
方案2:直接获取公共媒体库原始路径
- 适用场景:确实需要访问原始公共路径的场景,仅需申请普通的
READ_EXTERNAL_STORAGE权限即可,仅支持公共媒体目录下的视频 - 实现逻辑:通过ContentResolver查询MediaStore的DATA列获取原始路径
// Kotlin 示例代码:查询公共媒体库原始路径 fun getOriginalVideoPath(context: Context, videoUri: Uri): String? { var path: String? = null val projection = arrayOf(MediaStore.Video.Media.DATA) context.contentResolver.query(videoUri, projection, null, null, null)?.use { cursor -> if (cursor.moveToFirst()) { val columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA) path = cursor.getString(columnIndex) } } return path }
注意事项
- 若查询DATA列返回null,代表当前选中的视频不属于公共媒体库,无权访问其原始路径,只能采用方案1拷贝后使用
- 不要申请
MANAGE_EXTERNAL_STORAGE全量存储权限,普通应用申请该权限无法通过Google Play等应用市场的审核,仅文件管理、杀毒等特殊用途应用可申请 - 如果你仅需要播放、上传视频,完全不需要获取本地完整路径,直接使用图库返回的Uri即可完成对应操作:播放时直接传入Uri到播放器实例,上传时通过ContentResolver打开输入流读取内容即可
内容的提问来源于stack exchange,提问作者Awdhesh Kumar
相关产品推荐
相关产品推荐

