flutter 使用 url_launcher uri 发送电子邮件

问题描述 投票:0回答:8

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

void launchEmailSubmission() async {
    final Uri params = Uri(
      scheme: 'mailto',
      path: '[email protected]',
    );
    String url = params.toString();
    if (await canLaunch(url)) {
      await launch(url);
    } else {
      print('Could not launch $url');
    }
  }

但现在我想在邮件正文框中给它“默认”主题和提示文本(如果提示文本不可能,则为普通文本)。

有什么办法可以做到这一点吗?

flutter url mailto launcher
8个回答
18
投票

尝试在

queryParameters
中使用
Uri
。您可以通过以下方式实现此目的:

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

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


7
投票

正如 @tsitixe 指出的,您可以使用 Piyush 的答案并更改 queryParameters 来进行这样的查询,以避免电子邮件中的单词之间出现“+”符号:

void launchEmailSubmission() async {
    final Uri params = Uri(
    scheme: 'mailto',
    path: '[email protected]',
    query: 'subject=Default Subject&body=Default body'
);

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

}


2
投票

试试这个!

void _launchURL() async {
    final Uri params = Uri(
      scheme: 'mailto',
      path: '[email protected]',
    );
    String  url = params.toString();
    if (await canLaunch(url)) {
      await launch(url);
    } else {
      print( 'Could not launch $url');
    }
  }

2
投票

不要忘记将这些添加到您的

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>

1
投票

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

  • 它可以在网络上工作(
    canLaunch
    不适用于网络,所以用 try/catch 替换)。 来源
  • 如果没有可用的邮件客户端,则重新使用剪贴板
  • 它使用辅助函数正确编码主题和正文(否则你会得到
    +
    而不是空格
     

使用方法

await EmailUtils.launchEmailSubmission(
         toEmail: '[email protected]',
         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: '[email protected]',
  ///       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('&');
  }
}

1
投票

除了 @Can-Kaplan 的回答之外,截至 2023 年 1 月launch

canLaunch
折旧,应分别 替换为 launchUrl
canLaunchUrl

所以更新后的代码将是:

Future<void> launchEmailSubmission() async { final Uri params = Uri( scheme: 'mailto', path: '[email protected]', query: 'subject=Default Subject&body=DefaultBody'); if (await canLaunchUrl(params)) { await launchUrl(params); } else { log('Could not launch $params'); } }
需要注意的是,以下内容必须添加到

android>app>src>main>AndroidManifest.xml

<queries> <intent> <action android:name="android.intent.action.SENDTO" /> <data android:scheme="mailto" /> </intent> </queries>
我希望这有帮助。


1
投票
“canLaunch”已弃用,不应使用。请改用 canLaunchUrl。

使用吧

import 'package:url_launcher/url_launcher.dart'; //... final Uri params = Uri( scheme: 'mailto', path: '[email protected]', queryParameters: { 'subject': 'Default Subject', 'body': 'Default body' } ); if (await canLaunchUrl(params)) { await launchUrl(params); } else { print('Could not launch $params'); }
    

0
投票
“canLaunch 和 launch”已弃用,不应使用。请改用 canLaunchUrl 和 launchUrl。 网址也必须正确编码。因此:

void _sendEmail() async { String? encodeQueryParameters(Map<String, String> params) { return params.entries .map((MapEntry<String, String> e) => '${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value)}') .join('&'); } // ··· final Uri emailLaunchUri = Uri( scheme: 'mailto', path: [email protected], query: encodeQueryParameters(<String, String>{ 'subject': 'Your Subject', 'body':'Your body' }), ); try { launchUrl(emailLaunchUri); } catch (e) { print("errorr. $e"); }
    
© www.soinside.com 2019 - 2024. All rights reserved.