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

如何使用path_provider包将Flutter桌面端截图保存到桌面并自动发邮件

解决方案

1. 实现截图保存到桌面

你当前使用的getApplicationDocumentsDirectory获取的是应用文档目录,并非桌面路径。桌面端可以通过path_provider提供的getHomeDirectory获取用户主目录,再拼接桌面路径实现存储,具体修改如下:

步骤1:新增桌面路径获取与保存逻辑

首先确保已安装path_provider和path(用于跨平台路径拼接)依赖,编写路径和保存方法:

import 'dart:io';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';

// 获取桌面下的截图存储路径
Future<String> getDesktopFilePath() async {
  Directory? homeDir = await getHomeDirectory();
  if (homeDir == null) {
    throw Exception("无法获取用户主目录");
  }
  // 拼接桌面路径,三大桌面系统默认桌面都是主目录下的Desktop文件夹
  String desktopPath = path.join(homeDir.path, 'Desktop');
  // 文件名加时间戳避免覆盖旧截图
  String filePath = path.join(desktopPath, 'screenshot_${DateTime.now().millisecondsSinceEpoch}.png');
  return filePath;
}

// 把截图字节写入桌面文件
Future<void> saveScreenshotToDesktop(Uint8List imageBytes) async {
  String savePath = await getDesktopFilePath();
  await File(savePath).writeAsBytes(imageBytes);
}

步骤2:修改截图触发逻辑

在原有截图回调中加入保存逻辑:

ElevatedButton(
  onPressed: () {
    screenshotController
        .capture(delay: const Duration(milliseconds: 10))
        .then((capturedImage) async {
          if (capturedImage != null) {
            // 新增:保存到桌面
            await saveScreenshotToDesktop(capturedImage);
            if (context.mounted) {
              ShowCapturedWidget(context, capturedImage);
            }
          }
        })
        .catchError((onError) {
          print(onError);
        });
  },
  child: Text(_message)
),

2. 实现截图作为邮件发送

桌面端发带附件的邮件有两种常用方案:

方案1:调用系统默认邮件客户端(需用户手动确认发送)

使用url_launcher包唤起系统邮件客户端,自动填充收件人、主题、附件,实现简单无账号配置成本:

import 'package:url_launcher/url_launcher.dart';

Future<void> launchEmailWithScreenshot(Uint8List imageBytes) async {
  // 先把截图存到临时目录作为附件
  Directory tempDir = await getTemporaryDirectory();
  String tempPath = path.join(tempDir.path, 'temp_screenshot.png');
  await File(tempPath).writeAsBytes(imageBytes);

  // 构造邮件链接
  final emailUri = Uri(
    scheme: 'mailto',
    path: '收件人邮箱地址@xxx.com',
    queryParameters: {
      'subject': '组件截图',
      'body': '附件为截取的组件内容',
      'attachment': tempPath,
    },
  );

  if (await canLaunchUrl(emailUri)) {
    await launchUrl(emailUri);
  } else {
    print('无法打开邮件客户端');
  }
}

方案2:后台自动发送邮件(无需用户操作)

使用mailer包通过SMTP协议直接发送,需要提前配置发件人邮箱的SMTP授权码,适合需要全自动发送的场景:

import 'package:mailer/mailer.dart';
import 'package:mailer/smtp_server.dart';
import 'package:http_parser/http_parser.dart';

Future<void> autoSendEmail(Uint8List imageBytes) async {
  // 以QQ邮箱为例配置SMTP服务,其他邮箱替换对应参数即可
  final smtpServer = SmtpServer(
    'smtp.qq.com',
    port: 465,
    ssl: true,
    username: '你的发件人邮箱@qq.com',
    password: '你的SMTP授权码', // 需在邮箱设置页开启SMTP服务后获取
  );

  // 构造邮件内容
  final message = Message()
    ..from = const Address('你的发件人邮箱@qq.com', '发件人名称')
    ..recipients.add('收件人邮箱@xxx.com')
    ..subject = '自动发送的组件截图'
    ..text = '附件为系统自动截取的组件内容'
    ..attachments.add(
      Attachment(
        File.fromRawPath(imageBytes),
        filename: 'screenshot.png',
        contentType: MediaType('image', 'png'),
      ),
    );

  try {
    await send(message, smtpServer);
    print('邮件发送成功');
  } catch (e) {
    print('邮件发送失败:$e');
  }
}

注意事项

  • 需为桌面应用授予文件读写权限,否则无法写入桌面文件
  • 公开发布的应用不建议直接在客户端写死SMTP授权码,避免信息泄露
  • macOS端需要在Info.plist中配置邮件和文件读写相关权限

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 23:18:01