Skip to Content
Миграция с ВБР

🚀 Руководство по миграции: flutter_background_geolocation → Tracelet

Переходите с flutter_background_geolocation на Tracelet? Отличный выбор! Tracelet — это альтернатива с полностью открытым исходным кодом (Apache 2.0) с совместимым API 1:1, а также такими дополнительными функциями, как фильтрация Калмана, обнаружение макетов, зоны конфиденциальности и многое другое. Никаких лицензионных ключей, никаких проприетарных SDK, полный исходный код.

💡 Это руководство всегда отражает текущую версию.


⚡ Трехступенчатый скоростной бег

Серьезно, это так быстро.

Шаг 1. Поменяйте зависимости:

# Before dependencies: flutter_background_geolocation: ^5.x.x

После ✨

dependencies: tracelet: ^3.6.14

Шаг 2. Обновите импорт:

// Before import 'package:flutter_background_geolocation/flutter_background_geolocation.dart' as bg; // After — short & sweet ✅ import 'package:tracelet/tracelet.dart' as tl;

Шаг 3. Найдите и замените имя класса:

// Before bg.BackgroundGeolocation.ready(bg.Config(...)); // After tl.Tracelet.ready(tl.Config.balanced().copyWith(...));

Вот и все. Каждый метод, каждое событие, каждый обратный вызов — совместимость 1:1. Остальная часть этого руководства представляет собой просто шпаргалку для подробностей.


🏗️ Конфигурация: от плоской к структурированной

Предыдущий плагин использует один простой Config() со всеми полями на одном уровне. Tracelet организует их в логические разделы, что значительно упрощает чтение и обслуживание больших конфигураций.

// Before — flat config bg.Config( desiredAccuracy: bg.Config.DESIRED_ACCURACY_HIGH, distanceFilter: 10.0, stopOnTerminate: false, startOnBoot: true, stopTimeout: 5, url: 'https://api.example.com/locations', batchSync: true, autoSync: true, headers: {'Authorization': 'Bearer $token'}, heartbeatInterval: 60, notification: bg.Notification(title: 'Tracking', text: 'Active'), debug: true, logLevel: bg.Config.LOG_LEVEL_VERBOSE, ); // After — organized by section 🏠 tl.Config( geo: tl.GeoConfig( desiredAccuracy: tl.DesiredAccuracy.high, // typed enums! distanceFilter: 10.0, ), app: tl.AppConfig( stopOnTerminate: false, startOnBoot: true, heartbeatInterval: 60, ), android: tl.AndroidConfig( foregroundService: tl.ForegroundServiceConfig( notificationTitle: 'Tracking', notificationText: 'Active', ), ), motion: tl.MotionConfig( stopTimeout: 5, ), http: tl.HttpConfig( url: 'https://api.example.com/locations', batchSync: true, autoSync: true, headers: {'Authorization': 'Bearer $token'}, ), logger: tl.LoggerConfig( debug: true, logLevel: tl.LogLevel.verbose, // readable enum instead of int constants ), );

Краткий обзор разделов конфигурации:

  • geoGeoConfig — Точность, фильтр расстояния, эластичность, периодический режим, фильтр Калмана, ложное обнаружение
  • appAppConfig — Жизненный цикл, контрольный сигнал, расписание
  • androidAndroidConfig — 🆕 Только для Android: уведомление службы переднего плана, интервалы обновления местоположения, AlarmManager, периодические стратегии
  • iosIosConfig — 🆕 Только для iOS: тип активности, фоновые сеансы, предотвращение приостановки
  • motionMotionConfig — Тайм-аут остановки, распознавание активности, режим только акселерометра
  • httpHttpConfig — синхронизация URL-адреса, заголовков, пакетной обработки, отсрочки повторных попыток, режима только Wi-Fi.
  • loggerLoggerConfig — Уровень журнала, максимальное количество дней, звуки отладки.
  • geofenceGeofenceConfig — Радиус близости, начальный триггер, режим выбивания
  • persistencePersistenceConfig — Режим сохранения, максимальное количество дней/записей, шаблоны
  • auditAuditConfig — 🆕 хеш-цепочка SHA-256 — потому что защита от несанкционированного доступа имеет значение
  • privacyZonePrivacyZoneConfig — 🆕 Движок зоны конфиденциальности — лучший друг GDPR
  • securitySecurityConfig — 🆕 Шифрование базы данных при хранении (encryptDatabase)
  • attestationAttestationConfig — 🆕 Аттестация устройства/проверка целостности

