Flutter中如何将图片保存至Pictures目录的子文件夹?
解决Flutter中使用GallerySaver保存图片到嵌套文件夹的问题
问题分析
gallery_saver的albumName参数仅支持单层相册名称,无法直接指定嵌套路径(如Camera project/TestAlbum),因此需要手动创建目标嵌套目录,再将图片复制到该目录后通知媒体库识别。
解决方案步骤
- 添加必要依赖:需要
path_provider获取公共存储目录,permission_handler处理存储权限,dart:io操作文件和目录。 - 请求存储权限:确保应用拥有访问外部存储的权限。
- 创建嵌套目标目录:在公共Pictures目录下创建
Camera project/TestAlbum层级的文件夹。 - 复制拍摄的图片到目标目录:将camera拍摄的临时图片复制到自定义目录。
- 通知媒体库扫描图片:使用GallerySaver确保图片被系统相册识别。
修改后的完整代码
import 'dart:io'; import 'package:camera/camera.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:gallery_saver/gallery_saver.dart'; import 'package:path_provider/path_provider.dart'; import 'package:permission_handler/permission_handler.dart'; CameraController? controller; XFile? image; void _takePhoto(String folder) async { String folderName = folder; // 请求存储权限,适配不同Android版本 var storageStatus = await Permission.storage.request(); var mediaStatus = await Permission.readMediaImages.request(); if (!storageStatus.isGranted || !mediaStatus.isGranted) { Fluttertoast.showToast(msg: "需要存储权限才能保存图片"); return; } try { if (controller != null && controller!.value.isInitialized) { image = await controller!.takePicture(); if (image == null) { Fluttertoast.showToast(msg: "拍摄图片失败"); return; } // 获取系统公共Pictures目录 List<Directory>? externalDirs = await getExternalStorageDirectories(type: StorageDirectory.pictures); if (externalDirs == null || externalDirs.isEmpty) { Fluttertoast.showToast(msg: "无法访问Pictures目录"); return; } Directory publicPicturesDir = externalDirs.first; // 构建嵌套目标文件夹路径 String targetFolderPath = "${publicPicturesDir.path}/Camera project/$folderName"; Directory targetDir = Directory(targetFolderPath); // 递归创建所有层级目录(不存在时创建) if (!await targetDir.exists()) { await targetDir.create(recursive: true); } // 保留原图片文件名,生成目标文件路径 String fileName = image!.path.split('/').last; String targetFilePath = "${targetDir.path}/$fileName"; // 复制拍摄的临时图片到目标目录 await File(image!.path).copy(targetFilePath); // 通知媒体库扫描图片,确保在系统相册中显示 await GallerySaver.saveImage(targetFilePath); print("图片保存路径:$targetFilePath"); Fluttertoast.showToast(msg: "图片保存成功"); } } catch (e) { print(e); Fluttertoast.showToast(msg: "图片保存失败:${e.toString()}"); } }
注意事项
- 权限适配:Android 13及以上需申请
READ_MEDIA_IMAGES权限,Android 10-12需申请WRITE_EXTERNAL_STORAGE权限;iOS需在Info.plist中添加NSPhotoLibraryAddUsageDescription权限说明。 - 目录兼容性:
getExternalStorageDirectories返回系统公共Pictures目录,适配不同Android版本的存储规则。 - 媒体扫描:调用
GallerySaver.saveImage会自动触发媒体扫描,无需额外操作即可让图片在系统相册中显示。
内容的提问来源于stack exchange,提问作者Abdullah Al Noman
相关产品推荐
相关产品推荐

