Launch Native URL Schemes in Flutter with the url_launcher Plugin

Paul Halliday

When developing mobile applications, there’s going to be times when you want to interact with apps outside of your own app. This could be something as simple as opening a web page in Safari, to deep-linking into another application with context.

If this is something you’re looking for, we’re able to do exactly that with the url_launcher plugin! This plugin has 100 health rating on pub.dev and is made by the Google flutter.dev team.

Creating a new Flutter project

As always, we’ll start off by setting up a new project and adding the plugin:

# New Flutter project
$ flutter create flut_url_launcher

# Open this up inside of VS Code
$ cd flut_url_launcher && code .

Adding the URL Launcher plugin

Head over to your pubspec.yaml and add the following plugin:

dependencies:
  flutter:
    sdk: flutter

  url_launcher: ^5.2.5

Scaffolding our Project

Our application only requires one page. We’ll go ahead and create a HomePage at home_page.dart.

import 'package:flutter/material.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: () {},
          ),
        ],
      ),
    );
  }
}

Let’s add the HomePage to main.dart:

import 'package:flut_url_launcher/home.dart';
import 'package:flutter/material.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(),
    );
  }
}

Using the URL Launcher plugin

The first thing that we’ll be doing is launching a web page, hence why we’ve got a placeholder ListTile for that.

Web Pages

The web page we’ll be launching is google.com. Let’s update our ListTile to be an async function and do the following:

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.

App Launch

In this case, we’re calling launch with forceSafariVC, as this makes it launch directly in the application on iOS.

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:

const url = 'https://google.com';

if (await canLaunch(url)) {
  await launch(url, forceWebView: true);
} else {
  throw 'Could not launch $url';
}

This then gives us a WebView style:

WebView

Google Maps and Apple Maps

What about if you wanted to launch Google or Apple maps? Firstly, let’s define a lat and lng for wherever we want to open.

class HomePage extends StatelessWidget {
  final String lat = "37.3230";
  final String lng = "-122.0312";

  // ...
}

If you want to do this in a real application, you may want to take advantage of the Geolocation, for which I wrote about recently: Flutter: Getting a User's Location with the Geolocator Plugin

We can then create a new ListTile that takes advantage of this:

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

Maps

Telephone

Ring ring. Let’s add the functionality to call a phone number from within our app.

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:

ListTile(
  title: Text("Telephone"),
  onTap: () async {
    String telephoneUrl = "tel:$telephoneNumber";

    if (await canLaunch(telephoneUrl)) {
      await launch(telephoneUrl);
    } else {
      throw "Can't phone that number.";
    }
  },
),

Telephone

Wrap up

I hope you can see the potential with the url_launcher plugin! We’re able to power up our Flutter app(s) by integrating native experiences across the board.

  Tweet It

🕵 Search Results

🔎 Searching...

Sponsored by #native_company# — Learn More
#native_title# #native_desc#
#native_cta#