Exploring the hidden ventures of Url Launcher in Flutter

Using Url Launcher in Flutter enhances the App’s ability to foster amazing outcomes. With the help of this amazing tool/plugin, we can incorporate URL redirection, prepare Email stuff, send an SMS, and so on. Moreover, due to its outstanding popularity, it has now become Flutter’s favorite. With that being said, let’s elucidate Exploring the hidden ventures of Url Launcher in Flutter.


Table of Contents

– More on Url Launcher

Url Launcher has strong support for all major platforms of Flutter including Android, iOS, Web, Linux, Windows, and Mac. In addition to this, it has an excellent optimization of previewing a web page under an In-App View or the Browser itself.

Secondly, there needs to be some sort of configuration required to fulfill certain tasks. For instance, SMS, Email, etc.

Let’s now move on to the next section and shed some light on the project overview.

– Project Overview

Our project is going to be intelligible, i.e. we have the following:

A screen that represents ElevatedButtons with each performing different tasks is supported by this plugin.

Let’s now move on to the implementation section.

– Implementation

First, install the url_launcher plugin under pubspec.yaml file.

Note: If you’re facing any sort of issue regarding versions, you can use this command to install a suitable version of any package/plugin.

flutter pub add url_launcher

Otherwise, you are good to go.

— Setting up the UI

Create a new dart file as demo_screen.dart and fill it up with the following snippet:

import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:url_launcher_demo/widgets/customized_button.dart';

class DemoScreen extends StatelessWidget {
  const DemoScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text("Url Launcher"),
        ),
        body: ListView(
          shrinkWrap: true,
          padding: const EdgeInsets.symmetric(
            horizontal: 14,
            vertical: 30,
          ),
          children: [
            CustomizedButton(
                onTap: () {},
                label: "Redirection"),
            CustomizedButton(
                onTap: () {},
                label: "Redirection In-App Preview"),
            CustomizedButton(
                onTap: () {},
                label: "Send an Email"),
            CustomizedButton(
                onTap: () {},
                label: "Send an SMS"),
            CustomizedButton(
                onTap: () {},
                label: "TEL"),
          ],
        ));
  }
}

For now, this snippet contains five customized buttons, each having a different task to perform.

Let’s now dive into each of them.

1- Redirection

Passing a URL to the scheme that redirects to the webpage.

Here is a self-explanatory code snippet:

  dynamic urlRedirect(String url) async {
    final result = await launchUrl(Uri.parse(url));

    if (!result) {
      throw Exception("Error");
    }
  }

In the above snippet, launchUri is a pre-build function that verifies the provided URL and parses it accordingly. If this fails, it will throw an exception, otherwise redirect.

Let’s now attach this function with:

CustomizedButton(
  onTap: () {
    urlRedirect("https://www.flutterdirectory.com");
  },
label: "Redirection"),

Run the app and try it out!

Visual Preview

2. Redirection – In-App-Preview

In-App-Preview refers to the URL redirection in the app itself, rather than in the browser, allowing it to have a:

  • Cache Mechanism
  • Javascript Services

In the above snippet, create a new function as:

 dynamic urlRedirectInApp(String url) async {
    final result = await launchUrl(Uri.parse(url));

    if (!result) {
      throw Exception("Error");
    }
  }

For now, it remains the same as the first one.

Here, under the launchUri itself, add a mode like:

mode: LaunchMode.inAppWebView,

followed by webConfiguration:

webViewConfiguration: const WebViewConfiguration(
  enableJavaScript: true,
  enableDomStorage: true
),

The final code snippet:

  dynamic urlRedirectInApp(String url) async {
    final result = await launchUrl(
      Uri.parse(url),
      mode: LaunchMode.inAppWebView,
      webViewConfiguration: const WebViewConfiguration(
        enableJavaScript: true,
        enableDomStorage: true
      ),
    );

    if (!result) {
      throw Exception("Error");
    }
  }

Attach this function with the respective ElevatedButton and reload the App.

You will be able to see a slight difference.

3. Send an Email

This is a bit of a tricky section, so special attention is required here.

We need to keep the following things in mind:

  • Modifying the Scheme
Uri emailUri = Uri(
 scheme: 'mailto',
);
  • Adding the Path (receiver’s email address)
Uri emailUri = Uri(
 scheme: 'mailto',
 path: 'testuser@gmail.com',
);
  • Attach encodedQueryParams

Note: For any scheme besides http or https, it is a safe approach to use queryParameters to prevent spaces from being converted to + in many cases (according to the doc).