🗺️ Шпаргалка по большой конфигурации

Не волнуйтесь, каждое поле имеет сопоставление 1:1. Вот ваш Розеттский камень.

Местоположение и отслеживание → GeoConfig

Before → Tracelet ───────────────────────────────────────────────────────────── desiredAccuracy (int: -2…100) → geo.desiredAccuracy (DesiredAccuracy enum) .high / .medium / .low / .veryLow / .passive distanceFilter → geo.distanceFilter (default 10m) stationaryRadius → geo.stationaryRadius (default 25m) locationTimeout → geo.locationTimeout (default 60s) disableElasticity → geo.disableElasticity elasticityMultiplier → geo.elasticityMultiplier (default 1.0) stopAfterElapsedMinutes → geo.stopAfterElapsedMinutes (-1 = disabled) enableTimestampMeta → geo.enableTimestampMeta maxMonitoredGeofences → geo.maxMonitoredGeofences (-1 = platform default)

Поля, специфичные для Android → AndroidConfig:

Before → Tracelet ───────────────────────────────────────────────────────────── locationUpdateInterval → android.locationUpdateInterval (1000ms) fastestLocationUpdateInterval → android.fastestLocationUpdateInterval (500ms) deferTime → android.deferTime allowIdenticalLocations → android.allowIdenticalLocations geofenceModeHighAccuracy → geofence.geofenceModeHighAccuracy (cross-platform; android.* is deprecated) scheduleUseAlarmManager → android.scheduleUseAlarmManager

Поля, специфичные для iOS → IosConfig:

Before → Tracelet ───────────────────────────────────────────────────────────── activityType → ios.activityType (LocationActivityType enum) useSignificantChangesOnly → ios.useSignificantChangesOnly showsBackgroundLocationIndicator → ios.showsBackgroundLocationIndicator pausesLocationUpdatesAutomatically → ios.pausesLocationUpdatesAutomatically locationAuthorizationRequest → ios.locationAuthorizationRequest disableLocationAuthorizationAlert → ios.disableLocationAuthorizationAlert preventSuspend → ios.preventSuspend

🆕 Эксклюзивные поля GeoConfig для Tracelet:

  • geo.enableAdaptiveMode — Адаптирует фильтр расстояния по активности + заряду батареи + скорости.
  • geo.periodicLocationInterval — 900 по умолчанию (15 минут).
  • geo.periodicDesiredAccuracy.medium по умолчанию
  • geo.filter (LocationFilter) — Калман, ложное обнаружение, пороги точности

🧹 Фильтр местоположения → LocationFilter (эксклюзивно для Tracelet!)

  • 🆕 filter.policyLocationFilterPolicy.adjust / .ignore / .discard
  • 🆕 filter.useKalmanFilter — расширенный фильтр Калмана с 4 состояниями — профессионально сглаживайте шум GPS
  • 🆕 filter.mockDetectionLevel.disabled / .basic / .heuristic — поймайте поддельные местоположения
  • 🆕 filter.rejectMockLocations — Автоматическое отклонение макетов местоположений.
  • 🆕 filter.maxImpliedSpeed — Фильтр спайков — «нет, пользователь НЕ телепортировался»
  • 🆕 filter.trackingAccuracyThreshold — минимальная точность принятия
  • 🆕 filter.odometerAccuracyThreshold — Минимальная точность обновлений одометра.

Обнаружение движения → MotionConfig

Before → Tracelet ───────────────────────────────────────────────────────────── stopTimeout → motion.stopTimeout (default 5 min) motionTriggerDelay → motion.motionTriggerDelay disableMotionActivityUpdates → motion.disableMotionActivityUpdates (set true for accelerometer-only, no permission!) isMoving → motion.isMoving (initial state) activityRecognitionInterval → motion.activityRecognitionInterval (10000ms) minimumActivityRecognitionConfidence → motion.minimumActivityRecognitionConfidence (75) disableStopDetection → motion.disableStopDetection stopDetectionDelay → motion.stopDetectionDelay stopOnStationary → motion.stopOnStationary triggerActivities → motion.activityTypes (Set<ActivityType>)

