使用Android VideoView播放图库视频问题求助
Hey there! Let's figure out why your VideoView isn't playing that video file from the gallery. The issue could stem from how you're creating the URI, missing permissions, or even overlooked setup steps for VideoView itself. Here’s a breakdown of what to check and fix:
1. URI Construction is Likely the Culprit (Especially for Android 10+)
Directly using a file path to create a file:// URI won’t work reliably on Android 10 (API 29) and above due to Scoped Storage restrictions. Instead, you need to use a Content URI which is the standard way to access media files in modern Android versions.
If you got the video from the gallery picker:
When you use an intent like ACTION_PICK or ACTION_GET_CONTENT to select the video, you should directly use the URI returned in the intent result, not manually construct one from the file path. For example:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == PICK_VIDEO_REQUEST && resultCode == RESULT_OK) { val videoUri = data?.getData() // This is the correct Content URI to use mVideoView.setVideoURI(videoUri) mVideoView.start() // Don't forget this! } }
If you're using a known file path (e.g., from your own storage):
For API 29+, you need to fetch the corresponding Content URI via MediaStore:
val filePath = "/storage/emulated/0/DCIM/Camera/VID_20200711_165727.mp4" val contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI // Query MediaStore to get the video's ID val projection = arrayOf(MediaStore.Video.Media._ID) val selection = "${MediaStore.Video.Media.DATA} = ?" val selectionArgs = arrayOf(filePath) contentResolver.query(contentUri, projection, selection, selectionArgs, null)?.use { cursor -> if (cursor.moveToFirst()) { val videoId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID)) val videoUri = ContentUris.withAppendedId(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, videoId) mVideoView.setVideoURI(videoUri) mVideoView.start() } }
2. Don’t Forget Permissions
Your app needs permission to access the video file:
- For API 23 to 32: Request
READ_EXTERNAL_STORAGE(dynamic permission is required, not just manifest declaration). - For API 33+: Request
READ_MEDIA_VIDEOinstead, which is more granular.
Without these permissions, VideoView can’t access the file, so it’ll appear to do nothing.
3. Complete VideoView Setup
Just calling setVideoURI() isn’t enough—you need to:
- Call
mVideoView.start()to begin playback. - Add error handling to debug issues like unsupported formats or corrupted files:
mVideoView.setOnErrorListener { _, errorCode, extraCode -> Log.e("VideoPlayback", "Error: Code $errorCode, Extra $extraCode") // Show an error message to the user here true }
- Optional but helpful: Attach a
MediaControllerto let users control playback:
mVideoView.setMediaController(MediaController(this))
4. Consider Format Compatibility or Switch to ExoPlayer
VideoView supports common formats (MP4, 3GP) but has limited codec support. If the video uses a less common codec, you might need to use ExoPlayer instead. ExoPlayer is more flexible, supports more formats, and is recommended by Google for media playback in modern apps.
Start with checking the URI construction and making sure you call start()—those are the most common fixes for this issue. If you still run into problems, use the error listener to get more details about what’s going wrong.
内容的提问来源于stack exchange,提问作者androidcodehunter

