🚀 Руководство по миграции: 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
),
);Краткий обзор разделов конфигурации:
geo→GeoConfig— Точность, фильтр расстояния, эластичность, периодический режим, фильтр Калмана, ложное обнаружениеapp→AppConfig— Жизненный цикл, контрольный сигнал, расписаниеandroid→AndroidConfig— 🆕 Только для Android: уведомление службы переднего плана, интервалы обновления местоположения, AlarmManager, периодические стратегииios→IosConfig— 🆕 Только для iOS: тип активности, фоновые сеансы, предотвращение приостановкиmotion→MotionConfig— Тайм-аут остановки, распознавание активности, режим только акселерометраhttp→HttpConfig— синхронизация URL-адреса, заголовков, пакетной обработки, отсрочки повторных попыток, режима только Wi-Fi.logger→LoggerConfig— Уровень журнала, максимальное количество дней, звуки отладки.geofence→GeofenceConfig— Радиус близости, начальный триггер, режим выбиванияpersistence→PersistenceConfig— Режим сохранения, максимальное количество дней/записей, шаблоныaudit→AuditConfig— 🆕 хеш-цепочка SHA-256 — потому что защита от несанкционированного доступа имеет значениеprivacyZone→PrivacyZoneConfig— 🆕 Движок зоны конфиденциальности — лучший друг GDPRsecurity→SecurityConfig— 🆕 Шифрование базы данных при хранении (encryptDatabase)attestation→AttestationConfig— 🆕 Аттестация устройства/проверка целостности
🗺️ Шпаргалка по большой конфигурации
Не волнуйтесь, каждое поле имеет сопоставление 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.policy—LocationFilterPolicy.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)Примечание:
scheduleUseAlarmManager→android.scheduleUseAlarmManager|preventSuspend→ios.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.enabledHTTP-синхронизация → 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.enabled—falseпо умолчанию. Хеш-цепочка SHA-256 в каждом месте — тампер = разрушенaudit.hashAlgorithm— NOTTRANS1LATEaudit.includeExtrasInHash—falseпо умолчанию
🛡️ Зоны конфиденциальности → PrivacyZoneConfig (эксклюзивно для Tracelet)
privacyZone.enabled—falseпо умолчанию. Включите механизм зоны конфиденциальности.
🎯 Константы точности — типизированные перечисления!
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 автоматических предупреждений. - Совместимость OEM —
getSettingsHealth()— Обнаруживает агрессивные средства уничтожения батареи на устройствах Huawei, Xiaomi, Samsung, OPPO и сообщает пользователям, как их исправить. - Обнаружение поездок —
onTrip(cb)— Автоматически определяет поездки по расстоянию, продолжительности, маршрутным точкам и средней скорости. - Многоугольные геозоны —
Geofence(vertices: [...])— Не только круги. Нарисуйте любую фигуру с поддержкой многоугольников с использованием лучевого приведения. - Отключение геозоны —
geofence.geofenceModeKnockOut— Геозона автоматически удаляется после первого ВЫХОДА. Идеально подходит для разовых оповещений. - Поиск геозоны —
getGeofence(id)— Запрос одной геозоны, не загружая их все. - Помощники по разрешениям —
openAppSettings(),openBatterySettings()— прямые глубокие ссылки на системные настройки. - Интеллектуальные повторы —
http.maxRetries+ задержка — Экспоненциальная задержка с джиттером. Ваш сервер скажет вам спасибо. - Синхронизация только по Wi-Fi —
http.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.onXxx → tl.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_moving → isMoving, is_charging → isCharging, а также новое поле 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.scheduleUseAlarmManagerpreventSuspendнет в AppConfig — теперь этоios.preventSuspend- Бэкенд не может проанализировать
is_moving— Теперь этоisMoving(camelCase) - У вас все еще есть код лицензионного ключа? — Удалите его — он не нужен Tracelet
- Свойства
Stateвыглядят по-другому — проверьте Справочник API - Ошибки типа
HeadlessEvent.event— Приведение:event.event as tl.Location
📚 Дополнительные ресурсы
- Справочник API — каждый метод, каждый параметр
- Руководство по настройке — подробное описание всех параметров конфигурации.
- Фоновое отслеживание — как он выдерживает убийства приложений
- Установка Android — настройка для Android.
- Установка iOS — настройка для iOS.
- Проблемы GitHub — застряли? ты у нас есть
Добро пожаловать на сторону открытого исходного кода. У нас есть печенье. 🍪