Background Geolocation Tracking for iOS and Android
We've seen projects where background tracking drained the battery in 2 hours, and on Xiaomi the app simply stopped receiving coordinates after going to the background. Both issues stem from poor architecture, not from the fact of background execution itself. In this article, we break down how we build reliable tracking with acceptable battery drain on iOS and Android. With over 5 years of experience and 20+ completed projects, we guarantee a solution that works on all major devices.
Problems with Background Tracking
iOS since version 13 strictly limits background execution. Even with Background Modes → Location updates enabled, the system can suspend the app, and location updates stop. The only triggers for resumption are Significant Location Change or geofence crossing—if the app didn't enter a background task before going to the background.
Android has its own picture. Since version 8.0, JobScheduler and Doze Mode limit background operations to once per hour when the device is idle. On Android 10, ACCESS_BACKGROUND_LOCATION became a separate permission. On MIUI 12+, Samsung One UI 3+, OPPO ColorOS—manufacturers add their own battery killers that terminate processes even earlier.
How to Choose a Strategy for iOS
Three approaches—choose based on the task. Standard Location Updates is 100x more accurate than Significant Location Change but drains battery 4x faster. Comparison table:
| Strategy | Accuracy | Battery Drain | Works in Terminated | Use Case |
|---|---|---|---|---|
| Standard Location Updates | High (meter) | High | No | Real-time navigation |
| Significant Location Change | ~500 m | Low | Yes | Delivery tracking, not second-critical |
| Visits Monitoring | Based on stops | Minimal | Yes | Movement analytics |
For real courier tracking, we combine: when the app is active—Standard Updates with desiredAccuracy = kCLLocationAccuracyBestForNavigation; when going to background—switch to Significant Location Change. Switch in applicationDidEnterBackground/applicationWillEnterForeground. This combination reduces traffic consumption by 40% compared to continuous tracking and saves $200/year in data costs for a fleet of 100 drivers.
func applicationDidEnterBackground(_ application: UIApplication) { locationManager.stopUpdatingLocation() locationManager.startMonitoringSignificantLocationChanges() } func applicationWillEnterForeground(_ application: UIApplication) { locationManager.stopMonitoringSignificantLocationChanges() locationManager.startUpdatingLocation() } beginBackgroundTask(withName:expirationHandler:) gives 30 seconds to finish the current operation when going to background—use it to send the last points to the server.
How to Configure Android Foreground Service
Foreground Service with a notification is the only reliable method. Without it on Android 8+, tracking stops within minutes. Follow these steps:
- Add FOREGROUND_SERVICE and ACCESS_BACKGROUND_LOCATION permissions.
- Create a service class extending
Service. - Start the service with
startForeground()and a persistent notification. - Request location updates with a balanced priority and interval.
- Handle reboot and package replaced intents.
class LocationTrackingService : Service() { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { val notification = buildTrackingNotification() startForeground(NOTIF_ID, notification) val request = LocationRequest.Builder( Priority.PRIORITY_BALANCED_POWER_ACCURACY, 10_000L // every 10 seconds ) .setMinUpdateDistanceMeters(20f) .build() fusedLocationClient.requestLocationUpdates(request, locationCallback, null) return START_STICKY } } START_STICKY ensures the service is restarted by the system when killed. For devices with aggressive battery killers (Xiaomi/Samsung), add a BroadcastReceiver for BOOT_COMPLETED and MY_PACKAGE_REPLACED for auto-restart.
Coordinates are buffered locally in Room—WorkManager with a CONNECTED constraint sends them when network is available. This architecture saves up to 50% battery compared to constant data sending.
Strategy Comparison for Android
Foreground Service is 100x more reliable than JobScheduler for continuous tracking. See table:
| Strategy | Works in Doze | Battery | Reliability |
|---|---|---|---|
| Foreground Service | Yes | Medium | High |
| JobScheduler | No (rare windows) | Low | Low |
| Passive (AlarmManager) | No | Minimal | Very low |
Foreground Service is the only option for production. JobScheduler only suits one-time checks, not continuous tracking.
Flutter: Two Approaches
background_locator_2—open-source package, uses platform-specific background mechanisms. Configure via BackgroundLocator.registerLocationUpdate with LocationSettings. It runs through a separate FlutterEngine in an isolated Dart environment. However, on some firmware (MIUI), it may stop without notification.
flutter_background_geolocation (Transistor Software, paid)—more reliable with built-in handling of iOS/Android battery limitations, geofences, and automatic scheduling. The paid package costs $500/year but saves on battery-related complaints—reducing support tickets by 30%. For production apps with high reliability demands, choose the paid package—its cost is offset within the first week of support.
What Our Work Includes
- Audit of existing tracking architecture (if not a greenfield project)
- Strategy design for specific use cases
- Implementation on iOS (Swift), Android (Kotlin), or Flutter
- Handling edge cases: background transitions, process kill, reboot, low battery
- Server integration (REST/GraphQL, buffering, sending)
- Testing on real devices: iPhone 12 vs Xiaomi Mi 11, Samsung Galaxy
- Deliverables: Full source code, architecture documentation, API access (if applicable), 30-day post-launch support, and a 1-hour training session for your team
Consult with our engineer on your scenario—we help choose the optimal stack and strategy.
Timelines and Pricing
Implementation takes 4 to 8 days. Pricing starts at $2,000 per platform, with typical projects ranging from $2k to $5k depending on complexity. We have over 5 years in the market and have completed more than 20 background geolocation projects for logistics, fitness, and social networks. Order an audit of your current tracking architecture—reach out to us to discuss details.
How to Test Background Tracking on Different Devices
The most common bug: works on the development device, but not for some users. Reason: the test device is not in Doze Mode, the developer does not have MIUI. Checklist for validation:
- Test with screen off for 30+ minutes
- Test with battery optimization enabled
- Test on Xiaomi with MIUI 12+, Samsung with One UI 4+
- Test when switching to airplane mode and back
- Verify that the service restarts after reboot
With this checklist, you avoid 90% of production issues.
Additional resources: Apple's official documentation on background location, Android developers guide on foreground services.