🆕 Эксклюзивные поля Tracelet MotionConfig:

  • motion.motionDetectionMode.accelerometer / .speed / .smart — способ определения движения (умный = акселерометр и скорость GPS; рекомендуется)
  • motion.shakeThreshold — Настройка только акселерометра (по умолчанию 2.5)
  • motion.stillThreshold — Настройка только акселерометра (по умолчанию 0,4)
  • motion.stillSampleCount — Настройка только акселерометра (по умолчанию 25)
  • motion.speedMovingThreshold / motion.speedStationaryDelay / motion.speedWakeConfirmCount — настройка скоростного режима (используется .speed / .smart)
  • motion.stationaryTrackingMode / motion.stationaryPeriodicInterval / motion.stationaryPeriodicAccuracy — что делать после остановки (периодические исправления или геозоны)

Приложение → AppConfig

Before → Tracelet ───────────────────────────────────────────────────────────── stopOnTerminate → app.stopOnTerminate (default true) startOnBoot → app.startOnBoot (default false) heartbeatInterval → app.heartbeatInterval (default 60s) schedule → app.schedule (cron-like expressions)

Примечание: scheduleUseAlarmManagerandroid.scheduleUseAlarmManager | preventSuspendios.preventSuspend

🔔 Уведомление службы переднего плана → AndroidConfig.foregroundService

Важно (изменение 2.x.x): Уведомление службы переднего плана теперь настроено как android.foregroundService (AndroidConfig), а не как app. Это концепция только для Android.

Before (Notification) → Tracelet (AndroidConfig.foregroundService) ───────────────────────────────────────────────────────────── title → android.foregroundService.notificationTitle text → android.foregroundService.notificationText color → android.foregroundService.notificationColor smallIcon → android.foregroundService.notificationSmallIcon largeIcon → android.foregroundService.notificationLargeIcon priority → android.foregroundService.notificationPriority channelName → android.foregroundService.channelName channelId → android.foregroundService.channelId sticky → android.foregroundService.notificationOngoing actions → android.foregroundService.actions enabled → android.foregroundService.enabled

HTTP-синхронизация → HttpConfig

Before → Tracelet ───────────────────────────────────────────────────────────── url → http.url (null = sync disabled) method → http.method (HttpMethod.post / .put) headers → http.headers httpRootProperty → http.httpRootProperty (default 'location') batchSync → http.batchSync maxBatchSize → http.maxBatchSize autoSync → http.autoSync autoSyncThreshold → http.autoSyncThreshold httpTimeout → http.httpTimeout (default 60000ms) params → http.params extras → http.extras locationsOrderDirection → http.locationsOrderDirection (LocationOrder enum)

🆕Поля HttpConfig, эксклюзивные для Tracelet:

  • http.disableAutoSyncOnCellular — синхронизация только через Wi-Fi — сохраните этот тарифный план!
  • http.maxRetries — значение по умолчанию 10, с экспоненциальной задержкой + джиттером.
  • http.retryBackoffBase — по умолчанию 1000 мс.
  • http.retryBackoffCap — по умолчанию 300000 мс (5 минут).

Геозенс → GeofenceConfig

Before → Tracelet ───────────────────────────────────────────────────────────── geofenceProximityRadius → geofence.geofenceProximityRadius (default 1000m) geofenceInitialTriggerEntry → geofence.geofenceInitialTriggerEntry (default true)
  • 🆕 geofence.geofenceModeKnockOut — Автоматическое удаление геозоны после первого ВЫХОДА — раз и готово!

Постоянство → PersistenceConfig

Before → Tracelet ───────────────────────────────────────────────────────────── persistMode → persistence.persistMode (.all / .location / .geofence / .none) maxDaysToPersist → persistence.maxDaysToPersist (-1 = forever) maxRecordsToPersist → persistence.maxRecordsToPersist (-1 = unlimited) locationTemplate → persistence.locationTemplate (Mustache-style) geofenceTemplate → persistence.geofenceTemplate (Mustache-style) disableProviderChangeRecord → persistence.disableProviderChangeRecord extras → persistence.extras

Ведение журнала → LoggerConfig

