如何使用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
相关产品推荐
相关产品推荐

