NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
pub.dev · #1468 most downloaded on pub.dev
The most sophisticated background location tracking & geofencing module with battery-conscious motion-detection intelligence for iOS and Android.
Last release 6 days ago
27 Sep 2026
Ships fairly regularly
a new release about every 3 weeks
Nearly every release is documented
notes for 60 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
8 years old
190 releases · first in 2018
[Android] Performance enhancements and error-checking.
[Android] Fix memory-leak in .startBackgroundTask: If a Task timed-out and is "FORCE KILLED", it was never removed from a List .
.startBackgroundTask: If a Task timed-out and is "FORCE KILLED", it was never removed from a List<Task>.Exception NullPointerException:at com.transistorsoft.locationmanager.util.BackgroundTaskWorker.onStoppedOne column per quarter.
[iOS] Fix build failure "Use of '@import' when C++ modules are disabled"
stopSelfResult(startId) instead of stopSelf(). This could improve reports of Android ANR
Context.startForeground.Geofence arguments (eg: invalid latitude/longitude)..getCurrentPosition in a Timer (eg: every second).HeartbeatService from a Foreground Service to AlarmManager ONESHOT. :warning: In your onHeartbeat event, if you intend to perform any kind of asynchronous function, you should wrap it inside BackgroundGeolocation.startBackgroundTask in order to prevents the OS from suspending your app before your task is complete:BacckgroundGeolocation.onHeartbeat((event) async {
print("[onHeartbeat] $event");
// First register a background-task.
var taskId = await BackgroundGeolocation.startBackgroundTask();
try {
// Now you're free to perform long-running tasks, such as getCurrentPosition()
var location = await BackgroundGeolocation.getCurrentPosition(
samples: 3,
timeout: 30,
extras: {
"event": "heartbeat"
}
);
print("[onHeartbeat] location: $location");
} catch(error) {
print("[getCurrentPosition] ERROR: $error");
}
// Be sure to singal completion of your background-task:
BackgroundGeolocation.stopBackgroundTask(taskId);
});
List in AbstractService.SingleLocationRequest error occurs and at least one sample exits, prefer to resolve the request successfully rather than firing the error (eg: getCurrentPosition, motionchange, providerchange requests).[Android] :warning: If you have the following elements defined in your __AndroidManifest.xml__, __DELETE__ them: ```diff
AndroidManifest.xml, DELETE them:- <service android:name="com.transistorsoft.locationmanager.service.TrackingService" android:foregroundServiceType="location" />
- <service android:name="com.transistorsoft.locationmanager.service.LocationRequestService" android:foregroundServiceType="location" />
AlarmManager "exact alarms" (which the plugin does take advantage of). If you wish the plugin to use AlarmManager "exact alarms" in your app, you must now explicitly define that permission in your own AndroidManifest:<manifest>
<uses-permission android:minSdkVersion="34" android:name="android.permission.USE_EXACT_ALARM" />
</manifest>
WorkManager instead of a foreground-service.AlarmManager exact alarms (android.permission.SCHEDULE_EXACT_ALARM), the plugin can no longer rely upon launching a foreground-service using an exact alarm. Instead, the plugin will create a geofence around the current position (configured with initialTriggerEntry) to hopefully immediately launch a foreground-service to handle the fake geofence event, since Android allows foreground-service launches due to Geofencing events.android:foregroundServiceType in the plugin's AndroidManifest (handled automatically by the plugin).DeviceSettings.startMonitoringPowerSaveChanges.Fix nullsafety issue in TransistorAuthorizationToken.destroy.
TransistorAuthorizationToken.destroy.ApiException.getStatusCode() if native addGeofence method fails.[Android] Gradle v8 now requires namespace attribute in gradle files.
namespace attribute in gradle files.Config.showsBackgroundLocationIndicator is false (the default). As a result of this change, Config.showsBackgroundLocationIndicator will now default to true.[Android] Upgrade logback-android dependency to 3.0.0 (org.slf4j-api to `2.0.7).
logback-android dependency to 3.0.0 (org.slf4j-api to `2.0.7).[Android] Fix String concatenation issue on Turkish devices where method-name composed for use with reflection is incorrectly capitalized (ie: isMovin
[Android] Fix String concatenation issue on Turkish devices where method-name composed for use with reflection is incorrectly capitalized (ie: isMoving -> setIsMovingis incorrectly capitalized with Turkish capital assetİsMoving. Simply enforce Locale.ENGLISHwhen performingString.toUpperCase(Locale.ENGLISH)`.
[iOS] Fix bug in TSScheduler. When schedule was cleared via .setConfig, only the State.schedulerEnabled property was set to false, but the TSScheduler singleton contained an internal 'enabled' property which was not reset to false. Solution was to simply call stop() method upon TSScheduler singleton.
[Android] Bump default hmsLocationVersion = 6.9.0.300. There are reports of Google rejecting apps due to older huawei HMS dependenc ies.
hmsLocationVersion = 6.9.0.300. There are reports of Google rejecting apps due to older huawei HMS dependenc
ies.ClassCastException related to Motion API error[Android] Introduce __Huawei HMS Support__. Requires a separate license key purchased here.
at com.transistorsoft.locationmanager.service.TrackingService.changePace(TrackingService.java:264)
at com.transistorsoft.locationmanager.service.TrackingService$c.onError(TrackingService.java:69)
at com.transistorsoft.locationmanager.location.SingleLocationRequest.onError(SingleLocationRequest.java:18)
at com.transistorsoft.locationmanager.location.SingleLocationRequest.start(SingleLocationRequest.java:71)
at com.transistorsoft.locationmanager.location.TSLocationManager.getCurrentPosition(TSLocationManager.java:3)
at com.transistorsoft.locationmanager.service.TrackingService.changePace(TrackingService.java:321)
at com.transistorsoft.locationmanager.service.TrackingService$c.onError(TrackingService.java:69)
at com.transistorsoft.locationmanager.location.SingleLocationRequest.onError(SingleLocationRequest.java:18)
at com.transistorsoft.locationmanager.location.SingleLocationRequest.start(SingleLocationRequest.java:71)
at com.transistorsoft.locationmanager.location.TSLocationManager.getCurrentPosition(TSLocationManager.java:3)
at com.transistorsoft.locationmanager.service.TrackingService.changePace(TrackingService.java:321)
at com.transistorsoft.locationmanager.service.TrackingService$c.onError(TrackingService.java:69)
at com.transistorsoft.locationmanager.location.SingleLocationRequest.onError(SingleLocationRequest.java:18)
at com.transistorsoft.locationmanager.location.SingleLocationRequest.start(SingleLocationRequest.java:71)
.
.
.
[Fixed][Android] Implement support for play-services-location v21 (ext.playServicesLocationVersion in your android/build.gradle). The plugin can now w
play-services-location v21 (ext.playServicesLocationVersion in your android/build.gradle). The plugin can now work with either <= v20 or >= v21.[Fixed] Resolve minor dart static analysis warnings (mostly to do with curly braces).
[Changed] __Android__ Update logback-android version.
logback-android version.[Fixed] __Android__: Catch Fatal Exception: java.lang.IllegalArgumentException: NetworkCallback was already unregistered
Fatal Exception: java.lang.IllegalArgumentException: NetworkCallback was already unregisteredlogback-android has not been automatically clearing all expired records (Config.logMaxDays) from the log database. The logback-android database consists of three tables and only one was being cleared (see https://github.com/tony19/logback-android/pull/214), resulting in a constantly growing database (where logLevel > LOG_LEVEL_OFF). This version of the plugin will alter the logback-android database tables with ON DELETE CASCADE to ensure all log-data is properly removed.stopSchedule and startSchedule (See API docs HTTP Guide for more information).[Android] add @pragma('vm:entry-point') to lib's _headlessCallbackDispatcher`, required for *release* builds on Flutter >= 3.3.0.
@pragma('vm:entry-point') to lib's _headlessCallbackDispatcher`, required for release builds on Flutter >= 3.3.0.[Android] play-services:location has introduced a breaking change in v21, breaking the plugin. googlePlayServicesLocationVersion will be capped with a…
getCurrentPosition not respecting timeout.play-services:location has introduced a breaking change in v21, breaking the plugin. googlePlayServicesLocationVersion will be capped with a maximum of v20. The next major release (4.10.0) will set a minimum required version of v21.[iOS] Rebuild TSLocationManager.xcframework with *XCode 13*.
TSLocationManager.xcframework with XCode 13.[iOS] Build TSLocationManager.xcframework with *XCode 14*.
TSLocationManager.xcframework with XCode 14.android.permission.POST_NOTIFICATIONS for Android 13 (targetSdkVersion 33). Requ
ired to allow enabling notifications in Settings->Apps.Authorization.refreshHeaders for full control over HTTP headers sent to Authorization.refreshUrl when refreshing auth token.null check when executing PowerManager.isPowerSaveMode()Config.disableProviderChangeRecord (default false) to allow disabling the automatical HTTP POST of the onProviderChange location record. Some users do not want this automatically uploaded locatio
n whenever the state of location-services is changed (eg: Location-services disabled, Airplane mode, etc).disableMotionActivityUpdates: true and calling .start() followed immediately by .changePace(true). The SDK would fail to enter the moving state, entering the stationary state instead.Add new iOS 15 CLLocation attribute Location.ellipsoidal_altitude *The altitude as a height above the World Geodetic System 1984 (WGS84) ellipsoid, me
CLLocation attribute Location.ellipsoidal_altitude The altitude as a height above the World Geodetic System 1984 (WGS84) ellipsoid, measured in meters. Android Location.altitude has always returned ellipsoidal altutude, so both Location.altitude and Location.ellipsoidal_altitude will return the same value.[Android] Fix java.lang.IllegalArgumentException TSProviderManager.handleProviderChangeEvent`.
java.lang.IllegalArgumentException TSProviderManager.handleProviderChangeEvent`.startOnBoot: false with stopOnTerminate: false could start-on-boot.State.enabled returned by calling .stop() returns true due to implementation running in a background-thread but callback executed immediately on the main-thread. However, requesting .state immediately after calling .stop would return the correct value of State.enabled.notification.sticky not being respected.[Android] Refactor application life-cycle management. Remove deprecated permission android.permission.GET_TASKS traditionally used for detecting when…
onProviderChange event: not properly detecting when location-services disabled.Context.startForegroundService with try / catch: the plugin will now catch exception ForegroundServiceStartNotAllowedException and automatically retry with an AlarmManager oneShot event.android.permission.GET_TASKS traditionally used for detecting when the app has been terminated. The new life-cycle mgmt system can detect Android headless-mode in a much more elegant manner.WhenInUse behaviour: The plugin will not allow .changePace(true) to be executed when the app is in the background (since Android forbids location-services to initiated in the background with WhenInUse).useSignificantChangesOnly behaviour. Will use a default motionTriggerDelay with minimum 60000ms, minimum distanceFilter: 250 and enforced stopTimeout: 20.location.mock will now be present for iOS when the location is mocked, just like Android.[Android] Fix bug in Android 12 support for executing .start() in background while terminated. Used JobScheduler ONESHOT instead of AlarmManager.
.start() in background while terminated. Used JobScheduler ONESHOT instead of AlarmManager.ConcurrentModificationException in onPermissionGranted.[Android] Fix issue device reboot behaviour related to change in 4.6.1 for Android 11. Could produce multiple motionchange requests after airplane-mod
4.6.1 for Android 11. Could produce multiple motionchange requests after airplane-mode togged off after reboot.[Android] If on device reboot location-services fails to provide a location (eg: timeout, airplane mode), the plugin would rely on motion API events t
ForegroundServiceStartNotAllowedException: immediately launch the SDK's TrackingService as soon as .start() executes. If a location-timeout occurs while fetching the onMotionChange position after device reboot with startOnBoot: true, the ForegroundServiceStartNotAllowedException could be raised.android:enabled and android:permission to the SDK's built-in BootReceiver:<receiver android:name="com.transistorsoft.locationmanager.BootReceiver" android:enabled="true" android:exported="false" android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
[Android] Android 12 support for executing .start() and .getCurrentPosition() while the plugin is disabled and in the background. This is a bypass of
.start() and .getCurrentPosition() while the plugin is disabled and in the background. This is a bypass of new Android 12 restrictions for starting foreground-services in the background by taking advantage of AlarmManager.Fatal Exception: android.app.ForegroundServiceStartNotAllowedException: startForegroundService() not allowed due to mAllowStartForeground false: service
[Android] Add a few extra manufacturer-specific Intent for DeviceSettings.showPowerManager().
Intent for DeviceSettings.showPowerManager().compileSdkVersion 31 is now required.targetSdkVersion 29 is required to release an Android app to Play Store, the SDK's AndroidManifest now automatically applies android:foregroundServiceType="location" to all required Service declarations. You no longer need to manually provide overrides in your own AndroidManifest, ie:<manifest>
<application>
- <service android:name="com.transistorsoft.locationmanager.service.TrackingService" android:foregroundServiceType="location" />
- <service android:name="com.transistorsoft.locationmanager.service.LocationRequestService" android:foregroundServiceType="location" />
</application>
</manifest>
[Android] Upgrade android-permissions dependency from 0.1.8 -> 2.1.6.
android-permissions dependency from 0.1.8 -> 2.1.6.TSLocationManager.xcframework with XCode 13.3Config.authorization: append Config.headers with request to refreshUrl
[Android] While testing adding 20k geofences, the Logger can cause an OutOfMemory error. Define a dedicated thread executor Executors.newFixedThreadPo
OutOfMemory error. Define a dedicated thread executor Executors.newFixedThreadPool(2) for posting log messages in background.stopOnTerminate: true[Fixed][iOS] Regression bug in iOS SAS authorization strategy
late (Location.event, Location.mock). Location.event will be empty-string when there is no corresponding event.[Fixed][iOS} iOS Config.authorization did not allow http response status 201
[Fixed][Android] Android custom layout (Config.notification.layout) events not working in Headless mode.
Config.notification.layout) events not working in Headless mode.reset:false behaviour. When .ready() was called a 2nd time, the plugin would apply the config anyway, bypassing reset:false.Authorization.strategy "SAS" (alternative to default JWT).[Added][Android] Implement new Android 12 "reduced accuracy" mechanismrequestTemporaryFullAccuracy.
requestTemporaryFullAccuracy.[Fixed][iOS] Authorization.refreshPayload refreshToken was not performing a String replace on the {refreshToken} template, instead over-writing the en
Authorization.refreshPayload refreshToken was not performing a String replace on the {refreshToken} template, instead over-writing the entire string. Eg: if provided with 'refresh_token': 'Bearer {refreshToken}, Bearer would be over-written and replaced with only the refresh-token.[Fixed][Android] Fixed crash reported by Huawei device, where verticalAccuracy returns NaN.
heartbeatInterval and preventSuspend to dynamically update interval when changed with setConfig.[Changed][Android] Revert default okHttpVersion back to 3.12.13. 4.x requires minSdkVersion 21 (*Android 5*).
okHttpVersion back to 3.12.13. 4.x requires minSdkVersion 21 (Android 5).[Changed][Android] Update Android android-permissions to import from *MavenCentral* instead of deprecated jCenter.
okhttp version to 4.9.1.eventbus to 3.2.0.android-permissions to import from MavenCentral instead of deprecated jCenter.TSLocationManager using XCode 12.4 instead of 12.5.1.getCurrentPosition() is executed before .start(), the Android SDK fails to request motion permission.[Fixed][iOS] Reports 2 reports of iOS crash NSInvalidArgumentException (TSLocation.m line 178) with iOS 14 .x. Wrap JSON serialization in @try/@catch
NSInvalidArgumentException (TSLocation.m line 178) with iOS 14
.x. Wrap JSON serialization in @try/@catch block. iOS JSON serialization docs state the supplied NSError err
or ref should report problems but it seems this is only "sometimes" now.Same as previous version. Simply performed flutter format on dart code to satisfy dart analyzer on pub.dev
Release nullsafety version as 4.0.0.
[Changed] Config.authorization will perform regexp on the received response, searching for keys such as accessToken, access_token, refreshToken, refre
Config.authorization will perform regexp on the received response, searching for keys such as accessToken, access_token, refreshToken, refresh_token, rather than performing regexp on the data itself.[Fixed] Nullsafety casting bug in DeviceInfo, DeviceSettings.
DeviceInfo, DeviceSettings.[Fixed][Android] Fix threading issue ConcurrentMmodificationException in TSConfig.
ConcurrentMmodificationException in TSConfig.[Fixed][Android] Don't synchronize access to ThreadPool. Addresses ANR issues
DeviceSettings _CastError (type 'Future<dynamic>' is not a subtype of type 'FutureOr<bool>' in type cast)[Fixed][Android] Implmementing State.didDeviceReboot in previous version introduced a source of ANR due time required to generate and persist JSON Con
[Added] New State param State.didDeviceReboot, signals if the device was rebooted.
State param State.didDeviceReboot, signals if the device was rebooted.locationTemplate property timestampMeta.[Fixed][Android] Flutter 2 breaks Android Headless mode with null-pointer exception.
* [Added] Dart nullsafety.
[Changed] Config.authorization will perform regexp on the received response, searching for keys such as accessToken, access_token, refreshToken, refre
Config.authorization will perform regexp on the received response, searching for keys such as accessToken, access_token, refreshToken, refresh_token.[Fixed][Android] Fix threading issue ConcurrentMmodificationException in TSConfig
ConcurrentMmodificationException in TSConfig[Fixed][Android] Don't synchronize access to ThreadPool. Addresses ANR issues.
[Fixed][Android] Implmementing State.didDeviceReboot in previous version introduced a source of ANR due time required to generate and persist JSON Con
[Added] New State param State.didDeviceReboot, signals if the device was rebooted.
State param State.didDeviceReboot, signals if the device was rebooted.locationTemplate property timestampMeta.[Fixed][Android] Flutter 2 did something to break Headless registration.
See Breaking Changes with `background_fetch@0.7.0`
TSLocationManager.framework to new .xcframework for MacCatalyst support with new Apple silcon.cocoapods >= 1.10+.iOS' new .xcframework requires cocoapods >= 1.10+:
$ pod --version
// if < 1.10.0
$ sudo gem install cocoapods
background_fetch.[Fixed][iOS] startOnBoot: false was not being respected.
startOnBoot: false was not being respected.getCurrentPosition are executed, the location permission handler could hang and not return, causing neither getCurrentPosition request to execute.[Changed] Remove Config.encrypt feature. This feature has always been flagging a Security Issue with Google Play Console and now the iOS TSLocationMan
Config.encrypt feature. This feature has always been flagging a Security Issue with Google Play Console and now the iOS TSLocationManager is being flagged for a virus by Avast MacOS:Pirrit-CS[PUP]. This seems to be a false-positive due to importing RNCryptor package.stopAfterElapsedMinutes was configured with a value greater-than stopTimeout, the event would fail to fire.[Fixed][iOS] Fix issue with iOS buffer-timer with requestPermission. Could execute callback twice.
[Fixed][iOS] When requesting WhenInUse location permission, if user grants "Allow Once" then you attempt to upgrade to Always, iOS simply does nothing
WhenInUse location permission, if user grants "Allow Once" then you attempt to upgrade to Always, iOS simply does nothing and the requestPermission callback would not be called. Implemented a 500ms buffer timer to detect if the iOS showed a system dialog (signalled by the firing of WillResignActive life-cycle notification). If the app does not WillResignActive, the buffer timer will fire, causing the callback to requestPermission to fire.requestPermission not showing backgroundPermissionRationale dialog on targetSdkVersion 29 when using locationAuthorizationRequest: 'WhenInUse' followed by upgrade to Always.Location.coords attributes speed_accuracy and heading_accuracy.sync method when no HTTP service is configured.isMainActivityActive to detect when TSLocationManagerActivity is active.[Fixed][Android] isMainActivityActive reported incorrect results for Android apps configured with "product flavors". This would cause the SDK to fail
isMainActivityActive reported incorrect results for Android apps configured with "product flavors". This would cause the SDK to fail to recognize app is in "headless" state and fail to transmit headless events.Location.coords.altitudeAccuracy was not being returned.targetSdkVersion 30 support for new Android background location permission with new Config.backgroundLocationRationale. Android 11 has changed location authorization and no longer offers the [Allow all the time] button on the location authorization dialog. Instead, Android now offers a hook to present a custom dialog to the user where you will explain exactly why you require "Allow all the time" location permission. This dialog can forward the user directly to your application's Location Permissions screen, where the user must explicity authorize [Allow all the time]. The Background Geolocation SDK will present this dialog, which can be customized with Config.backgroundPermissionRationale.BackgroundGeolocation.ready(Config(
locationAuthorizationRequest: 'Always',
backgroundPermissionRationale: PermissionRationale(
title: "Allow access to this device's location in the background?",
message: "In order to allow X, Y and Z in the background, please enable 'Allow all the time' permission",
positiveAction: "Change to Allow all the time",
negativeAction: "Cancel"
)
));
Your coding agent can read these notes before it upgrades. Set up the MCP server →