Before → Tracelet ───────────────────────────────────────────────────────────── logLevel (int const) → logger.logLevel (.verbose / .debug / .info / .warning / .error) logMaxDays → logger.logMaxDays (default 3) debug → logger.debug (alert sounds — fun at demos, terrifying at 3 AM)

🔐 Audit Trail → AuditConfig (эксклюзивно для Tracelet)

  • audit.enabledfalse по умолчанию. Хеш-цепочка SHA-256 в каждом месте — тампер = разрушен
  • audit.hashAlgorithm — NOTTRANS1LATE
  • audit.includeExtrasInHashfalse по умолчанию

🛡️ Зоны конфиденциальности → PrivacyZoneConfig (эксклюзивно для Tracelet)

  • privacyZone.enabledfalse по умолчанию. Включите механизм зоны конфиденциальности.

🎯 Константы точности — типизированные перечисления!

Before (int constants) → Tracelet (typed enum) ───────────────────────────────────────────────────────────── Config.DESIRED_ACCURACY_NAVIGATION → DesiredAccuracy.high Config.DESIRED_ACCURACY_HIGH → DesiredAccuracy.high Config.DESIRED_ACCURACY_MEDIUM → DesiredAccuracy.medium Config.DESIRED_ACCURACY_LOW → DesiredAccuracy.low Config.DESIRED_ACCURACY_VERY_LOW → DesiredAccuracy.veryLow Config.DESIRED_ACCURACY_LOWEST → DesiredAccuracy.passive

📡 Мероприятия — те же имена, меньше ввода

Все 14 потоков событий отображаются в соотношении 1:1. Просто поменяйте префикс:

Before → Tracelet Callback Type ───────────────────────────────────────────────────────────────────────── onLocation(cb) → onLocation(cb) Location onMotionChange(cb) → onMotionChange(cb) Location onActivityChange(cb) → onActivityChange(cb) ActivityChangeEvent onProviderChange(cb) → onProviderChange(cb) ProviderChangeEvent onGeofence(cb) → onGeofence(cb) GeofenceEvent onGeofencesChange(cb) → onGeofencesChange(cb) GeofencesChangeEvent onHeartbeat(cb) → onHeartbeat(cb) HeartbeatEvent onHttp(cb) → onHttp(cb) HttpEvent onSchedule(cb) → onSchedule(cb) State onPowerSaveChange(cb) → onPowerSaveChange(cb) bool onConnectivityChange(cb) → onConnectivityChange(cb) ConnectivityChangeEvent onEnabledChange(cb) → onEnabledChange(cb) bool onNotificationAction(cb) → onNotificationAction(cb) String onAuthorization(cb) → onAuthorization(cb) AuthorizationEvent N/A → 🆕 onTrip(cb) TripEvent (auto-detected trips!) N/A → 🆕 onRemoteConfig(cb) Config (remote config applied) removeListeners() → removeListeners() Cancels all subscriptions
// Before — so many characters... bg.BackgroundGeolocation.onLocation((bg.Location location) { print('[location] $location'); }); // After — ahh, much better tl.Tracelet.onLocation((tl.Location location) { print('[location] $location'); });

🔧 Методы — полное сопоставление

Жизненный цикл

Before → Tracelet ───────────────────────────────────────────────────────────── bg.BackgroundGeolocation.ready(cfg) → tl.Tracelet.ready(cfg) bg.BackgroundGeolocation.start() → tl.Tracelet.start() bg.BackgroundGeolocation.stop() → tl.Tracelet.stop() bg.BackgroundGeolocation.startGeofences() → tl.Tracelet.startGeofences() N/A → 🆕 tl.Tracelet.startPeriodic() bg.BackgroundGeolocation.getState() → tl.Tracelet.getState() bg.BackgroundGeolocation.setConfig() → tl.Tracelet.setConfig() bg.BackgroundGeolocation.reset() → tl.Tracelet.reset() N/A → 🆕 tl.Tracelet.getHealth()

Расположение

Before → Tracelet ───────────────────────────────────────────────────────────── getCurrentPosition(...) → getCurrentPosition(...) same params: desiredAccuracy, timeout, maximumAge, persist, samples, extras N/A → 🆕 getLastKnownLocation() — zero battery cost! watchPosition(cb, ...) → watchPosition(cb, ...) — returns watchId stopWatchPosition(id) → stopWatchPosition(id) changePace(isMoving) → changePace(isMoving) N/A → 🆕 updateLocationProviderOptions() — live accuracy/filter override, no pipeline restart getOdometer() → getOdometer() setOdometer(value) → setOdometer(value) resetOdometer() → setOdometer(0) — one less method to remember

