Table of Contents
Introduction
The url_launcher plugin allows your Flutter application to perform actions like opening a web page in Safari or deep-linking into another application with context.
In this article, you will use url_launcher to launch a web page, a map, and a telephone number.
Prerequisites
To complete this tutorial, you will need:
- To download and install Flutter.
- To download and install Android Studio _or_ Visual Studio Code.
- It is recommended to install plugins for your code editor:
Flutterextension installed for Visual Studio Code.
This tutorial was verified with Flutter v1.22.2, Android SDK v31.0.2, and Android Studio v4.1.
Step 1 — Setting Up the Project
Once you have your environment set up for Flutter, you can run the following to create a new application:
flutter create <^>url_launcher_example<^>
Navigate to the new project directory:
cd <^>url_launcher_example<^>
Using flutter create will produce a demo application that will display the number of times a button is clicked.
Step 2 — Adding the url_launcher Plugin
Next up, we'll need to add the url_launcher plugin within our pubspec.yaml:
[label pubspec.yaml]
dependencies:
flutter:
sdk: flutter
<^>url_launcher: ^6.0.3<^>
We can now go ahead and run this on the iOS or Android simulator or device of your choice.
Step 3 — Scaffolding the Application
Now, open main.dart in your code editor.
Replace everything in this file with with a MaterialApp that points at a HomePage which can be found at home.dart:
[label lib/main.dart]
import 'package:flutter/material.dart';
<^>import 'package:url_launcher_example/home.dart';<^>
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: <^>'URL Launcher'<^>,
theme: ThemeData(
primarySwatch: <^>Colors.deepPurple<^>,
),
home: <^>HomePage()<^>,
);
}
}
Next, create a new home.dart file and add the following lines of code:
[label lib/home.dart]
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("URL Launcher"),
),
body: Column(
children: <Widget>[
ListTile(
title: Text("Launch Web Page"),
onTap: () {},
),
],
),
);
}
}
Now that we've established a base application, we can start using url_launcher.
Step 4 — Launching Web Pages
url_launcher supports launching web pages.
Revisit home.dart and modify the following lines of code:
[label lib/home.dart]
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("URL Launcher"),
),
body: Column(
children: <Widget>[
ListTile(
title: Text("Launch Web Page"),
onTap: () <^>async<^> {
<^>const url = 'https://google.com';<^>
<^>if (await canLaunch(url)) {<^>
<^>await launch(url, forceSafariVC: false);<^>
<^>} else {<^>
<^>throw 'Could not launch $url';<^>
<^>}<^>
},
),
],
),
);
}
}
Notice how we're checking to see if the device canLaunch a particular URL scheme prior to calling the launch function.
Then run the application with the iOS emulator, and click Launch Web Page:
In this case, we're calling launch with forceSafariVC set to false. When unspecified, it will use "Safari View Controller".
If we wanted both iOS and Android to open the web page inside the application (as a WebView, for example), we'd do something like this:
[label lib/home.dart]
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("URL Launcher"),
),
body: Column(
children: <Widget>[
// ...
<^>ListTile(<^>
<^>title: Text("Launch Web Page (with Web View)"),<^>
<^>onTap: () async {<^>
<^>const url = 'https://google.com';<^>
<^>if (await canLaunch(url)) {<^>
<^>await launch(url, forceWebView: true);<^>
<^>} else {<^>
<^>throw 'Could not launch $url';<^>
<^>}<^>
<^>},<^>
<^>),<^>
],
),
);
}
}
Then run the application with the iOS emulator, and click Launch Web Page (with Web View):
Now you can use url_launcher for web pages.
Step 5 — Launching Google Maps and Apple Maps
url_launcher supports launching maps.
Revisit home.dart and set latitude and longitude:
[label lib/home.dart]
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
class HomePage extends StatelessWidget {
<^>final String lat = "37.3230";<^>
<^>final String lng = "-122.0312";<^>
// ...
}
Note: If you want to do this in a real application, you may want to take advantage of geocoding and geolocator to determine the user's current location
We can then add a new ListTile which can be used with the comgooglemaps: and https: URL schemes:
[label lib/home.dart]
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
class HomePage extends StatelessWidget {
final String lat = "37.3230";
final String lng = "-122.0312";
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("URL Launcher"),
),
body: Column(
children: <Widget>[
// ...
<^>ListTile(
<^>title: Text("Launch Maps"),<^>
<^>onTap: () async {<^>
<^>final String googleMapsUrl = "comgooglemaps://?center=$lat,$lng";<^>
<^>final String appleMapsUrl = "https://maps.apple.com/?q=$lat,$lng";<^>
<^>if (await canLaunch(googleMapsUrl)) {<^>
<^>await launch(googleMapsUrl);<^>
<^>}<^>
<^>if (await canLaunch(appleMapsUrl)) {<^>
<^>await launch(appleMapsUrl, forceSafariVC: false);<^>
<^>} else {<^>
<^>throw "Couldn't launch URL";<^>
<^>}<^>
<^>},<^>
<^>),<^>
],
),
);
}
}
Then, run the application with the iOS emulator, and click Launch Maps:
Now you can use url_launcher for web pages.
Step 6 — Launching Telephone
url_launcher supports launching phone calls.
Revisit home.dart and set a telephone number:
Let's add a telephoneNumber:
class HomePage extends StatelessWidget {
final String lat = "37.3230";
final String lng = "-122.0312";
<^>final String telephoneNumber = "01817658822";<^>
// ...
}
We can then add a new ListTile which can be used with the tel: URL scheme:
[label lib/home.dart]
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
class HomePage extends StatelessWidget {
final String lat = "37.3230";
final String lng = "-122.0312";
final String telephoneNumber = "01817658822";
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("URL Launcher"),
),
body: Column(
children: <Widget>[
// ...
<^>ListTile(<^>
<^>title: Text("Launch Telephone"),<^>
<^>onTap: () async {<^>
<^>String telephoneUrl = "tel:$telephoneNumber";<^>
<^>if (await canLaunch(telephoneUrl)) {<^>
<^>await launch(telephoneUrl);<^>
<^>} else {<^>
<^>throw "Can't phone that number.";<^>
<^>}<^>
<^>}<^>,
<^>),<^>
],
),
);
}
}
Then, run the application with a device and click Telephone:
Note: As pointed out by the url_launcher documentation, there are limitations with tel and other URL schemes in simulators without apps that support them.
Now you can use url_launcher for telephone numbers.
Conclusion
In this article, you used url_launcher to launch a web page, a map, and a telephone number.
If you'd like to learn more about Flutter, check out our Flutter topic page for exercises and programming projects.