Logo Dark

Flutter Location Tracking After Termination: How to Guide

19 June 2025

Developer Insights

Table of contents

Have you built a location-based Flutter app for delivery tracking, fitness, or a field team? If so, you may have encountered an issue where your app stops tracking location when the app is closed or terminated. 

Most location plugins, like geolocator or location, work just fine while the app is open or running in the background. But as soon as the app is terminated (either by the user or the OS), tracking just... stops. And that’s a dealbreaker for a lot of real-world use cases. 

That’s where the Flutter background geolocation plugin from Transistor Software comes in. It enables your app to continue tracking the user’s location even when it’s terminated, force-closed, or after a device reboot.  

In this guide, I’ll walk you through the process of setting it all up in Flutter location tracking. If you want your app to track reliably no matter what, you're in the right place.

Why Flutter Background Geolocation?

If you’ve worked with geolocator, location, or similar packages, you’ll know they’re easy to use but come with a major limitation: they don’t support tracking once the app is force-closed. It's great for building mobile apps quickly, thanks to its Flutter widgets that enable a reactive UI. For apps like delivery or fitness trackers where tracking must continue 24/7, that’s a dealbreaker.

flutter_background_geolocation goes beyond just foreground and background tracking. It supports a headless mode, which means it can continue to respond to location updates even after the app is killed or the phone is rebooted. 

This is possible thanks to native platform integration and clever use of lifecycle hooks behind the scenes.

Key Features of flutter_background_geolocation

  • Reliable tracking even after app termination and device reboots
  • Works seamlessly on both Android and iOS
  • Highly customizable (distance filters, intervals, accuracy levels)
  • Battery-efficient with motion detection and stop detection
  • Built-in support for sending location data to your server via HTTP
  • Supports geofencing and user activity detection (e.g., walking, stationary, moving)

How To Track Your Location In A Flutter App

Learn how to easily set up Flutter location tracking in a terminated state to get real-time location updates in your app, even when the app is in the background.

Prerequisites

There are different Flutter packages available that do the heavy lifting for us. The two most advanced ones are location and geolocator. Before integrating this plugin into your Flutter project, ensure you meet the following prerequisites:

  • Flutter SDK installed with a working environment for both Android and iOS development.
  • Access to physical devices for testing (background tracking is limited on emulators).
  • An optional backend server endpoint if you want to sync location data.

Plugin Installation

Add the dependency in pubspec.yaml

Dependencies:
flutter_background_geolocation: ^4.13.1 # check for latest version

Platform Configuration

Android Setup

  • Update your android/app/build.gradle:
defaultConfig {
   applicationId "com.example.app"
   minSdkVersion 21
   targetSdkVersion 33
}
  • Add these permissions in AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
  • Inside the tag:
<service android:name="com.transistorsoft.flutter.backgroundgeolocation.HeadlessTask" android:exported="true"/>

iOS Setup

  • Add required keys in Info.plist:
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>We use your location to track your movement</string>
<key>UIBackgroundModes</key>
<array>
   <string>location</string>
   <string>fetch</string>
</array>

Enable background modes in Xcode:

  • Open the project in Xcode
  • Go to “Signing & Capabilities” > “+ Capability”
  • Add Background Modes
  • Enable Location Updates

Initialization & Configuration

import 'package:flutter_background_geolocation/flutter_background_geolocation.dart' as bg;

void main() {
  runApp(MyApp());
  // Register Headless Task
  bg.BackgroundGeolocation.registerHeadlessTask(backgroundGeolocationHeadlessTask);
}

App Initialization

Below is a complete example of setting up the plugin with proper configuration:

@override
void initState() {
  super.initState();
  // Listen for location updates
  bg.BackgroundGeolocation.onLocation((bg.Location location) {
    print('[location] - $location');
  });
  // Fired whenever the plugin changes motion-state (stationary <-> moving)
  bg.BackgroundGeolocation.onMotionChange((bg.Location location) {
    print('[motionchange] - $location');
  });
  // Fired whenever the state of location services changes. Always fired at boot.
  bg.BackgroundGeolocation.onProviderChange((bg.ProviderChangeEvent event) {
    print('[providerchange] - $event');
  });
  // Fired when user activity (walking, running, still, etc.) changes
  bg.BackgroundGeolocation.onActivityChange((bg.ActivityChangeEvent event) {
    print('[onActivityChange] - $event');
  });
  // Fired when network connectivity changes
  bg.BackgroundGeolocation.onConnectivityChange((bg.ConnectivityChangeEvent event) async {
 if (event.connected) {
      await bg.BackgroundGeolocation.locations;
    }
  });
  // Fired on HTTP success/failure when using the `url` config
  bg.BackgroundGeolocation.onHttp((bg.HttpEvent event) {
    debugPrint('[${bg.Event.HTTP}] - $event');
  });
  // Fired when plugin requires re-authorization
  bg.BackgroundGeolocation.onAuthorization((bg.AuthorizationEvent event) {
    debugPrint('[${bg.Event.AUTHORIZATION}] = $event');
  });
  // Ready the plugin
  bg.BackgroundGeolocation.ready(bg.Config(
    desiredAccuracy: bg.Config.DESIRED_ACCURACY_HIGH,
    distanceFilter: 50.0,
    stopOnTerminate: false, // VERY IMPORTANT
    startOnBoot: true,      // VERY IMPORTANT
    debug: true,
    logLevel: bg.Config.LOG_LEVEL_VERBOSE,
  )).then((bg.State state) {
    if (!state.enabled) {
      bg.BackgroundGeolocation.start();
    }
  });
}
@override
Widget build(BuildContext context) {
  return MaterialApp(
    home: Scaffold(
      appBar: AppBar(title: const Text('Location Tracker')),
      body: const Center(child: Text('Tracking location...')),
    ),
  );
}

Headless Task for Terminated State

To handle location updates when the app is killed or removed from the recent apps list, implement a headless task:

void backgroundGeolocationHeadlessTask(bg.HeadlessEvent headlessEvent) async {
 switch(headlessEvent.name) {
   case bg.Event.LOCATION:
     bg.Location location = headlessEvent.event;
     print('[Headless] location: ${location.toString()}');
     // Save to local storage or send to API
     break;
 }
}

Key Configs for Terminated Tracking

Config Key Value Description stopOnTerminate false Keep tracking after app is killed startOnBoot true Resume tracking on device reboot

Sending Data to an API

If you want to send location updates to your backend, configure the plugin with HTTP sync:

bg.BackgroundGeolocation.ready(bg.Config(
 url: 'https://your-api.com/locations',
 headers: {
   'Authorization': 'Bearer your_token',
 },
 httpRootProperty: 'data',
 autoSync: true,
 batchSync: true,
 maxBatchSize: 50,
));

The plugin will automatically send location updates to your server in the background.

Testing Your Implementation

To validate your setup:

  • Run the app on a physical device.
  • Grant all necessary location permissions.
  • Move around with the device.
  • Kill the app from the recent apps screen.
  • Observe logs via adb logcat (Android) or Xcode console (iOS).

You should see output similar to:

[Headless] location:

*Note that emulators may not simulate background and headless tasks reliably.

Tips and Best Practices for Reliable Tracking

When implementing Flutter location tracking in terminated state, consider the following:

  • On iOS, background execution is subject to strict operating system constraints. Use motion-based tracking and avoid unnecessary location updates to conserve battery.
  • Always inform users why you are collecting their location.  It ensures your app complies with privacy guidelines and platform policies.
  • Regularly test behavior on real devices and across OS versions.

Conclusion

Implementing Flutter location tracking in terminated state ensures that your app can provide continuous location updates, even when the app is terminated, force-closed, or the device is rebooted. When you ask yourself, Why Flutter, it’s simple. The plugin provides fine-grained control, native integrations, and a simple API to work with both Android and iOS.

Use it to build robust features like delivery tracking, field workforce apps, outdoor activity logging, and more. As always, be transparent with users and optimize battery usage through smart configuration.

WRITTEN BY

Urvashi Kharecha

Lead Software Engineer at 7Span Developed 25+ apps from scratch to deployment, across various domains. Passionate about solving complex problems and adopting the latest technologies. Committed to delivering efficient, scalable, and maintainable solutions. Interested in open-source contributions, especially within the Flutter community.

More from this author

Making IT Possible

Making IT Possible

Making IT Possible

Making IT Possible

Making IT Possible

Making IT Possible

India (HQ)

201, iSquare Corporate Park, Science City Road, Ahmedabad-380060, Gujarat, India

Canada

24 Merlot Court, Timberlea, NS B3T 0C2, Canada

For Sales

[email protected]

Looking For Jobs

Apply Now

LinkedIn
Instagram
X
Facebook
Youtube
Discord
Dribbble
Behance
Github