19

Hello I try to launch email page with recipent. I tried flutter email sender who work with android but not on ios for me. So I tried url launcher to do the same thing, but not working also with iOS. I use iOS simulator, the problem can be this ?

I use this example of url launcher

mailto:xxxxx@xxxxx.com?subject=News&body=New%20plugin

I have this error

[VERBOSE-2:ui_dart_state.cc(148)] Unhandled Exception: Could not launch mailto:xxxx@xxxx.com?subject=News&body=New%20plugin
#0      _menuscreenState._launchURL (package:xxxx/bottom.dart:8285:7)
<asynchronous suspension>
#1      _menuscreenState.build.<anonymous closure>.<anonymous closure> (package:xxxx/bottom.dart:8705:13)

Here is the full example with url launcher

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

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {


  String email="contact@ouiquit.com";
  _launchEmail() async {
    if (await canLaunch("mailto:$email")) {
      await launch("mailto:$email");
    } else {
      throw 'Could not launch';
    }
  }

  @override
  Widget build(BuildContext context) {


    return MaterialApp(
      theme: ThemeData(primaryColor: Colors.red),
      home: Scaffold(
        appBar: AppBar(
          title: Text('test mail'),
          actions: <Widget>[
            IconButton(
              onPressed: _launchEmail,
              icon: Icon(Icons.send),
            )
          ],
        ),


      ),
    );
  }


}

Here is the error

[VERBOSE-2:ui_dart_state.cc(148)] Unhandled Exception: MissingPluginException(No implementation found for method canLaunch on channel plugins.flutter.io/url_launcher)
#0      MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:314:7)
<asynchronous suspension>
#1      canLaunch (package:url_launcher/url_launcher.dart:112:25)
<asynchronous suspension>
#2      _MyAppState._launchEmail (package:testmail/main.dart:20:15)
<asynchronous suspension>
#3      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:654:14)
#4      _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:729:32)
#5      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24)
#6      TapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:365:11)
#7      TapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:275:7)
#8      PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/<…>
Nitneuq
  • 3,866
  • 13
  • 41
  • 64

9 Answers9

36

This works for me on both Android and iOS devices:

Add query parameter if you have subject and body too.

final Uri params = Uri(
  scheme: 'mailto',
  path: 'email@example.com',
  query: 'subject=App Feedback&body=App Version 3.23', //add subject and body here
);

var url = params.toString();
if (await canLaunch(url)) {
  await launch(url);
} else {
  throw 'Could not launch $url';
}
Matt Ke
  • 3,599
  • 12
  • 30
  • 49
Ravinder Kumar
  • 7,407
  • 3
  • 28
  • 54
25

The above given solutions will work for API < 30 but for API >= 30 the following is needed to be added to your AndroidManifest.xml file for email sending to work.

<queries>
    <intent>
        <action android:name="android.intent.action.VIEW" />
        <data android:scheme="https" />
    </intent>
    <intent>
        <action android:name="android.intent.action.SEND" />
        <data android:mimeType="*/*" />
    </intent>
</queries>

source

StuckInPhDNoMore
  • 2,507
  • 4
  • 41
  • 73
9

For iOS

There is no Email App installed on the iOS Simulator you only can test this on a real device.

Furkan Cetintas
  • 600
  • 5
  • 13
4

This is the function I use to send mail using url_launcher :

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');
    }
  }
Axel Frau
  • 109
  • 1
  • 12
3

For all people still wondering why it is not working like I did. Remember that the simulator cannot handle mailto because the mail application is not available. If you use canLaunch before calling launch you will get more info.

Nuqo
  • 3,793
  • 1
  • 25
  • 37
2

try mailto plugin

https://pub.dev/packages/mailto#-readme-tab-

it works in both android & ios on device, it works great..

void funcOpenMailComposer() async{

    final mailtoLink = Mailto(
      to: ['test@gmail.com'],
      cc: ['test12@gmail.com','test13@gmail.com'],
      subject: '',
      body: '',
    );
  await launch('$mailtoLink');
}
Dharini
  • 700
  • 7
  • 20
1

Please try this, I have used this and it's working fine for me.

 _launchEmail() async {
      if (await canLaunch("mailto:$email")) {
        await launch("mailto:$email");
      } else {
        throw 'Could not launch';
      }
    }
1

For iOS i have add like this

**

_launchEmail() async {
    // ios specification
    final String subject = "Subject:";
    final String stringText = "Same Message:";
    String uri = 'mailto:administrator@gmail.com?subject=${Uri.encodeComponent(subject)}&body=${Uri.encodeComponent(stringText)}';
    if (await canLaunch(uri)) {
      await launch(uri);
    } else {
      print("No email client found");
    }
  }

**

1

I added this line in my manifest and I was able to start a call, open maps etc.

<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>

more info

Ninad7N
  • 544
  • 4
  • 13
  • 2
    Be aware if you do that, you will have to declare the usage of this permission on Google Play when deploying a production release. – Peter Ivanics Mar 08 '23 at 07:20