Flutter中使用camera包获取XFile后如何保存视频到系统相册
Flutter 官方camera包录制视频保存到系统相册实现方案
核心实现逻辑
你调用stopVideoRecording拿到XFile对象之后,完全不需要手动拼接系统相册路径做拷贝——因为Android 10版本之后引入分区存储机制、iOS有独立的沙盒权限规则,手动跨平台适配路径很容易出现兼容问题,直接通过适配全系统版本的媒体存储能力完成写入即可。
分步操作流程
- 权限配置
- Android端:根据系统版本申请对应存储权限,Android 12及以下申请
WRITE_EXTERNAL_STORAGE权限,Android 13及以上单独申请WRITE_MEDIA_VIDEO权限即可,无需申请全量存储权限 - iOS端:在应用的Info.plist中添加
NSPhotoLibraryAddUsageDescription字段,配置相册写入的权限说明文案
- Android端:根据系统版本申请对应存储权限,Android 12及以下申请
- 保存视频到相册的代码实现
你已经拿到的录制完成的XFile对象,本身指向缓存目录的临时视频,直接读取文件内容调用媒体写入接口即可完成相册保存,示例代码如下:
上述流程完成后,系统相册会自动扫描新写入的视频文件,不需要手动触发媒体库刷新。// 原有录制逻辑,获取临时文件 final XFile file = await _cameraController.stopVideoRecording(); // 读取临时文件的二进制数据 final Uint8List videoData = await file.readAsBytes(); // 调用媒体存储接口,将视频写入系统相册公共视频目录 await MediaStore().saveVideo( bytes: videoData, fileName: 'record_${DateTime.now().millisecondsSinceEpoch}.mp4', relativePath: '/Movies/我的应用', // 自定义相册内的子文件夹路径 );
缓存目录原文件的处理规则
- 必须删除缓存目录下的原临时文件。应用缓存目录属于应用私有存储空间,本身不受系统相册的媒体索引管控,长期留存录制的视频文件会持续占用应用的私有存储配额,导致应用安装包体积异常膨胀,严重时会触发系统的存储空间不足提醒。
- 删除操作需要等相册保存流程完全成功后再执行,具体实现代码:
// 保存成功后,读取缓存路径对应的文件对象 final cacheVideoFile = File(file.path); // 判断文件存在后执行删除 if (await cacheVideoFile.exists()) { await cacheVideoFile.delete(); }
注意:一定要在媒体保存接口返回成功之后再执行缓存删除操作,绝对不能在保存逻辑还没走完的时候就删除临时文件,否则会出现保存失败时视频永久丢失的问题。
避坑提示
- 不要尝试手动将文件拷贝到系统公共目录:Android 10以上的分区存储已经禁止应用直接向公共媒体目录的任意路径写入文件,手动拷贝大概率会出现文件写入成功但系统相册扫描不到的问题。
- 保存逻辑外层必须添加异常捕获:存储空间不足、权限被用户拒绝、系统媒体库异常都可能导致保存失败,捕获到异常时要及时给用户反馈,同时保留好原缓存文件方便重试保存。
内容的提问来源于stack exchange,提问作者user11573790
相关产品推荐
相关产品推荐