Геофенсинг

Before → Tracelet ───────────────────────────────────────────────────────────── addGeofence(g) → addGeofence(g) addGeofences(list) → addGeofences(list) removeGeofence(id) → removeGeofence(id) removeGeofences() → removeGeofences() getGeofences() → getGeofences() N/A → 🆕 getGeofence(id) — get one without fetching all N/A → 🆕 geofenceExists(id) — quick existence check

Постоянство и синхронизация

Before → Tracelet ───────────────────────────────────────────────────────────── getLocations() → getLocations([SQLQuery?]) — optional filtering! getCount() → getCount() destroyLocations() → destroyLocations() destroyLocation(uuid) → destroyLocation(uuid) insertLocation(params) → insertLocation(params) — returns UUID sync() → sync()

Разрешения — у нас есть помощники на несколько дней

Before → Tracelet ───────────────────────────────────────────────────────────── requestPermission() → requestLocationAuthorization() N/A → 🆕 getLocationAuthorization() N/A → 🆕 hasBackgroundPermission (getter) N/A → 🆕 getNotificationAuthorization() N/A → 🆕 requestNotificationAuthorization() N/A → 🆕 getMotionAuthorization() N/A → 🆕 requestMotionAuthorization() N/A → 🆕 requestTemporaryFullAccuracyAuthorization(purpose) — iOS 14+ N/A → 🆕 canScheduleExactAlarms() — Android 12+ N/A → 🆕 openExactAlarmSettings() N/A → 🆕 openAppSettings() N/A → 🆕 openLocationSettings() N/A → 🆕 openBatterySettings() N/A → 🆕 isIgnoringBatteryOptimizations()

Ведение журнала

Before → Tracelet ───────────────────────────────────────────────────────────── getLog() → getLog([SQLQuery?]) — optional filtering destroyLog() → destroyLog() emailLog(email) → emailLog(email) log(level, msg) → log(level, msg)

Планирование, фоновые задачи и безголовое управление

Before → Tracelet ───────────────────────────────────────────────────────────── startSchedule() → startSchedule() stopSchedule() → stopSchedule() startBackgroundTask() → startBackgroundTask() stopBackgroundTask(id) → stopBackgroundTask(id) registerHeadlessTask(cb) → registerHeadlessTask(cb)

Утилита

Before → Tracelet ───────────────────────────────────────────────────────────── getProviderState() → getProviderState() getSensors() → getSensors() getDeviceInfo() → getDeviceInfo() playSound(name) → playSound(name) isPowerSaveMode → isPowerSaveMode N/A → 🆕 getSettingsHealth() — detects OEM battery killers N/A → 🆕 openOemSettings(label) — opens OEM settings page N/A → 🆕 requestSettings(action) N/A → 🆕 showSettings(action)

🔐 Журнал аудита (только Tracelet — целостность корпоративного уровня)

  • verifyAuditTrail() — Проверьте хеш-цепочку SHA-256 — не было ли что-нибудь подделано?
  • getAuditProof(uuid) — Криптографическое подтверждение конкретной записи о местоположении.

🛡️ Зоны конфиденциальности (только для Tracelet — GDPR говорит спасибо)

  • addPrivacyZone(zone) — Добавить зону с действием: исключить/ухудшить/только события
  • addPrivacyZones(list) — Массовое добавление
  • removePrivacyZone(id) — Удалить по идентификатору
  • removePrivacyZones() — Удалить все
  • getPrivacyZones() — Список всех зон

🎁 Эксклюзивные функции Tracelet

