tsitixe
tsitixe

Reputation: 2341

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?

Upvotes: 10

Views: 11798

Answers (10)

rawcane
rawcane

Reputation: 55

canLaunch and Launch are now deprecated and need to be replaced by canLaunchUrl and LaunchUrl.

Adapting the example from url_launcher

You get something like

String? encodeQueryParameters(Map<String, String> params) {
    return params.entries
      .map((MapEntry<String, String> e) =>
          '${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value)}')
      .join('&');
  }

void launchEmailSubmission() async {
    final Uri emailUrl = Uri(
      scheme: 'mailto',
      path: '[email protected]',
      query: encodeQueryParameters(<String, String>{
        'subject': 'Default Subject',
        'body': 'Default body'
      }),
    );
 
    if (await canLaunchUrl(emailUrl)) {
      await launchUrl(emailUrl);
    } else {
      print('Could not launch $emailUrl');
    }
  }

Upvotes: 0

PK Chahar
PK Chahar

Reputation: 111

Below code working for me

    final String mMail = '[email protected]';
  _launchEmail() async {
    String email = Uri.encodeComponent(mMail);
    String subject = Uri.encodeComponent("App Support");
    String body = Uri.encodeComponent("");
    print(subject);
    Uri mail = Uri.parse("mailto:$email?subject=$subject&body=$body");
    if (await launchUrl(mail)) {
      //email app opened
    }else{
      //email app is not opened
    }
  }

Upvotes: 0

Subham Sharma
Subham Sharma

Reputation: 31

'canLaunch and launch' are deprecated and shouldn't be used. Use canLaunchUrl and launchUrl instead. the urls must also be properly encoded.So, for that:

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

Upvotes: 1

Noat LVC
Noat LVC

Reputation: 11

'canLaunch' is deprecated and shouldn't be used. Use canLaunchUrl instead.

Let use

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

Upvotes: 1

Diraph
Diraph

Reputation: 327

In addition to @Can-Kaplan answer, as of JANUARY 2023, launch and canLaunch has been depreciated and should be replaced with launchUrl and canLaunchUrl respectively.

So the updated code will be:

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

It is important to note that the following must be added to android>app>src>main>AndroidManifest.xml

  <queries>
    <intent>
      <action android:name="android.intent.action.SENDTO" />
      <data android:scheme="mailto" />
    </intent>
  </queries>

I hope this helps.

Upvotes: 2

Kyle Venn
Kyle Venn

Reputation: 8038

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

Upvotes: 1

Mohammed Babełły
Mohammed Babełły

Reputation: 183

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>

Upvotes: 2

Can Kaplan
Can Kaplan

Reputation: 156

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

}

Upvotes: 7

Rohit Soni
Rohit Soni

Reputation: 1447

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

Upvotes: 2

Piyush Maurya
Piyush Maurya

Reputation: 2015

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.

Upvotes: 18

Related Questions