'flutter send email with url_launcher uri

I'm using url_launcher to send email with system email in my app. I'm using code below and this guy is doing so well.

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');
    }
  }

But now I want to give it 'default' subject and hintText inside the mail body box(if hintText not possible, then normal text).

Is there any way to do this?



Solution 1:[1]

Try using queryParameters in Uri. You can achieve this in below shown way:

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');
    }
  }

It will open will default body and subject.

Solution 2:[2]

As @tsitixe pointed out you can use Piyushs answer and change queryParameters to query like this to avoid "+" symbols between the words in your E-Mail:

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');
}

}

Solution 3:[3]

Try this!

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');
    }
  }

Solution 4:[4]

Don't forget to add these at your 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>

Solution 5:[5]

We did a little bit of each of the approaches. Things it considers:

  • It will work on web (canLaunch doesn't work for web, so replace with try/catch). Source.
  • It falls back to using clipboard if no mail client is available
  • It encodes the subject and body correctly with a helper function (otherwise you'll get + instead of space )

Usage

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('&');
  }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Piyush Maurya
Solution 2 Can Kaplan
Solution 3 Rohit Soni
Solution 4 Mohammed Babe??y
Solution 5 Kyle Venn