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

Flutter中如何将图片保存至Pictures目录的子文件夹?

解决Flutter中使用GallerySaver保存图片到嵌套文件夹的问题

问题分析

gallery_saver的albumName参数仅支持单层相册名称,无法直接指定嵌套路径(如Camera project/TestAlbum),因此需要手动创建目标嵌套目录,再将图片复制到该目录后通知媒体库识别。

解决方案步骤

  1. 添加必要依赖:需要path_provider获取公共存储目录,permission_handler处理存储权限,dart:io操作文件和目录。
  2. 请求存储权限:确保应用拥有访问外部存储的权限。
  3. 创建嵌套目标目录:在公共Pictures目录下创建Camera project/TestAlbum层级的文件夹。
  4. 复制拍摄的图片到目标目录:将camera拍摄的临时图片复制到自定义目录。
  5. 通知媒体库扫描图片:使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 22:54:35