Реалізація фонового відслідження геолокації у мобільному додатку
Фонове відслідження — це те місце, де більшість команд отримує перші скарги від користувачів: «убивает батарею» або «перестає працювати через годину». Обидва симптоми — наслідок неправильного вибору стратегії, а не самого факту фонового трекинга.
Чому це складніше, ніж здається
iOS з версії 13 жорстко обмежує фонове виконання. Навіть з включеним Background Modes → Location updates система може призупинити додаток у режимі «suspended», і обновлення геолокації перестануть поступати. Тригером для відновлення служить тільки значне перемішення (Significant Location Change) або перетин геозони — якщо додаток не встиг увійти в «background task» до переходу в фон.
Android — своя картина. З версії 8.0 JobScheduler і Doze Mode обмежують фонові операції до одного разу на годину при «неактивній» зарядці. На Android 10 з'явилось ACCESS_BACKGROUND_LOCATION як окреме дозвіл. На MIUI 12+, Samsung One UI 3+, OPPO ColorOS — ще й виробники додають власні battery killers, які убивають процес раніше систематично.
Правильна архітектура для iOS
Три стратегії — обираємо за задачею:
1. Standard Location Updates — точні обновлення кожні N метрів. Потрібен Foreground Service (фактично — додаток повинен бути активним) або capability Background Location. Точність висока, розхід батареї високий. Підходить для активного навігатора.
2. Significant Location Change Monitoring — startMonitoringSignificantLocationChanges(). Обновлення при перемішенні на ~500 метрів або зміні вишки. Дуже економічний. Працює навіть при «terminated» стані — система запускає додаток у фоні. Підходить для трекинга доставки без вимоги до точності кожної секунди.
3. Visits Monitoring — startMonitoringVisits(). Визначає прибуття/відправління на основі аналізу зупинок. Мінімальний розхід батареї. Для аналітики переміщень, а не навігації.
Для реального курьерського трекинга комбінуємо: при активному додатку — Standard Updates з desiredAccuracy = kCLLocationAccuracyBestForNavigation, при уходе в фон — переключаємся на Significant Location Change. Переключення в applicationDidEnterBackground / applicationWillEnterForeground.
func applicationDidEnterBackground(_ application: UIApplication) {
locationManager.stopUpdatingLocation()
locationManager.startMonitoringSignificantLocationChanges()
}
func applicationWillEnterForeground(_ application: UIApplication) {
locationManager.stopMonitoringSignificantLocationChanges()
locationManager.startUpdatingLocation()
}
beginBackgroundTask(withName:expirationHandler:) дає 30 секунд на завершення поточної операції при переході в фон — використовуємо для відправки останніх точок на сервер.
Правильна архітектура для Android
Foreground Service з повідомленням — єдиний надійний спосіб. Без нього на Android 8+ трекинг зупиниться протягом кількох хвилин.
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 // кожні 10 секунд
)
.setMinUpdateDistanceMeters(20f)
.build()
fusedLocationClient.requestLocationUpdates(request, locationCallback, null)
return START_STICKY
}
}
START_STICKY гарантує перезапуск сервісу системою при убивстві. Для пристроїв з агресивним battery killer (Xiaomi/Samsung) додаємо BroadcastReceiver на BOOT_COMPLETED і MY_PACKAGE_REPLACED для автостарту.
Координати буферизуємо в Room локально — WorkManager з CONNECTED constraint відправляє їх при наявності мережі.
Flutter: два підходи
background_locator_2 — відкритий пакет, використовує platform-specific фонові механізми. Налаштування через BackgroundLocator.registerLocationUpdate з LocationSettings. Працює через окремий FlutterEngine в ізольованому Dart-оточенні.
flutter_background_geolocation (Transistor Software, платний) — більш надійний варіант з готовою обробкою iOS/Android батарейних обмежень, геозонами, автоматичним включенням/вимиканням трекинга за розписанням.
Для продакшн-додатків з вимогами до надійності обираємо платний пакет — $120 за ліцензію окуповуються за першу тиждень підтримки.
Тестування фонового трекинга
Найчастіший баг — працює на дев-пристрої, не працює у частини користувачів. Причина: тест-пристрій не в Doze Mode, у розробника немає MIUI. Чеклист для перевірки:
- Тест з вимкненим екраном на 30+ хвилин
- Тест з «Оптимізацією батареї» включеною
- Тест на Xiaomi з MIUI 12+, Samsung з One UI 4+
- Тест при переході в авіарежим і назад
- Перевірка, що сервіс перезапускається після reboot
Строк реалізації: чотири-вісім днів — архітектура, реалізація на потрібних платформах, обробка edge cases, тестування на реальних пристроях з різними прошивками.







