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

Android 11/Android Q系统如何保存视频文件(以保存WhatsApp状态为例)

视频保存代码问题修复方案

现有代码的核心错误如下:

  • 输出流绑定对象错误:调用openOutputStream时传入了源视频的vidUri,应该传入你新插入到MediaStore生成的目标视频Uri
  • 存在冗余错误代码:多写了Uri videoFileUri = contentResolver.insert(vidUri, contentValues)这行无效逻辑,会引发异常
  • 未写入实际视频数据:仅创建了空的视频文件占位,没有把源Uri的视频内容拷贝到新文件的输出流中,相当于保存了空文件,自然无法播放

修复后的完整代码

public void saveVideo(String name, Uri vidUri) {
    OutputStream fileOutputStream = null;
    InputStream inputStream = null;
    Uri videoUri;
    try {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            ContentResolver contentResolver = context.getApplicationContext().getContentResolver();
            ContentValues contentValues = new ContentValues();
            contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, name);
            contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "video/mp4");
            contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_MOVIES + "/V Troid/WhatsApp");
            // 插入获取目标视频的Uri
            videoUri = contentResolver.insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, contentValues);
            if (videoUri == null) {
                throw new IOException("无法创建目标视频文件");
            }
            // 分别打开源视频输入流、目标视频输出流
            inputStream = contentResolver.openInputStream(vidUri);
            fileOutputStream = contentResolver.openOutputStream(videoUri);
            if (inputStream == null || fileOutputStream == null) {
                throw new IOException("无法打开文件读写流");
            }
            // 拷贝视频数据
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                inputStream.transferTo(fileOutputStream);
            } else {
                byte[] buffer = new byte[8192];
                int len;
                while ((len = inputStream.read(buffer)) != -1) {
                    fileOutputStream.write(buffer, 0, len);
                }
            }
            // 强制刷新缓冲数据写入文件
            fileOutputStream.flush();
            Toast.makeText(context.getApplicationContext(), "视频保存成功", Toast.LENGTH_SHORT).show();
        }
    } catch (Exception e) {
        Toast.makeText(context.getApplicationContext(), "保存失败:\n" + e.getMessage(), Toast.LENGTH_SHORT).show();
    } finally {
        // 手动关闭流避免资源泄漏
        try {
            if (inputStream != null) inputStream.close();
            if (fileOutputStream != null) fileOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

适配Android11说明:当前逻辑完全符合分区存储要求,写入公共媒体目录不需要申请MANAGE_EXTERNAL_STORAGE权限,仅需要确保你对传入的源vidUri有读取权限即可:Android13+需申请READ_MEDIA_VIDEO权限,Android12及更低版本需申请READ_EXTERNAL_STORAGE权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 22:06:00