Android Studio中通过Intent传递录制视频至其他Activity播放失败求助
解决Intent传递视频Uri至VideoView Activity无法播放的问题
问题根源分析
你遇到的"Can't play this video"问题主要由以下几个原因导致:
- Android 7.0+的FileUri限制:
Uri.fromFile()生成的file://类型Uri在targetSdkVersion>=24时会触发FileUriExposedException,系统会阻止这类Uri跨组件传递,导致VideoView无法访问文件。 - 文件路径或存在性问题:
getAndroidMoviesFolder()的命名和示例路径(DCIM目录)不一致,可能导致实际保存的文件位置与传递的路径不匹配,文件不存在自然无法播放。 - 权限缺失:未获取读取外部存储/媒体的权限,或者未给目标Activity授予临时访问Uri的权限。
分步解决方案
1. 配置FileProvider以生成安全的Content Uri
Android推荐使用FileProvider来生成content://类型的Uri,避免FileUri暴露问题:
- 在
AndroidManifest.xml中注册FileProvider:
<application> <!-- 其他配置 --> <provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> </application>
- 在
res/xml目录下创建file_paths.xml,配置要共享的目录(根据你的视频实际存储路径调整,示例为DCIM目录):
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path name="dcim_files" path="DCIM/" /> </paths>
2. 修改RecordActivity的Uri生成与传递逻辑
替换Uri.fromFile()为FileProvider生成Uri,并授予临时访问权限:
File mediaFile = new File(getVideoFilePath()); // 先验证文件是否存在 if (!mediaFile.exists()) { Log.e("RecordError", "视频文件不存在,请检查保存路径"); return; } // 使用FileProvider生成Content Uri Uri uri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", mediaFile); Intent intent = new Intent(this, VideoEditorActivity.class); intent.putExtra("uri", uri.toString()); // 授予目标Activity临时读取权限 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); startActivity(intent);
3. 优化VideoViewActivity的播放逻辑并添加错误监听
保留原有Uri解析逻辑,添加错误监听以排查具体播放错误:
Bundle bundle = getIntent().getExtras(); if (bundle != null) { Uri uri = Uri.parse(bundle.getString("uri")); Log.e("video path = ", String.valueOf(uri)); binding.videoView.setVideoURI(uri); // 添加错误监听,获取具体错误码 binding.videoView.setOnErrorListener((mp, what, extra) -> { Log.e("VideoPlayError", "错误码:" + what + ",额外信息:" + extra); return false; }); binding.videoView.start(); }
4. 验证权限配置
- Android 6.0-12:动态申请
READ_EXTERNAL_STORAGE权限; - Android 13+:动态申请
READ_MEDIA_VIDEO权限;
确保应用已获取对应权限后再进行视频播放操作。
额外检查点
确认getAndroidMoviesFolder()返回的目录与实际视频保存目录一致,比如示例路径是DCIM,但函数名是"Movies",可能存在逻辑错误,建议打印该函数的返回值验证:
Log.e("FolderPath", getAndroidMoviesFolder().getAbsolutePath());
内容的提问来源于stack exchange,提问作者Rakesh Saini
相关产品推荐
相关产品推荐

