You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nexus设备默认谷歌相机MediaStore.ACTION_VIDEO_CAPTURE视频访问异常求助

我之前在Nexus设备上用谷歌默认相机做视频拍摄功能时,也踩过这个一模一样的坑!给你分享几个亲测有效的解决办法:

解决Nexus设备谷歌相机拍摄视频后无法访问的问题

问题根源

谷歌相机在处理MediaStore.ACTION_VIDEO_CAPTURE时,返回的Uri权限逻辑和其他第三方相机应用不一样,尤其是在Android 6.0+的动态权限机制下,直接用返回的Uri访问视频会触发权限拒绝的问题。


方案1:用FileProvider指定固定存储路径(最稳妥)

这种方法能彻底绕开相机应用的路径权限问题,直接让视频存在你可控的目录里:

  1. 在AndroidManifest.xml注册FileProvider
<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>
  1. 创建路径配置文件
    在res/xml目录下新建file_paths.xml,指定视频存储的位置:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 存在应用私有Movies目录,无需外部存储权限 -->
    <external-files-path name="captured_videos" path="Movies/" />
</paths>
  1. 修改拍摄视频的Intent代码
// 创建存储视频的临时文件
File videoStorageDir = getExternalFilesDir(Environment.DIRECTORY_MOVIES);
File videoFile = new File(videoStorageDir, "new_capture_" + System.currentTimeMillis() + ".mp4");

// 生成FileProvider的Uri
Uri outputUri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", videoFile);

// 构建拍摄Intent
Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
// 指定输出路径
takeVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputUri);
// 授予相机应用读写该Uri的临时权限
takeVideoIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
takeVideoIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

// 检查相机应用是否存在
if (takeVideoIntent.resolveActivity(getPackageManager()) != null) {
    startActivityForResult(takeVideoIntent, Globals.REQUEST_CODE_TAKE_VIDEO);
}

拍摄完成后,视频会直接存在你指定的应用私有目录,你可以直接读取这个文件,完全不用处理返回Uri的权限问题。


方案2:处理返回Uri的持久化权限(适合不想指定路径的场景)

如果必须用相机默认的存储路径,那得在onActivityResult里申请持久化权限:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == Globals.REQUEST_CODE_TAKE_VIDEO && resultCode == RESULT_OK) {
        Uri videoUri = data.getData();
        if (videoUri != null) {
            try {
                // 申请持久化的读取权限
                getContentResolver().takePersistableUriPermission(
                    videoUri,
                    Intent.FLAG_GRANT_READ_URI_PERMISSION
                );
                // 之后就可以用ContentResolver正常访问这个Uri了
                InputStream is = getContentResolver().openInputStream(videoUri);
                // 处理视频流...
            } catch (SecurityException | FileNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
}

⚠️ 注意:这个方法在部分版本的谷歌相机上可能不稳定,有些情况下相机不会返回支持持久化权限的Uri。


额外提醒

  • Android 10及以上版本,访问应用私有目录不需要WRITE_EXTERNAL_STORAGE权限,用方案1的话可以省去权限申请步骤;
  • 测试时尽量覆盖不同Android版本的Nexus设备(比如Nexus 5X、6P),不同版本的谷歌相机行为可能略有差异。

内容的提问来源于stack exchange,提问作者Mike Walker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:03:38