Limitations
We’d rather you know the gaps up front than discover them after buying.
Not implemented yet
- No Flutter web/desktop support. iOS & Android only — the closed-source native engine is mobile-only, so there is no web, macOS, Windows, or Linux implementation, and none is planned. See Compatibility.
- A larger set of Transistorsoft config/methods is deliberately out of
scope, not a temporary gap — see
Migration: API parity
for the full list (
schedule, templates,getLocations()pagination/SQL,startBackgroundTask,getDeviceInfo, and others).
Accepted-but-no-op config keys
These are accepted for API compatibility but currently do nothing:
| Key | Status |
|---|---|
foregroundService | No-op — the Android foreground service required for background location is always on while tracking, regardless of this key. No equivalent concept on iOS. |
backgroundPermissionRationale | No-op on iOS; Android uses its own permission-rationale flow (shouldShowRequestPermissionRationale) instead of a config-driven dialog. |
debug | Not a no-op, but plays audible sound cues only (location, heartbeat, motion-change, stop-timeout, geofence events) — it does not affect tracking, filtering, or upload behavior. |
The Config reference flags foregroundService
and backgroundPermissionRationale inline with a “No-op” badge.
Platform-specific config keys
These keys are fully functional on their home platform and a silent no-op on the other:
| Key | Home platform | No-op on |
|---|---|---|
stationaryLocationUpdateInterval | Android | iOS |
activityRecognitionInterval | Android | iOS |
locationUpdateInterval | Android | iOS |
showsBackgroundLocationIndicator | iOS | Android |
stationaryDistanceFilter | iOS | Android |
preventSuspend | iOS | Android |
useSessionEngine | iOS (17+; the value is stored but unread on Android) | Android |
Platform notes
- Geofence transitions fire past the boundary — that is OS behavior, not a
bug. Both platforms deliberately debounce region crossings to avoid
flapping on GPS noise. On iOS, Core Location reports ENTER/EXIT only after
the device has cleared the radius plus a system-defined cushion: an EXIT
typically arrives tens of seconds after the geometric crossing — at running
or driving speed that is roughly 100–300 m beyond the circle, and in the
worst case minutes later. On Android, transitions add up to ~30 s of
reporting latency (
notificationResponsiveness) on top of fused-location detection lag. Thelocationattached to a geofence event is the last accepted fix at the moment the OS delivered the transition, so on a map the event marker lands where the device was when the OS made its decision, not on the circle’s edge. This applies to anything built on the platform geofencing services — see the Geofencing guide. If your use case needs tighter boundaries, compare distance to the fence center in your ownonLocationhandler while tracking is active. - Offline queue persistence. The offline upload queue is stored in
SQLite (
bgeo.db,location_eventstable) withmaxRecordsToPersist/maxDaysToPersistretention; geofences persist in the same database. Persisted native log rows have their own retention —logMaxDaysplus a hard 25,000-row cap. - iOS background delivery is subject to Core Location’s rules. BGeo uses
a session-based engine (
CLLocationUpdate.liveUpdates+CLBackgroundActivitySession, on by default on iOS 17+ viauseSessionEngine) plus a wake region so tracking resumes after kill/eviction/reboot, but exact cadence depends on iOS, device settings (Low Power Mode, Background App Refresh, Precise Location), and OS scheduling. iOS < 17 always uses the legacy delivery path regardless of this flag. registerHeadlessTask()is Android-only. iOS relaunches the app natively on a significant-location-change wake instead of running a headless dispatcher — there is noAppRegistry-equivalent headless execution path on iOS.registerHeadlessTask()retains your task on iOS but never invokes it while the app process isn’t running; native uploads, retries, and token refresh continue regardless. See Boot & killed-app behavior. On Android, headless dispatch deliberately excludes rawlocationevents (onlyheartbeat,motionchange,geofence,providerchange,powersavechange,http, andconnectivitychangereach a headless task) — see the same guide’s Android headless tasks section. TheHeadlessTaskyou pass must be a top-level function or a static method — a closure or instance method can’t be resolved byPluginUtilities.getCallbackHandlein a fresh background isolate, andregisterHeadlessTask()throws anArgumentErrorimmediately (before any platform call) if you pass one.- Android OEM battery managers can force-stop apps and drop geofence/activity-recognition/boot callbacks until the app is reopened. A battery-optimization exemption is the only reliable mitigation on such devices — this affects every background-location SDK.