Функции, которые вы получаете с Tracelet и недоступны в flutter_background_geolocation:

  • Периодический режимTracelet.startPeriodic() — GPS-фиксация каждые N минут через WorkManager. Никакого обслуживания на переднем плане, никаких уведомлений, никакого разряда батареи.
  • Фильтр Калманаgeo.filter.useKalmanFilter: true — EKF с 4 состояниями сглаживает шум GPS. Ваши треки выглядят профессионально, а не пьяно.
  • Адаптивная выборкаgeo.enableAdaptiveMode: true — Автоматически настраивает фильтр расстояния в зависимости от активности, заряда батареи и скорости.
  • Обнаружение имитации (3 уровня)geo.filter.mockDetectionLevel — обнаруживает подмену GPS посредством подсчета спутников, дрейфа в реальном времени и анализа временных меток.
  • Зоны конфиденциальностиaddPrivacyZone() — Исключение, ухудшение или ограничение отслеживания в конфиденциальных областях. Соответствие GDPR встроено.
  • АудитverifyAuditTrail() — хэш-цепочка SHA-256. Докажите, что данные о вашем местоположении не были подделаны.
  • Проверка работоспособностиgetHealth() — Один звонок расскажет вам все: разрешения, GPS, аккумулятор, проблемы OEM, 12 автоматических предупреждений.
  • Совместимость OEMgetSettingsHealth() — Обнаруживает агрессивные средства уничтожения батареи на устройствах Huawei, Xiaomi, Samsung, OPPO и сообщает пользователям, как их исправить.
  • Обнаружение поездокonTrip(cb) — Автоматически определяет поездки по расстоянию, продолжительности, маршрутным точкам и средней скорости.
  • Многоугольные геозоныGeofence(vertices: [...]) — Не только круги. Нарисуйте любую фигуру с поддержкой многоугольников с использованием лучевого приведения.
  • Отключение геозоныgeofence.geofenceModeKnockOut — Геозона автоматически удаляется после первого ВЫХОДА. Идеально подходит для разовых оповещений.
  • Поиск геозоныgetGeofence(id) — Запрос одной геозоны, не загружая их все.
  • Помощники по разрешениямopenAppSettings(), openBatterySettings() — прямые глубокие ссылки на системные настройки.
  • Интеллектуальные повторыhttp.maxRetries + задержка — Экспоненциальная задержка с джиттером. Ваш сервер скажет вам спасибо.
  • Синхронизация только по Wi-Fihttp.disableAutoSyncOnCellular — Сохраняйте мобильные данные, синхронизируйте только по Wi-Fi.
  • Движение только с помощью акселерометраmotion.shakeThreshold — Обнаружение движения без разрешения на распознавание активности. Всплывающее окно с нулевым разрешением.
  • Веб-поддержка — тот же API Dart работает в браузере для отслеживания на переднем плане (в вкладке). Фоновое отслеживание и некоторые встроенные функции недоступны — см. Веб-поддержка.

🤷 Функции, которых еще нет в Tracelet

Некоторые функции предыдущего плагина пока недоступны. Они либо запланированы, либо их легко обойти:

  • Синхронизация геозон на стороне сервераПланируется. На данный момент извлеките данные из своего API и вызовите addGeofences().
  • Интерполяция locationTemplateОбъявлено, не реализовано. Преобразование в обратный вызов onLocation или использование http.extras.
  • Автообновление JWTОбъявлено, не подключено. Установите http.headers вручную; слушайте onAuthorization.
  • Демо-серверНе планируется. Используйте собственный бэкэнд — подойдет любая конечная точка REST.
  • Активация лицензионного ключа — 🎉 Не требуется! Это открытый исходный код.

🛠️ Пошаговая миграция

Шаг 1. Обновите pubspec.yaml.

dependencies: tracelet: ^3.6.14

Удалите flutter_background_geolocation и все пакеты лицензионных ключей. Они вам больше не понадобятся!

Шаг 2. Настройка Android

См. INSTALL-ANDROID.md . Ключевые отличия:

  • Дополнительные зависимости — 🆕 Tracelet 2.0.0+ требует явного добавления play-services-location к вашему build.gradle, если вы хотите высокоточное отслеживание GMS. В противном случае происходит возврат к стандартному AOSP GPS.
  • Нет лицензионного ключа — удалите всю конфигурацию BackgroundGeolocation.org из AndroidManifest.xml.
  • Разрешения — автоматически объединяются через Gradle, вы не объявляете их.
  • minSdkVersion — API 21+ (то же, что и раньше)
  • Kotlin — весь собственный код — Kotlin.

Шаг 3. Настройка iOS

