安卓双视频同屏应用开发:MediaMetadataRetriever FileNotFoundException问题
解决MediaMetadataRetriever FileNotFoundException的方案
你遇到这个问题,主要是因为跨Activity传递媒体URI时的权限问题或者数据源设置方式错误,结合你的开发场景,我给你整理了具体的解决步骤:
1. 确保跨Activity传递URI时携带访问权限
从系统媒体选择器拿到的content://类型URI,只有当前发起选择的Activity拥有临时访问权限。如果你直接把URI传给第二个Activity,它默认没有权限访问这个URI,就会触发FileNotFoundException。
解决方法:启动第二个Activity时,给Intent添加FLAG_GRANT_READ_URI_PERMISSION标记,把临时权限传递过去。完整的onActivityResult代码可以这么写:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 0 && resultCode == RESULT_OK && data != null) { Uri selectedVideoUri = data.getData(); // 启动第二个Activity Intent secondActivityIntent = new Intent(this, YourSecondActivity.class); secondActivityIntent.setData(selectedVideoUri); // 关键:添加权限标记,让第二个Activity能访问该URI secondActivityIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); startActivity(secondActivityIntent); } }
2. 正确初始化MediaMetadataRetriever
很多人会犯的错误是把content:// URI当成普通文件路径传入setDataSource(String path)方法,这肯定会报错,因为这不是真实的文件路径。你需要使用支持ContentResolver的重载方法来设置数据源:
在第二个Activity中:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); Uri videoUri = getIntent().getData(); if (videoUri == null) { // 处理URI为空的情况 return; } MediaMetadataRetriever retriever = new MediaMetadataRetriever(); try { // 用ContentResolver和URI来设置数据源,这是正确的姿势 retriever.setDataSource(this, videoUri); // 在这里执行你的操作,比如获取视频帧、宽高等 // Bitmap frame = retriever.getFrameAtTime(); } catch (IOException e) { e.printStackTrace(); // 这里可以添加错误提示逻辑 } finally { // 记得释放资源 retriever.release(); } }
额外提醒:避免转换content URI为文件路径
在Android 10及以上的Scoped Storage机制下,直接把content:// URI转换成真实文件路径的做法不仅复杂,还可能因为权限限制失败。直接使用ContentResolver配合URI访问媒体资源是官方推荐的合规方式。
内容的提问来源于stack exchange,提问作者Josemafuen
相关产品推荐
相关产品推荐

