Reputation: 1387
I have a little link in my app that says "Send us an e-mail". When you click it, I want the default email app to open, with an email started to our email address. I used to make it do exactly that with the launch()
method in the url_launcher
package like this:
import 'package:url_launcher/url_launcher.dart' as url;
Future<bool?> pressedSendUsEmail() async {
bool? success;
try {
print('Pressed Send us an e-mail...');
success = await url.launch('mailto:[email protected]'); // Works like a charm...
print('success is $success');
} catch (e) {
print('Caught an error in Send us an e-mail!');
print('e is: ${e.toString()}');
}
return success;
}
But now, I get a warning saying launch()
is deprecated! I should use launchUrl()
instead. But launchUrl()
doesn't take a String argument, it takes a Uri argument... and I don't know how to write this Uri correctly, so that it does what I want! I tried:
success = await url.launchUrl(Uri(path: 'mailto:[email protected]'));
but that throws an error, because it can't interpret the ":" character. I've tried:
success = await url.launchUrl(
Uri.https('mailto:[email protected]', ''),
);
and that launches the link, but in the browser... and it doesn't start up an e-mail to the pre-printed address. I tried adding:
success = await url.launchUrl(
Uri.https('mailto:[email protected]', ''),
mode: url.LaunchMode.externalApplication,
);
and that gives me an option of which external app to open the link with, but unfortunately, only browser apps are listed... not the email app!
How should I write my command to make the launchUrl()
just do exactly what the old launch()
did?? Most grateful for help!
Edit:
After that question was satisfactorily answered below, I now have a follow-up qn:
In another part of the app, there is a place where the user can type in a link, and I used to launch it with launch()
... Is there a simple way to do that, as well?
Because in that case, I don't know if the link is gonna be a http or a https or indeed a mailto:!... and I would prefer not having to write lots of code to find that out! I just want it to try and launch the link exactly the way it's written, and so long as it's written correctly, it will work.
Upvotes: 6
Views: 9127
Reputation: 44220
Using the service already built-in to Uri
...
void _sendEmail(){
final Uri emailLaunchUri = Uri(
scheme: 'mailto',
path: '[email protected]',
queryParameters: {
'subject': 'CallOut user Profile',
'body': widget.userModel?.username ?? ''
},
);
launchUrl(emailLaunchUri);
}
Upvotes: 8
Reputation: 75
The built-in query builder only work correctly for http/https.
For anything else, the following should be used, otherwise you will have "+" instead of spaces:
String? encodeQueryParameters(Map<String, String> params) {
return params.entries
.map((MapEntry<String, String> e) =>
'${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value)}')
.join('&');
}
///
void _sendEmail() {
final Uri emailLaunchUri = Uri(
scheme: 'mailto',
path: '[email protected]',
query: encodeQueryParameters({
'subject': 'CallOut user Profile',
'body': widget.userModel?.username ?? ''
}),
);
launchUrl(emailLaunchUri);
}
Source: url_launcher Documentation
Upvotes: 2
Reputation: 2521
Try this:
void _sendEmail(){
final Uri emailLaunchUri = Uri(
scheme: 'mailto',
path: '[email protected]',
queryParameters: {
'subject': 'CallOut user Profile',
'body': widget.userModel?.username ?? ''
},
);
launchUrl(emailLaunchUri);
}
Upvotes: 9