Skip to content

Utilizing the Location Package in Flutter: A Comprehensive Guide

  • by

The location package is an essential tool for Flutter developers needing to handle location services on Android, iOS, macOS, and web. It offers functionalities to request and manage location permissions, retrieve the device’s location, and get continuous updates as the location changes.

Getting Started

To begin, add the location package to your Flutter project’s pubspec.yaml file:

dependencies:
  location: ^7.0.0

Platform-Specific Configuration

Android

For Android, to enable location services in the background, you must use the enableBackgroundMode API and include necessary permissions in your AndroidManifest.xml file:

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>

Ensure that the user is informed about enabling these permissions, especially for Android 11 and above, where the "always allow" option must be manually enabled from the app settings.

iOS

For iOS, add the following keys to your Info.plist file:

<key>NSLocationWhenInUseUsageDescription</key>
<string>Your message here</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Your message here</string>
<key>UIBackgroundModes</key>
<array>
    <string>location</string>
</array>
macOS

For macOS, ensure the app is sandboxed and location services are enabled in Xcode:

  1. Click on your application target in the project navigator.
  2. Navigate to the "Capabilities" tab.
  3. Enable the "App Sandbox" and select "Location" under "App Data".

Add the following permissions to your Info.plist:

<key>NSLocationWhenInUseUsageDescription</key>
<string>Your message here</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Your message here</string>

Implementation

To use the location package, import it in your Dart code:

import 'package:location/location.dart';
Requesting Location

Here’s a basic example to request location services and permissions:

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();
Listening to Location Changes

To get continuous updates as the location changes, use the onLocationChanged stream:

location.onLocationChanged.listen((LocationData currentLocation) {
  // Use current location
});
Enabling Background Mode

To enable location updates when the app is in the background:

location.enableBackgroundMode(enable: true);

Advanced Usage

The location package also provides methods to manage permissions and location settings. Here’s a summary of the available methods:

  • requestPermission(): Requests location permission and returns a PermissionStatus.
  • hasPermission(): Checks the current permission status.
  • serviceEnabled(): Checks if location services are enabled.
  • requestService(): Prompts the user to enable location services.
  • changeSettings({LocationAccuracy accuracy, int interval, double distanceFilter}): Updates the settings for location requests.
  • getLocation(): Gets the current location of the device.
  • onLocationChanged: Provides a stream of location updates.
  • enableBackgroundMode({bool enable}): Enables or disables background location mode.

Example Project

Below is an example to showcase the usage of the location package:

import 'package:flutter/material.dart';
import 'package:location/location.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: LocationExample(),
    );
  }
}

class LocationExample extends StatefulWidget {
  @override
  _LocationExampleState createState() => _LocationExampleState();
}

class _LocationExampleState extends State<LocationExample> {
  Location location = Location();

  bool _serviceEnabled;
  PermissionStatus _permissionGranted;
  LocationData _locationData;

  @override
  void initState() {
    super.initState();
    initLocationService();
  }

  Future<void> initLocationService() async {
    _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();
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Location Example'),
      ),
      body: Center(
        child: _locationData == null
            ? CircularProgressIndicator()
            : Text('Location: ${_locationData.latitude}, ${_locationData.longitude}'),
      ),
    );
  }
}

Conclusion

The location package is a powerful tool for integrating location services into your Flutter application. With support for multiple platforms and a range of features, it can handle various use cases from simple location requests to continuous tracking in the background.

For more detailed information and advanced configurations, refer to the official documentation on pub.dev.

By mastering the location package, you can enhance your Flutter applications with robust location-based functionalities.

For more guides on using Flutter libraries, check out our other posts, such as Mastering Location Services in Flutter with the Geolocator Plugin.

Leave a Reply

Your email address will not be published. Required fields are marked *