location 10.0.2
location: ^10.0.2 copied to clipboard
Cross-platform plugin for easy access to device's location in real-time.
location #
This plugin for Flutter handles getting a location across Android, iOS, macOS, web, Windows and Linux. It also provides callbacks when the location is changed.
| Android | iOS | macOS | Web | Windows | Linux |
|---|---|---|---|---|---|
| ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Background mode is available on Android and iOS. Windows relies on
Windows.Devices.Geolocation and Linux on GeoClue2 (over D-Bus); both require
the system location service to be enabled.
Web demo (more features available on Android/iOS)
Getting Started #
Add this to your package's pubspec.yaml file:
dependencies:
location: ^10.0.0
Android #
To use location background mode on Android, you have to use the enableBackgroundMode({bool enable}) API before accessing location in the background and adding necessary permissions. You should place the required permissions in your applications
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
Remember that the user has to accept the location permission to always allow to use the background location. The Android 11 option to always allow is not presented on the location permission dialog prompt. The user has to enable it manually from the app settings. This should be explained to the user on a separate UI that redirects the user to the app's location settings managed by the operating system. More on that topic can be found on Android developer pages.
iOS #
And to use it in iOS, you have to add this permission in Info.plist :
// This is probably the only one you need. Background location is supported
// by this -- the caveat is that a blue badge is shown in the status bar
// when the app is using location service while in the background.
NSLocationWhenInUseUsageDescription
// Deprecated, use NSLocationAlwaysAndWhenInUseUsageDescription instead.
NSLocationAlwaysUsageDescription
// Use this very carefully. This key is required only if your iOS app
// uses APIs that access the user’s location information at all times,
// even if the app isn't running.
NSLocationAlwaysAndWhenInUseUsageDescription
To receive location when application is in background, to Info.plist you have to add property list key :
UIBackgroundModes
with string value:
location
Web #
Nothing to do, the plugin works directly out of box.
macOS #
Ensure that the application is properly "sandboxed" and that the location is enabled. You can do this in Xcode with the following steps:
- In the project navigator, click on your application's target. This should bring up a view with tabs such as "General", "Capabilities", "Resource Tags", etc.
- Click on the "Capabilities" tab. This will give you a list of items such as "App Groups", "App Sandbox", and so on. Each item will have an "On/Off" button.
- Turn on the "App Sandbox" item and press the ">" button on the left to show the sandbox stuff.
- In the "App Data" section, select "Location".
Add this permission in Info.plist :
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
Windows #
Nothing to do. The plugin uses the Windows.Devices.Geolocation APIs, which
prompt the user for location access on first use. Make sure Location is enabled
in the Windows privacy settings.
Linux #
The plugin talks to GeoClue2
over D-Bus, so a running geoclue service is required (it ships with most
desktop distributions). No extra dependency needs to be bundled with your app.
Usage #
Then you just have to import the package with
import 'package:location/location.dart';
In order to request location, you should always check Location Service status and Permission status manually
Location location = Location();
bool serviceEnabled;
PermissionStatus permissionGranted;
LocationData locationData;
serviceEnabled = await location.serviceEnabled();
if (!serviceEnabled) {
serviceEnabled = await location.requestService();
if (!serviceEnabled) {
return;
}
}
permissionGranted = await location.hasPermission();
if (permissionGranted == PermissionStatus.denied) {
permissionGranted = await location.requestPermission();
if (permissionGranted != PermissionStatus.granted) {
return;
}
}
locationData = await location.getLocation();
You can also get continuous callbacks when your position is changing:
location.onLocationChanged.listen((LocationData currentLocation) {
// Use current location
});
To receive location when application is in background you have to enable it:
location.enableBackgroundMode(enable: true)
enableBackgroundMode(enable: true) is a standalone call: you can invoke it
before you start listening to onLocationChanged. On Android it also
requests the ACCESS_BACKGROUND_LOCATION permission when it has not been granted
yet, so you can use it to prompt for background permission independently, without
having to activate a location stream first.
This only keeps tracking location while your app process is alive — on
Android via a foreground service, on iOS via a background execution exemption.
Neither survives the user manually killing the app (swiping it away from the
recent-apps list) or the OS terminating it outright; there is no way for any
Flutter plugin to run Dart code once the process itself no longer exists. If
you need tracking that resumes after the app is killed/terminated, look at a
plugin built around native background services designed for that, such as
flutter_background_geolocation.
Be sure to check the example project to get other code samples.
On Android, a foreground notification is displayed with information that location service is running in the background.
On iOS, while the app is in the background and gets the location, the blue system bar notifies users about updates. Tapping on this bar moves the User back to the app.
Public Methods Summary #
| Return | Description |
|---|---|
| Future<PermissionStatus> | requestPermission() Request the Location permission. Returns a PermissionStatus to know if the permission has been granted. |
| Future<PermissionStatus> | hasPermission() Returns a PermissionStatus to know the state of the location permission. |
| Future<bool> | isBackgroundPermissionGranted() Whether background ("Allow all the time"/Always) location access has been granted, separately from foreground access. Always false on web. |
| Future<bool> | serviceEnabled() Returns a boolean to know if the Location Service is enabled or if the user manually deactivated it. |
| Future<bool> | requestService() Show an alert dialog to request the user to activate the Location Service. On iOS, will only display an alert due to Apple Guidelines, the user having to manually go to Settings. Returns a boolean to know if the Location Service has been activated (always false on iOS). |
| Future<bool> | changeSettings({accuracy, interval, distanceFilter, pausesLocationUpdatesAutomatically, backgroundInterval}) Changes the settings of future requests. interval/distanceFilter/backgroundInterval are Android-only; pausesLocationUpdatesAutomatically is iOS/macOS-only. See settings for details. |
| Future<LocationData> | getLocation() Gets a one-time position of the user. Requests permission if not already granted, and throws a PERMISSION_DENIED error if permission still isn't granted. |
| Future<LocationData?> | getLastKnownLocation() Returns the most recently cached location immediately (or null if none is available), without waiting for a fresh fix. Always null on web. |
| Stream<LocationData> | onLocationChanged Stream of the user's location. Requests permission if not already granted, and throws a PERMISSION_DENIED error if permission still isn't granted. |
| Future<bool> | isBackgroundModeEnabled() Checks whether background mode is currently enabled. |
| Future<bool> | enableBackgroundMode({enable, requireBackgroundPermission}) Enables or disables retrieving location events in the background (Android/iOS only). requireBackgroundPermission (Android only, default true) controls whether ACCESS_BACKGROUND_LOCATION is required. |
| Future<AndroidNotificationData?> | changeNotificationOptions({channelName, title, iconName, imageName, iconBytes, imageBytes, subtitle, description, color, onTapBringToFront}) Customizes the Android background-mode notification. See notifications. |
You should try to manage permission manually with requestPermission() to avoid error, but plugin will try handle some cases for you.
Objects #
class LocationData {
final double latitude; // Latitude, in degrees
final double longitude; // Longitude, in degrees
final double? accuracy; // Estimated horizontal accuracy of this location, radial, in meters
final double? verticalAccuracy; // Estimated vertical accuracy of altitude, in meters
final double? altitude; // In meters above the WGS 84 reference ellipsoid
final double? speed; // In meters/second
final double? speedAccuracy; // In meters/second. Not available on web
final double? heading; // Horizontal direction of travel of this device, in degrees
final double? time; // Timestamp of the LocationData
final bool? isMock; // Is the location currently mocked
final bool? isProducedByAccessory; // Whether the fix came from a connected accessory (e.g. external GPS). iOS/macOS only
final double? headingAccuracy; // Estimated bearing accuracy, in degrees. Android only
final double? elapsedRealtimeNanos; // Time of this fix, in elapsed real-time since system boot. Android only
final double? elapsedRealtimeUncertaintyNanos; // Uncertainty of elapsedRealtimeNanos. Android only
final int? satelliteNumber; // Number of satellites used to derive the fix. Android only
final String? provider; // Name of the provider that generated this fix. Android only
}
enum LocationAccuracy {
powerSave, // To request best accuracy possible with zero additional power consumption
low, // To request "city" level accuracy
balanced, // To request "block" level accuracy
high, // To request the most accurate locations available
navigation, // To request location for navigation usage (affects only iOS)
reduced, // Maps to kCLLocationAccuracyReduced on iOS 14+; equivalent to `low` elsewhere
}
// Status of a permission request to use location services.
enum PermissionStatus {
/// The permission to use location services has been granted for high accuracy.
granted,
/// The permission has been granted but for low (approximate) accuracy only.
grantedLimited,
/// The permission to use location services has been denied by the user. May have been denied forever on iOS.
denied,
/// The permission to use location services has been denied forever by the user. No dialog will be displayed on permission request.
deniedForever
}
LocationData also has toJson()/fromJson() and copyWith() for serialization and copying.
Note: you can convert the timestamp into a DateTime with: DateTime.fromMillisecondsSinceEpoch(locationData.time!.toInt())
Feedback #
Please feel free to give me any feedback helping support this plugin !