См. INSTALL-IOS.md . Ключевые отличия:

  • Нет лицензионного ключа — удалите записи из списка предыдущего плагина.
  • Фоновые режимы — те же: обновление местоположения, фоновая выборка, удаленные уведомления.
  • Info.plist — те же ключи описания использования (NSLocationAlwaysAndWhenInUseUsageDescription и т. д.)
  • Podfile — удалить источники модуля предыдущего плагина.

Шаг 4. Обновите конфигурацию

Превратите свою квартиру Config() → соединение Config(). См. раздел Конфигурация: от плоского к структурированному выше.

Шаг 5. Обновите прослушиватели событий

Найдите и замените bg.BackgroundGeolocation.onXxxtl.Tracelet.onXxx:

// Before bg.BackgroundGeolocation.onLocation((bg.Location location) { print('[location] $location'); }); // After tl.Tracelet.onLocation((tl.Location location) { print('[location] $location'); });

Шаг 6. Обновление вызовов жизненного цикла

// Before bg.BackgroundGeolocation.ready(config).then((bg.State state) { if (!state.enabled) bg.BackgroundGeolocation.start(); }); // After tl.Tracelet.ready(config).then((tl.State state) { if (!state.enabled) tl.Tracelet.start(); });

Шаг 7. Обновите безголовую задачу

// Before @pragma('vm:entry-point') void backgroundGeolocationHeadlessTask(bg.HeadlessEvent event) async { switch (event.name) { case bg.Event.LOCATION: bg.Location location = event.event; break; } } void main() { bg.BackgroundGeolocation.registerHeadlessTask(backgroundGeolocationHeadlessTask); runApp(MyApp()); } // After — shorter function name is a bonus 😎 @pragma('vm:entry-point') void headlessTask(tl.HeadlessEvent event) async { switch (event.name) { case 'location': tl.Location location = event.event as tl.Location; break; } } void main() { tl.Tracelet.registerHeadlessTask(headlessTask); runApp(MyApp()); }

📦 Полезная нагрузка HTTP: Snake_case → CamelCase

Внимание, серверные разработчики! Есть кое-что, что нужно обновить на вашем сервере.

flutter_background_geolocation отправляет это:

{ "location": { "coords": { "latitude": 37.42, "longitude": -122.08, "accuracy": 12.3 }, "timestamp": "2026-03-06T10:30:00.000Z", "is_moving": true, "uuid": "abc-123", "odometer": 1234.5, "activity": { "type": "walking", "confidence": 85 }, "battery": { "level": 0.72, "is_charging": false }, "extras": { "custom_key": "custom_value" } } }

Tracelet отправляет это:

{ "location": { "coords": { "latitude": 37.42, "longitude": -122.08, "accuracy": 12.3 }, "timestamp": "2026-03-06T10:30:00.000Z", "isMoving": true, "uuid": "abc-123", "odometer": 1234.5, "isMock": false, "activity": { "type": "walking", "confidence": 85 }, "battery": { "level": 0.72, "isCharging": false }, "extras": { "custom_key": "custom_value" } } }

TL;DR: is_movingisMoving, is_chargingisCharging, а также новое поле isMock. Обновите анализ JSON, и все будет в порядке.


🚨 Распространенные ошибки

Не учите это на собственном горьком опыте — мы уже это сделали:

  • Config теперь является составным — перенос полей в GeoConfig(...), AppConfig(...), HttpConfig(...) и т. д.
  • desiredAccuracy: -1 не работает — Используйте DesiredAccuracy.high — типизированные перечисления, а не магические числа.
  • logLevel: 5 не работает — используйте LogLevel.verbose.
  • Не могу найти resetOdometer() — Сейчас setOdometer(0)
  • Свойство notification: исчезло — это foregroundService: ForegroundServiceConfig(...) внутри android: (AndroidConfig), а не app.
  • scheduleUseAlarmManager нет в AppConfig — теперь это android.scheduleUseAlarmManager
  • preventSuspend нет в AppConfig — теперь это ios.preventSuspend
  • Бэкенд не может проанализировать is_moving — Теперь это isMoving (camelCase)
  • У вас все еще есть код лицензионного ключа? — Удалите его — он не нужен Tracelet
  • Свойства State выглядят по-другому — проверьте Справочник API 
  • Ошибки типа HeadlessEvent.event — Приведение: event.event as tl.Location

📚 Дополнительные ресурсы


Добро пожаловать на сторону открытого исходного кода. У нас есть печенье. 🍪