使用 url_launcher uri 发送电子邮件

flutter send email with url_launcher uri

我正在使用 url_launcher 在我的应用程序中使用系统电子邮件发送电子邮件。我正在使用下面的代码,这个人做得很好。

void launchEmailSubmission() async {
    final Uri params = Uri(
      scheme: 'mailto',
      path: 'myOwnEmailAddress@gmail.com',
    );
    String url = params.toString();
    if (await canLaunch(url)) {
      await launch(url);
    } else {
      print('Could not launch $url');
    }
  }

但现在我想给它 'default' 邮件正文框中的主题和提示文本(如果提示文本不可能,则使用普通文本)。

有什么办法吗?

尝试在 Uri 中使用 queryParameters。您可以通过下面显示的方式实现此目的:

void launchEmailSubmission() async {
    final Uri params = Uri(
      scheme: 'mailto',
      path: 'myOwnEmailAddress@gmail.com',
      queryParameters: {
        'subject': 'Default Subject',
        'body': 'Default body'
      }
    );
    String url = params.toString();
    if (await canLaunch(url)) {
      await launch(url);
    } else {
      print('Could not launch $url');
    }
  }

它将默认打开正文和主题。

试试这个!

void _launchURL() async {
    final Uri params = Uri(
      scheme: 'mailto',
      path: 'my.mail@example.com',
    );
    String  url = params.toString();
    if (await canLaunch(url)) {
      await launch(url);
    } else {
      print( 'Could not launch $url');
    }
  }

正如@tsitixe 所指出的,您可以使用 Piyushs 的答案并更改查询参数以像这样查询以避免电子邮件中单词之间的“+”符号:

void launchEmailSubmission() async {
    final Uri params = Uri(
    scheme: 'mailto',
    path: 'myOwnEmailAddress@gmail.com',
    query: 'subject=Default Subject&body=Default body'
);

String url = params.toString();
    if (await canLaunch(url)) {
    await launch(url);
} else {
    print('Could not launch $url');
}

}

不要忘记将这些添加到您的 AndroidManifest.xml:

<queries>
  <!-- If your app opens https URLs -->
  <intent>
    <action android:name="android.intent.action.VIEW" />
    <data android:scheme="https" />
  </intent>
  <!-- If your app makes calls -->
  <intent>
    <action android:name="android.intent.action.DIAL" />
    <data android:scheme="tel" />
  </intent>
  <!-- If your app emails -->
  <intent>
    <action android:name="android.intent.action.SEND" />
    <data android:mimeType="*/*" />
  </intent>
</queries>

我们对每种方法都做了一点。它考虑的事情:

  • 它将在网络上运行(canLaunch 不适用于网络,因此替换为 try/catch)。 Source.
  • 如果没有可用的邮件客户端,它会回退到使用剪贴板
  • 它使用辅助函数正确编码主题和正文(否则你会得到 + 而不是 space

用法

await EmailUtils.launchEmailSubmission(
         toEmail: 'info@catfacts.co',
         subject: 'I love this app',
         body: 'Your feedback below: \n');

email_utils.dart

import 'package:flutter/services.dart';
import 'package:url_launcher/url_launcher.dart';

class EmailUtils {
  
  /// Example
  /// ```dart
  /// await EmailUtils.launchEmailSubmission(
  ///       toEmail: 'info@catfacts.co',
  ///       subject: 'I love this app',
  ///       body: 'Your feedback below: \n');
  /// ```
  void launchEmailSubmission({
    required String toEmail,
    required String subject,
    required String body,
  }) async {
    String mailUrl = _getEmailString(toEmail: toEmail, subject: subject, body: body)
    // Use `try` instead of `canLaunch` because it doesn't work on web
    try {
      await launch(mailUrl);
    } catch (e) {
      await Clipboard.setData(ClipboardData(text: '$subject \n $body'));
      // Toast to user it was copied to clipboard
    }
  }

  static String _getEmailString({
    required String toEmail,
    required String subject,
    required String body,
  }) {
    final Uri emailReportUri = Uri(
      scheme: 'mailto',
      path: toEmail,
      query: _encodeQueryParameters(<String, String>{
        'subject': subject,
        'body': body,
      }),
    );

    return emailReportUri.toString();
  }

  /// Using `queryParameters` above encodes the text incorrectly.
  /// We use `query` and this helper function to encode properly.
  static String? _encodeQueryParameters(Map<String, String> params) {
    return params.entries
        .map((e) =>
            '${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value)}')
        .join('&');
  }
}