Here’s the encoded function:

  String encodeQueryParams(Map<String, String> params) {
    return params.entries
        .map((MapEntry<String, String> e) =>
            "${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value)}")
        .join('&');
  }

Now, attach this function to the existing Uri Scheme:

Uri emailUri = Uri(
 scheme: 'mailto',
 path: 'testuser@gmail.com',
 query: encodeQueryParameters(<String, String>{
   'subject': 'This is a sample test subject',
  }),
);

Finally, to run this scheme, use:

await launchUrl(emailRes);

Attach this function with the CustomizedBbutton's onPressed entity, and you’re good to go.

4. Send an SMS

For this scheme, there needs to be some configurations done, for Android and iOS, depending on the API level.

  • Android

Note: If your App is targeting (Android 11) API level 30 or above, we need to add <queries> tag, supported by the respective <intent>

Under the AndroidManifest.xml file, and after the closure of </application>, add the following snippet:

    <queries>
        <intent>
            <action android:name="android.intent.action.VIEW" />
            <data android:scheme="sms" />
        </intent>
    </queries>
  • iOS

Under the info.plist file, add this scheme as LSApplicationQueriesSchemes:

<key>LSApplicationQueriesSchemes</key>
<array>
  <string>sms</string>
</array>

Now, in the demo_screens.dart, add a new function, and fill up with the following Uri:

Uri smsUri = Uri(
 scheme: 'sms',
 path: '234567899',
 query: encodeQueryParams({"body": "Test Msg"}),
);

And lastly, attach this to launchUri

await launchUrl(smsUri);

Visual Preview

Send an SMS

5. Add a Call (TEL)

Just as we did with the SMS scheme, we need to do the same for TEL as well.

  • Android

Under the AndroidManifest.xml file, append the existing code with:

<intent>
  <action android:name="android.intent.action.VIEW" />
  <data android:scheme="tel" />
</intent>

Complete Code view:

    <queries>
        <intent>
            <action android:name="android.intent.action.VIEW" />
            <data android:scheme="sms" />
        </intent>

        <intent>
            <action android:name="android.intent.action.VIEW" />
            <data android:scheme="tel" />
        </intent>
    </queries>
  • iOS

Under info.plist, append within the existing key:

<string>tel</string>

Complete Code view:

<key>LSApplicationQueriesSchemes</key>
    <array>
      <string>sms</string>
      <string>tel</string>
    </array>

In the demo_screens.dart, add a new function, and fill up with the following Uri:

 dynamic telRedirection() async {
    Uri telRes = Uri(
      scheme: 'tel',
      path: '+1234567899',
    );

    await launchUrl(telRes);
  }

Visual Preview

TEL

6. Google Map Redirection

So, up till now, we have covered all aspects of url_launcher, but with an addition, we are going to parse Google Maps as well.

For this, we shall need the following stuff:

String url;
String latitude;
String longitude;

Considering Pakistan's latitude and longitude, the following snippet represents this:

String pkLat = "29.951343261529818";
String pkLng = "69.28117596277134";

---- url in the following format ----
https://www.google.com/maps/search/?api=1&query=$pkLat,$pkLng;

We’re done with the half part, it’s time to encode this URL with:

Uri.encodeFull(mapUrl);

Finally, test it with:

await launchUrl(Uri.parse(encodedURl));

The Complete Code View:

launchMap() async {

    String pkLat = "29.951343261529818";
    String pkLng = "69.28117596277134";

    String googleMapslocationUrl = "https://www.google.com/maps/search/?
    api=1&query=$pkLat,$pkLng";

    final String encodedURl = Uri.encodeFull(googleMapslocationUrl);

    final result = await launchUrl(Uri.parse(encodedURl));

    if (!result) {
      throw Exception("Error");
    }
 }

Note: encodeFull entity encodes the URI string to percent-encoding for safe literal use as a full URI. For eg, digits and characters are percent-encoded (as per doc).

Attach another ElevatedButton and you’re good to go.

Visual Preview

Map
Hope you enjoyed reading it!!

The Conclusion

So, in this blog post, Exploring the hidden ventures of Url Launcher in Flutter, we descriptively discussed how this plugin interacts with Flutter in the form of URLs, email, SMS, and so on. Furthermore, we attached some valuable code snippets and lesson notes in between with a special focus on Google Maps at the end. Other than that, we attached respective visuals for better understanding.

If you think that something is missing, please jot it down in the comment section below, I would be more than happy to respond.

Link to the source code – Click Here

Check out my YouTube handle for Flutter & GitHub tutorials

Previous Blog Posts – Click Here

Thank you so much for your precious time!

1 thought on “Exploring the hidden ventures of Url Launcher in Flutter”

Leave a Comment