ex_background_geolocation 1.0.0-beta.2
ex_background_geolocation: ^1.0.0-beta.2 copied to clipboard
Background location tracking for Android and iOS: motion detection that turns GPS off when parked, geofencing and an offline-safe HTTP upload queue.
1.0.0-beta.2 - 2026-11-02 #
- iOS: a release build without a valid
licenseKeyno longer resumes tracking that was on at the last launch. On both platforms,ready()with a key that is not valid for this app or release now stops tracking that is running. - The example app shows
start()errors such asLICENSE_INVALID.
1.0.0-beta.1 - 2026-11-02 #
First public release. Android (minSdk 24) and iOS (15.0+).
Tracking and motion #
- Background location tracking: an Android foreground service and the iOS
locationbackground mode. Survives app kill and reboot - Android restarts the service (stopOnTerminate: false,startOnBoot: true); iOS relaunches the app on a stationary-region exit or significant-location change (host apps callExBackgroundGeolocationPlugin.resumeIfNeeded(launchOptions:)from their AppDelegate - see README). - Motion state machine that turns GPS off when the device is parked: a stop timer
(
stopTimeout) plus activity recognition (Android) / Core Motion (iOS) go stationary, and a stationary geofence (stationaryRadius, at least 150 m) resumes tracking when the device leaves. On Android, periodic activity updates and a low-power location also resume it while stationary.changePace()forces either state. - Stops the motion sensors miss (a car idling with the engine on) end the trip
after 3 minutes (or
stopTimeout, if longer) without GPS movement. - iOS: for
stationaryGraceTime(5 min by default) after a stop, a low-accuracy location feed keeps the app running so moving off again resumes tracking at once; longer stops fall back to the stationary region. onLocation,onMotionChange,onActivityChangeandgetCurrentPosition().
Uploads #
- Every fix is stored in a native SQLite queue and POSTed to
Config.url(autoSync), withheaders, extraparamsand alocationFieldswhitelist for the body.uploadIntervalthrottles stored points. - Uploads retry on their own: when the network returns and on a backoff
(15 s, 30 s, 60 s ...) capped by
retryMaxInterval. A record the server rejects as invalid (HTTP 400, 413, 414, 415, 422) is dropped after 3 attempts so it cannot block the queue; every other failure is kept and retried. - While a retry is waiting, new locations are only queued instead of each
starting another upload (
uploadBackoff, on by default; turn it off to try again with every new location). Locations that arrive while an upload is failing don't each make their own attempt. onHttp,sync(),getCount(),destroyLocations(). Each payload carries the phone'sutcOffsetMinutes.
Odometer and trip state #
- Native odometer (
location.odometer,resetOdometer()), counted while the app is closed and persisted across restarts and reboots. - Persistent trip counters (
getTripStats(),resetTrip()) and full-stateTripStatesnapshots after every fix, upload, motion change, start and stop - throughonState, an Android broadcast and an iOS notification, so native host code can read them with no Dart running.emitStateEventsandstateEventIntervalcontrol them.
Geofencing #
addGeofence(s),removeGeofence(s),getGeofences()andonGeofence(ENTER/EXIT), monitored while the app is closed and kept across reboots. iOS monitors at most 20 regions.
Permissions and device state #
requestPermission()walks through foreground location, "Always" and (Android 10+) activity recognition;getPermissionStatus(),openSettings(),getActivityRecognitionStatus(),requestActivityRecognition().- The phone's Location switch:
isLocationServicesEnabled(),openLocationSettings()andonProviderChange.
Background hooks #
- Android headless task (
registerHeadlessTask) for events while no UI is running. - Deferred events (
addDeferredEvent,getDeferredEvents,clearDeferredEvents) to hand data from background code to the next app launch; iOS native helpersremoveUserGeofenceandaddDeferredEventNative.
Packaging and licensing #
- The native cores ship as compiled binaries: an Android AAR and an iOS XCFramework (CocoaPods and Swift Package Manager).
- Release builds need a license key (
Config.licenseKey) tied to the app's bundle ids; one key covers an app's Android and iOS ids and includes 12 months of updates. Debug installs run unlicensed and log a warning when the key would fail in release. See README > Licensing.