Dart Tutorial

Flutter Lesson 64 of 83 4 min read

url_launcher, share_plus, geolocator and Other Common Flutter Plugins

Open links, phone and email with url_launcher, share content with share_plus, get the device location with geolocator, and more.

On this page

A handful of plugins appear in almost every app. This lesson covers the ones you are most likely to need.

flutter pub add url_launcher
import 'package:url_launcher/url_launcher.dart';

Future<void> openWebsite() async {
  final url = Uri.parse('https://www.dart-tutorial.dev');
  final ok = await launchUrl(url, mode: LaunchMode.externalApplication);
  if (!ok) debugPrint('Could not open $url');
}

Future<void> callNumber(String number) => launchUrl(Uri(scheme: 'tel', path: number));

Future<void> sendSms(String number) => launchUrl(Uri(scheme: 'sms', path: number));

Future<void> sendEmail() => launchUrl(
      Uri(
        scheme: 'mailto',
        path: 'support@example.com',
        queryParameters: {'subject': 'Help with my order'},
      ),
    );

Future<void> openMap(double lat, double lng) =>
    launchUrl(Uri.parse('https://www.google.com/maps/search/?api=1&query=$lat,$lng'));
LaunchModeOpens in
externalApplicationThe browser, or the app that handles the link
inAppBrowserViewA browser sheet on top of your app
inAppWebViewA web view inside your app
platformDefaultWhatever the platform prefers

Setup for checking links. If you call canLaunchUrl, Android and iOS require you to declare which schemes you will ask about (<queries> in AndroidManifest.xml, LSApplicationQueriesSchemes in Info.plist). The simpler path is to call launchUrl directly and handle a false result, as above.

Build links with Uri(...), not string concatenation, so spaces and special characters are encoded correctly.

share_plus: the system share sheet #

flutter pub add share_plus
import 'package:share_plus/share_plus.dart';

Future<void> shareLesson() async {
  await SharePlus.instance.share(
    ShareParams(
      text: 'I am learning Flutter at https://www.dart-tutorial.dev/flutter/',
      subject: 'A good Flutter course',
    ),
  );
}

Future<void> shareFile(String path) async {
  await SharePlus.instance.share(
    ShareParams(files: [XFile(path)], text: 'My report'),
  );
}

The API of this plugin has changed between major versions. If these calls do not match the version you installed, check its page on pub.dev.

On iPad, the share sheet needs a position to point at. Pass sharePositionOrigin with the rectangle of the button that was tapped, or it may not appear.

geolocator: where is the device? #

flutter pub add geolocator

Setup: ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION in the Android manifest, and NSLocationWhenInUseUsageDescription in Info.plist.

import 'package:geolocator/geolocator.dart';

class LocationException implements Exception {
  LocationException(this.message);
  final String message;
}

Future<Position> currentPosition() async {
  if (!await Geolocator.isLocationServiceEnabled()) {
    throw LocationException('Location is switched off on this device.');
  }

  var permission = await Geolocator.checkPermission();
  if (permission == LocationPermission.denied) {
    permission = await Geolocator.requestPermission();
  }
  if (permission == LocationPermission.denied) {
    throw LocationException('Location permission was denied.');
  }
  if (permission == LocationPermission.deniedForever) {
    throw LocationException('Enable location for this app in Settings.');
  }

  return Geolocator.getCurrentPosition();
}

// Usage
final position = await currentPosition();
debugPrint('${position.latitude}, ${position.longitude}');

// Distance between two points, in metres
final metres = Geolocator.distanceBetween(27.7172, 85.3240, 28.2096, 83.9856);

There are four separate things that can go wrong: location switched off, permission denied, permission permanently denied, and no signal. Handle each with a clear message.

For continuous updates, such as tracking a delivery, listen to Geolocator.getPositionStream() and cancel the subscription when you are done. Location drains the battery.

To turn coordinates into an address, use the geocoding plugin.

package_info_plus: your app’s version #

import 'package:package_info_plus/package_info_plus.dart';

final info = await PackageInfo.fromPlatform();
Text('Version ${info.version} (${info.buildNumber})')

Show it on your About screen. It is the first thing you will ask a user who reports a bug.

connectivity_plus: online or offline #

import 'package:connectivity_plus/connectivity_plus.dart';

final results = await Connectivity().checkConnectivity();
final offline = results.contains(ConnectivityResult.none);

// React to changes
final subscription = Connectivity().onConnectivityChanged.listen((results) {
  debugPrint(results.contains(ConnectivityResult.none) ? 'Offline' : 'Online');
});

This reports whether the device has a network connection, not whether the internet is reachable. A device can be on Wi-Fi with no internet. The reliable approach is still to make the request and handle its failure.

local_auth: fingerprint and face #

import 'package:local_auth/local_auth.dart';

final auth = LocalAuthentication();

Future<bool> unlock() async {
  if (!await auth.isDeviceSupported()) return false;
  try {
    return await auth.authenticate(
      localizedReason: 'Unlock to view your saved cards',
    );
  } catch (e) {
    return false;
  }
}

Notifications #

KindPluginTriggered by
Localflutter_local_notificationsThe app itself: reminders, timers, alarms
Pushfirebase_messagingYour server, even when the app is closed

Both need the notification permission on Android 13 and later and on iOS, plus setup steps described in their documentation. Push notifications on iOS also need an Apple developer account and a real device.

Clipboard and haptics, with no plugin #

import 'package:flutter/services.dart';

await Clipboard.setData(const ClipboardData(text: 'ORDER-1042'));
final data = await Clipboard.getData(Clipboard.kTextPlain);

HapticFeedback.lightImpact();     // a small tap
HapticFeedback.selectionClick();  // when a picker changes

Try it yourself #

Build a “contact us” screen with four buttons: call a number, send an email with a prefilled subject, open a location in maps, and share the app. Add the app’s version at the bottom. Test what happens on an emulator that has no phone app.

Practise in the playground Updated by Santosh Adhikari