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.
url_launcher: open links, call, email #
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'));
LaunchMode | Opens in |
|---|---|
externalApplication | The browser, or the app that handles the link |
inAppBrowserView | A browser sheet on top of your app |
inAppWebView | A web view inside your app |
platformDefault | Whatever 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 #
| Kind | Plugin | Triggered by |
|---|---|---|
| Local | flutter_local_notifications | The app itself: reminders, timers, alarms |
| Push | firebase_messaging | Your 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.