Реализация фонового отслеживания геолокации в мобильном приложении
Мы сталкивались с проектами, где фоновый трекинг «съедал» заряд за 2 часа, а на Xiaomi приложение просто не получало координаты после перехода в фон. Обе проблемы — следствие неправильной архитектуры, а не самого факта фонового выполнения. В этой статье разберём, как мы строим надёжный трекинг с приемлемым расходом батареи на iOS и Android.
Проблемы фонового трекинга
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?
Три подхода — выбираем по задаче. Сравнение в таблице:
| Стратегия | Точность | Расход батареи | Работает в terminated | Применение |
|---|---|---|---|---|
| Standard Location Updates | Высокая (метр) | Высокий | Нет | Навигация в реальном времени |
| Significant Location Change | ~500 м | Низкий | Да | Трекинг доставки, не критичный к секундам |
| Visits Monitoring | На основе остановок | Минимальный | Да | Аналитика перемещений |
Для реального курьерского трекинга комбинируем: при активном приложении — 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 секунд на завершение текущей операции при переходе в фон — используем для отправки последних точек на сервер. Благодаря этой комбинации удаётся снизить расход трафика на 40% по сравнению с непрерывным трекингом.
Как настроить Android Foreground Service?
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 отправляет их при наличии сети. Такая архитектура экономит до 50% заряда по сравнению с постоянной отправкой данных.
Сравнение стратегий для Android
| Стратегия | Работает в Doze | Батарея | Надёжность |
|---|---|---|---|
| Foreground Service | Да | Средний | Высокая |
| JobScheduler | Нет (редкие окна) | Низкий | Низкая |
| Passive (AlarmManager) | Нет | Минимальный | Очень низкая |
Foreground Service — единственный вариант для продакшна. JobScheduler подходит только для разовых проверок, но не для непрерывного трекинга.
Flutter: два подхода
background_locator_2 — открытый пакет, использует platform-specific фоновые механизмы. Настройка через BackgroundLocator.registerLocationUpdate с LocationSettings. Работает через отдельный FlutterEngine в изолированном Dart-окружении. Однако на некоторых прошивках (MIUI) может отключаться без уведомления.
flutter_background_geolocation (Transistor Software, платный) — более надёжный вариант с готовой обработкой iOS/Android батарейных ограничений, геозонами, автоматическим включением/выключением трекинга по расписанию. Для продакшн-приложений с высокими требованиями к надёжности выбираем платный пакет — его стоимость компенсируется за первую неделю поддержки за счёт экономии на батарейных жалобах.
Что входит в работу
- Аудит текущей архитектуры трекинга (если проект не с нуля)
- Проектирование стратегии под конкретные сценарии использования
- Реализация на iOS (Swift), Android (Kotlin) или Flutter
- Обработка edge cases: переход в фон, убийство процесса, reboot, низкий заряд
- Интеграция с сервером (REST/GraphQL, буферизация, отправка)
- Тестирование на реальных устройствах: iPhone 12 против Xiaomi Mi 11, Samsung Galaxy
- Документация по архитектуре и деплой
Проконсультируйтесь с нашим инженером по вашему сценарию — мы поможем выбрать оптимальный стек и стратегию.
Сроки и стоимость
Срок реализации — от 4 до 8 дней. Стоимость рассчитывается индивидуально в зависимости от количества платформ, сложности интеграций и требований к точности. Мы работаем на рынке более 5 лет, реализовали свыше 20 проектов с фоновой геолокацией для логистики, фитнеса и социальных сетей. Закажите аудит текущей архитектуры трекинга — напишите нам, чтобы обсудить детали.
Тестирование фонового трекинга
Самый частый баг — работает на дев-устройстве, не работает у части пользователей. Причина: тест-устройство не в Doze Mode, у разработчика нет MIUI. Чеклист для проверки:
- Тест с выключенным экраном на 30+ минут
- Тест с «Оптимизацией батареи» включённой
- Тест на Xiaomi с MIUI 12+, Samsung с One UI 4+
- Тест при переходе в авиарежим и обратно
- Проверка, что сервис перезапускается после reboot
Дополнительные материалы: Background Location Updates на iOS, Foreground Services на Android.







