URL Launcher is a Flutter plug-in that allows your applications to launch web browsers, map applications, dialer applications, mail applications, and more. The URL Launcher plug-in creates intents to open applications that use different URL schemes.

In this article, we’ll build a simple project that demonstrates how to use the URL Launcher plug-in to open a Web browser and dialer, mail, and maps applications.

The premise condition

Before completing this tutorial, you must have the following Settings.

  • Any IDE that has the Flutter SDK installed (e.g. Android Studio, VSCode).
  • Dart and Flutter basics

This tutorial is validated with Flutter V2.5.1 and Android Studio V3.5.

So, with everything set, let’s get started.

Project Settings

Create a new Flutter project by running the following command on the terminal.

$ flutter create url_launcher_example

Copy the code

Next, we need to add the URl_launcher plug-in as a dependency to our project. You can do this by running the following command on your terminal.

$ flutter pub add url_launcher

Copy the code

Therefore, the URl_launcher plug-in will be added as a dependency to our pubspec.yaml file.

Next, we need to build the user interface for our application. Copy and paste the following code into your main.dart file.

import 'package:flutter/material.dart'; import 'package:url_launcher_example/custom_button.dart'; import 'package:url_launcher/url_launcher.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', debugShowCheckedModeBanner: false, theme: ThemeData( primarySwatch: Colors.blue, ), home: const MyHomePage(), ); } } class MyHomePage extends StatelessWidget { const MyHomePage({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xFF3E1F92), body: SafeArea(child: Padding(Padding: const EdgeInsets. All (20.0), child: Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text('Get in touch', style: TextStyle(color: colors.white, fontSize: 30.0, fontWeight: fontweight.bold), const SizedBox(height: 10.0), const Text("We'd love to hear from you. Our friendly team is always here to chat.", style: TextStyle(color: Color(0xFFA895D1), fontSize: 15.0, fontWeight: fontweight.normal), const SizedBox(height: TextButton(onPressed: () {// Logic goes here}, style: textButton.styleFrom (padding: const EdgeInsets.all(15), ), child: Row( mainAxisSize: MainAxisSize.min, children: const [ Icon(Icons.phone, color: Color(0xFFED92A2)), SizedBox(width: 20.0), Text('+0123 4567 8910', style: TextStyle(Color: red) Color(0xFFA294C2), fontSize: 16.0, fontWeight: fontweight.w500),],),), TextButton(onPressed: () { //logic goes here }, style: TextButton.styleFrom( padding: const EdgeInsets.all(15), ), child: Row( mainAxisSize: MainAxisSize.min, children: const [ Icon(Icons.sms, color: Color(0xFFED92A2)), SizedBox(width: 20.0), Text('+0123 4567 8910', style: TextStyle(color: color (0xFFA294C2), fontSize: 16.0, fontWeight: FontWeight.w500)), ], ), ), TextButton( onPressed: () { //logic goes here }, style: TextButton.styleFrom( padding: const EdgeInsets.all(15), ), child: Row( mainAxisSize: MainAxisSize.min, children: const [ Icon(Icons.mail, color: Color(0xFFED92A2)), SizedBox(width: 20.0), Text('[email protected]', style: TextStyle(Color: Color(0xFFA294C2), fontSize: 16.0, fontWeight: fontweight.w500),],),), TextButton(onPressed: () { //logic goes here }, style: TextButton.styleFrom( padding: const EdgeInsets.all(15), ), child: Row( mainAxisSize: MainAxisSize.min, children: const [ Icon(Icons.location_pin, color: Color(0xFFED92A2)), SizedBox(width: 20.0), Text('87 Summer St., Boston, MA 02110', style: TextStyle(color: color (0xFFA294C2), fontSize: 16.0, fontWeight: FontWeight.w500)), ], ), ), TextButton( onPressed: () { //logic goes here }, style: TextButton.styleFrom( padding: const EdgeInsets.all(15), ), child: Row( mainAxisSize: MainAxisSize.min, children: const [ Icon(Icons.language, color: Color(0xFFED92A2)), SizedBox(width: 20.0), Text('blog.logrocket.com', style: TextStyle(Color: Color(0xFFA294C2), fontSize: 16.0, fontWeight: fontweight.w500)),],),],),),)); }}Copy the code

Now that we have created a basic user interface for our application, we can run the code on emulators or physical devices. When the execution is complete, your device or emulator should display a screen similar to this.

The asynchronous function of the URL initiator

The URL Launcher plug-in provides two asynchronous functions: canLaunch and launch. The canLaunch function returns a Boolean value indicating whether the device can handle a URL scheme. For example, if a device does not have an E-mail application installed, it will not be able to launch a URL using the Mailto scheme.

The launch function, on the other hand, takes a String as an argument, as a URL; It parses the given URL string and passes it to the underlying platform for processing. The launch function also has other named optional parameters that can be used to change specific Settings on the Android and iOS platforms, some of which are shown below.

  • Android Settings only.
    • forceWebView– If set tonullfalse, open the URL in the default browser of the device. Otherwise, launch the URL in the WebView
    • enableJavaScript– If set totrue, enable JavaScript in the WebView.
    • enableDomStorage– When the value is set totrueWebView enables DOM storage.
  • IOS Settings only.
    • forceSafariVC– If set totrue, opens the URL in Safari view Controller; Otherwise, the device’s default handler is used
    • statusBarBrightness– Collects an enumeration value, which can beBrightness.darkOr it could beBrightness.lightTo set the status bar brightness of the app after opening the link on an iOS device.

Now that we know how the URL Launcher plug-in works and what it provides, let’s look at some examples of how we can implement it in our application.

Launch a web page with the URL Launcher

The following code is self-explanatory; Notice that we use the canLaunch function to check if the device canLaunch a specific URL scheme, and then call the launch function.

TextButton(
  onPressed: () async {
      const url = 'https://blog.logrocket.com';
      if(await canLaunch(url)){
        await launch(url);
      }else {
        throw 'Could not launch $url';
      }
    },
    child: const CustomWidget(
      icon: Icons.language,
      label: 'Open a URL',
    ),
),

Copy the code

Run the code on your device and launch the page by clicking on the Open URL card from our original user interface.

In cases where we want the browser to be embedded in our application, we set the forceWebView to true.

TextButton( onPressed: () async { const url = 'https://blog.logrocket.com'; if(await canLaunch(url)){ await launch(url, forceWebView = true); //forceWebView is true now }else { throw 'Could not launch $url'; }},... //Copy the code

We can choose to disable JavaScript on websites to improve our browsing speed and online activity; However, there is a downside to this, which is that if we set enableJavaScript to false, you may not be able to access certain features of the site. Considering Twitter’s official website, it relies heavily on JavaScript.

TextButton( onPressed: () async { const url = 'https://www.twitter.com'; //Twitter's URL if(await canLaunch(url)){ await launch( url, forceWebView = true, //enables WebView enableJavaScript = false //disables JavaScript ); }else { throw 'Could not launch $url'; }},... //Copy the code

EnableJavaScript = true with JavaScript enabled, we get the following result.

Start a phone dialer application

To initiate a call, we use the TEL: URL scheme, followed by a phone number, as shown in the code below.

TextButton(
  onPressed: () async {
    String telephoneNumber = '+2347012345678';
    String telephoneUrl = "tel:$telephoneNumber";
    if (await canLaunch(telephoneUrl)) {
      await launch(telephoneUrl);
    } else {
      throw "Error occured trying to call that number.";
    }
    child: const CustomWidget(
      icon: Icons.call,
      label: 'Call a phone\nnumber',
    ),
),

Copy the code

Start a messaging app

To send a short message, we use the SMS: URL scheme and an implementation similar to the one above.

TextButton(
  onPressed: () async {
    String telephoneNumber = '+2347012345678';
    String smsUrl = "sms:$telephoneNumber";
    if (await canLaunch(smsUrl)) {
        await launch(smsUrl);
    } else {
        throw "Error occured trying to send a message that number.";
    }
    child: const CustomWidget(
      icon: Icons.textsms,
      label: 'Send an SMS',
    ),
),

Copy the code

Start a mail application

To send an E-mail, we need to pass the recipient’s E-mail address, the subject line, the body of our E-mail, and the Mailto: URL scheme to the emailUrl Widget, in addition to the Mailto: URL scheme. See below.

TextButton( onPressed: () async { String email = '[email protected]'; String subject = 'This is a test email'; String body = 'This is a test email body'; String emailUrl = "mailto:$email? subject=$subject&body=$body"; if (await canLaunch(emailUrl)) { await launch(emailUrl); } else { throw "Error occured sending an email"; } }, child: const CustomWidget( icon: Icons.forward_to_inbox, label: 'Send an email', ), ),Copy the code

Start the map

To view a location on a map, we need to pass the location’s latitude and longitude values along with the Geo: URL scheme to mapUrl.

TextButton(onPressed: () async {const String lat = "42.3540"; Const String LNG = "71.0586"; const String mapUrl = "geo:$lat,$lng"; if (await canLaunch(mapUrl)) { await launch(mapUrl); } else { throw "Couldn't launch Map"; } }, child: const CustomWidget( icon: Icons.near_me, label: 'Check location', ), ),Copy the code

conclusion

The URL Launcher plug-in is handy when you need to connect to other applications from your application. We’ve looked at the use of the URL Launcher plug-in and how to implement it to suit each use.

The full code for the project can be found on GitHub. Thank you for reading.