react-native-background-geolocation
Version:
The most sophisticated cross-platform background location-tracking & geofencing module with battery-conscious motion-detection intelligence
702 lines (589 loc) • 89.1 kB
Markdown
# Change Log
## 3.10.0 — 2021-02-17
- [Fixed][iOS] `startOnBoot: false` was not being respected.
- [Fixed][Android] If multiple simultaneous calls to `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 `TSLocationManager` is being flagged for a virus by *Avast* *MacOS:Pirrit-CS[PUP]*. This seems to be a false-positive due to importing [RNCryptor](https://github.com/RNCryptor/RNCryptor) package.
- [Fixed][Android] If `stopAfterElapsedMinutes` was configured with a value greater-than `stopTimeout`, the event would fail to fire.
## 3.9.3 — 2020-11-06
- [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 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.
- [Fixed][Android] Issue with `requestPermission` not showing `backgroundPermissionRationale` dialog on `targetSdkVersion 29` when using `locationAuthorizationRequest: 'WhenInUse'` followed by upgrade to `Always`.
- [Added] Added two new `Location.coords` attributes `speed_accuracy` and `heading_accuracy`.
- [Fixed][iOS] fix bug providing wrong Array of records to `sync` method when no HTTP service is configured.
- [Fixed][Android] Add extra logic for `isMainActivityActive` to detect when `TSLocationManagerActivity` is active.
## 3.9.1 — 2020-10-02
- [Fixed][Android] `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.
- [Added][Android] `Location.coords.altitude_accuracy` was not being returned.
- [Added][Android] _Android 11_, `targetSdkVersion 30` support for new Android background location permission with new `Config.backgroundLocationRationale`. Android 11 has [changed location authorization](https://developer.android.com/preview/privacy/location) 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`.
```javascript
BackgroundGeolocation.ready({
locationAuthorizationRequest: 'Always',
backgroundPermissionRationale: {
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"
}
});
```

- [Fixed][iOS] Add intelligence to iOS preventSuspend logic to determine distance from stationaryLocation using configured stationaryRadius rather than calculated based upon accuracy of stationaryLocation. If a stationaryLocation were recorded having a poor accuracy (eg: 1000), the device would have to walk at least 1000 meters before preventSuspend would engage tracking-state.
- [Fixed][Android] Android LocationRequestService, used for getCurrentPosition and motionChange position, could remain running after entering stationary state if a LocationAvailability event was received before the service was shut down.
- [Fixed][iOS] Ignore didChangeAuthorizationStatus events when disabled and no requestPermissionCallback exists. The plugin could possibly respond to 3rd-party permission plugin events.
- [Added] Huawei-specific implementation for method isPowerSaveMode. Was always returning true.
- [Changed] Remove unnecessary android.exported on several AndroidManifest elements.
## 3.9.0 — 2020-08-20
- [Added][iOS] iOS 14 introduces a new switch on the initial location authorization dialog, allowing the user to "disable precise location". In support of this, a new method `BackgroundGeolocation.requestTemporaryFullAccuracy` has been added for requesting the user enable "temporary high accuracy" (until the next launch of your app), in addition to a new attribute `ProviderChangeEvent.accuracyAuthorization` for learning its state in the event `onProviderChange`:

```javascript
BackgroundGeolocation.onProviderChange((event) => {
print("[providerchange]", event);
// Did the user disable precise locadtion in iOS 14+?
if (event.accuracyAuthorization == BackgroundGeolocation.ACCURACY_AUTHORIZATION_REDUCED) {
// Supply "Purpose" key from Info.plist as 1st argument.
BackgroundGeolocation.requestTemporaryFullAccuracy("DemoPurpose").then((accuracyAuthorization) => {
if (accuracyAuthorization == BackgroundGeolocation.ACCURACY_AUTHORIZATION_FULL) {
console.log("[requestTemporaryFullAccuracy] GRANTED:", accuracyAuthorization);
} else {
console.log("[requestTemporaryFullAccuracy] DENIED:", accuracyAuthorization);
}
}).catch((error) => {
console.log("[requestTemporaryFullAccuracy] FAILED TO SHOW DIALOG:", error);
});
}
}
```
These changes are fully compatible with Android, which will always return `BackgroundGeolocation.ACCURACY_AUTHORIZATION_FULL`
- [Added][Android] Add `onChange` listener for `Config.locationAuthorizationRequest` to request location-authorization.
- [Changed][iOS] If `locationAuthorizationRequest == 'WhenInUse'` and the user has granted the higher level of `Always` authorization, do not show `locationAuthorizationAlert`.
- [Changed][iOS] When `locationAuthorizationRequest: 'Always'`, the SDK will now initially request `WhenInUse` followed immediately with another request for `Always`, rather than having to wait an unknown length of time for iOS to show the authorization upgrade dialog:
- [Added][iOS] Apple has changed the behaviour of location authorization — if an app initially requests `When In Use` location authorization then later requests `Always` authorization, iOS will *immediately* show the authorization upgrade dialog (`[Keep using When in Use`] / `[Change to Always allow]`).
__Example__
```javascript
componentDidMount() {
BackgroundGeolocation.ready({
locationAuthorizationRequest: 'WhenInUse',
.
.
.
});
}
async onClickStartTracking() {
await BackgroundGeolocation.start();
//
// some time later -- could be immediately after, hours later, days later, etc.
//
// Simply update `locationAuthorizationRequest` to "Always" -- the SDK will cause iOS to automatically show the authorization upgrade dialog.
BackgroundGeolocation.setConfig({
locationAuthorizationRequest: 'Always'
});
}
```

- [Fixed][iOS] when `getCurrentPosition` is provided with `extras`, those `extras` overwrite any configured `Config.extras` rather than merging.
- [Fixed][Android] When cancelling Alarms, use `FLAG_UPDATE_CURRENT` instead of `FLAG_CANCEL_CURRENT` -- there are [reports](https://stackoverflow.com/questions/29344971/java-lang-securityexception-too-many-alarms-500-registered-from-pid-10790-u) of older Samsung devices failing to garbadge-collect Alarms, causing the number of alarms to exceed maximum 500, generating an exception.
[Fixed][Android] Modify `isMainActivityActive` code to look specifically for `MainActivity` instead of any activity. Some apps might use their own custom activity during headless operation.
## 3.8.1 - 2020-07-13
- [Fixed][iOS] Geofence `EXIT` sometimes not firing when using `notifyOnDwell`.
- [Changed][Android] Refactor geofencing-only mode to not initiate "Infinite Geofencing" when the total number of added geofences is `< 99` (the maximum number of simultaneous geofences that can be monitored on Android). This prevents the SDK from periodically requesting location to query "geofences within `geofenceProximityRadius`". iOS already has this behaviour (where its maximum simultaneous geofences is `19`).
- [Fixed][iOS] When using `#ready` with `reset: true` (the default), and `autoSync: false`, the SDK could initiate HTTP service if any records exist within plugin's SQLite database, since `reset: true` causes `autoSync: true` for a fraction of a millisecond, initiating the HTTP Service.
- [Fixed][Android] :warning: `com.android.tools.build:gradle:4.0.0` no longer allows "*direct local aar dependencies*". The Android Setup now requires a custom __`maven url`__ to be added to your app's root __`android/build.gradle`__:
```diff
allprojects {
repositories {
mavenLocal()
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url("$rootDir/../node_modules/react-native/android")
}
maven {
// Android JSC is installed from npm
url("$rootDir/../node_modules/jsc-android/dist")
}
+ maven {
+ // Required for react-native-background-geolocation
+ url("${project(':react-native-background-geolocation-android').projectDir}/libs")
+ }
+ maven {
+ // Required for react-native-background-fetch
+ url("${project(':react-native-background-fetch').projectDir}/libs")
+ }
+ }
}
```
- [Fixed][Android] `onConnectivityChange` can report incorrect value for `enabled` when toggling between Wifi Off / Airplane mode.
- [Added][Android] New Config option `Notification.sticky` (default `false`) for allowing the Android foreground-service notification to be always shown. The default behavior is the only show the notification when the SDK is in the *moving* state, but Some developers have expressed the need to provide full disclosure to their users when the SDK is enabled, regardless if the device is stationary with location-services OFF.
- [Added] Support for providing a native "beforeInsert" block in iOS `AppDelegate.m` and Android `MainApplication.java`. The returned object will be inserted into the SDK's SQLite database and uploaded to your `Config.url`.
__iOS__ `AppDelegate.m`
```obj-c
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
.
.
.
// [OPTIONAL] This block is called before a location is inserted into the background_geolocation SQLite database.
// - The returned NSDictionary will be inserted.
// - If you return nil, no record will be inserted.
TSLocationManager *bgGeo = [TSLocationManager sharedInstance];
bgGeo.beforeInsertBlock = ^NSDictionary *(TSLocation *tsLocation) {
CLLocation *location = tsLocation.location;
NSLog(@"[beforeInsertBlock] %@: %@", tsLocation.uuid, location);
// Return a custom schema or nil to cancel SQLite insert.
return @{
@"lat": @(location.coordinate.latitude),
@"lng": @(location.coordinate.longitude),
@"battery": @{
@"level": tsLocation.batteryLevel,
@"is_charging": @(tsLocation.batteryIsCharging)
}
};
};
return YES;
}
```
__Android__ `MainApplication.java`
```java
public class MainApplication extends Application implements ReactApplication {
@Override
public void onCreate() {
super.onCreate();
.
.
.
// [OPTIONAL] This block is called before a location is inserted into the background_geolocation SQLite database.
// - The returned NSDictionary will be inserted.
// - If you return nil, no record will be inserted.
BackgroundGeolocation.getInstance(this).setBeforeInsertBlock(new TSBeforeInsertBlock() {
@Override
public JSONObject onBeforeInsert(TSLocation tsLocation) {
Location location = tsLocation.getLocation();
JSONObject json = new JSONObject();
JSONObject battery = new JSONObject();
try {
json.put("lat", location.getLatitude());
json.put("lng", location.getLongitude());
battery.put("level", tsLocation.getBatteryLevel());
battery.put("is_charging", tsLocation.getBatteryIsCharging());
json.put("battery", battery);
return json;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
});
}
}
```
## 3.7.0 - 2020-05-28
- [Fixed][Android] `onGeofence` event-handler fails to be fired when `maxRecordsToPersist: 0`.
- [Fixed][Android] `requestPermission` method was always returning `AUTHORIZATION_STATUS_ALWAYS` even when *When in Use* was selected.
- [Fixed][Android] Android plugin was importing an `androidx` dependency `localbroadcastmanager` without first checking if `useAndroidX` was set to `true`.
- [Fixed][iOS] When using `disableStopDetection: true` with `pausesLocationUpdatesAutomatically: true`, the `CLLocationManagerDelegate didPauseLocationUpdates` the `motionchange` event reported `isMoving: true`.
- [Fixed][Android] Ensure location failure callback is executed on main-thread.
- [Changed][Android] Gradle import `tslocationmanager.aar` using `api` rather than `implementation` in order to allow overrides in `AndroidManifest.xml`.
- [Fixed][iOS] When upgrading from a version previous to `3.4.0`, if any records exist within plugin's SQLite database, those records could fail to be properly migrated to new schema.
- [Added] New method `BackgroundGeolocation.destroyLocation(uuid)` for destroying a single location by `Location.uuid`.
- [Fixed] Allow firebase-adapter to validate license flavors on same key (eg: .development, .staging).
- [Fixed] iOS geofence listeners on `onGeofence` method *could possibly* fail to be called when a geofence event causes iOS to re-launch the app in the background (this would **not** prevent the plugin posting the geofence event to your `Config.url`, only a failure of the Javascript `onGeofence` to be fired).
- [Changed] Android library `tslocationmanager.aar` is now compiled using `androidx`. For backwards-compatibility with those how haven't migrated to `androidX`, a *reverse-jetified* build is included. Usage is detected automatically based upon `android.useAndroidX` in one's `gradle.properties`.
## 3.6.2 - 2020-04-08
- [Added] [Android] Add new `Config.motionTriggerDelay (milliseconds)` for preventing false-positive triggering of location-tracking (while walking around one's house, for example). If the motion API triggers back to `still` before `motionTriggerDelay` expires, triggering to the *moving* state will be cancelled.
- [Fixed] Address issue with rare reports of iOS crashing with error referencing `SOMotionDetector.m`.
- [Fixed] Odometer issue with Android/iOS: Do not persist `lastOdometerLocation` when plugin is disabled.
- [Added] iOS `Config.showsBackgroundLocationIndicator`, A Boolean indicating whether the status bar changes its appearance when an app uses location services in the background.
- [Changed] `cordova-plugin-background-fetch` dependency updated to `3.x` with new iOS 13 `BGTaskScheduler` API.
- [Fixed] `synchronize` methods in `TSLocationManager` to address Android NPE related to `buildTSLocation`.
- [Fixed] Typescript declaration for `Location.isMoving` should be `Location.is_moving`.
- [Fixed] iOS: Bug in `accessToken` RegExp in Authorization token-refresh handler.
- [Fixed] Part of the raw Javascript API contained typescript, which would cause an error on older mobile browser versions.
- [Added] Implement four new RPC commands `addGeofence`, `removeGeofence`, `addGeofences`, `removeGeofences`. Document available RPC commands in "HttpGuide".
- [Fixed] Android: launch-Intent for foreground-service notification was causing notification-click to re-launch the Activity rather than show existing.
- [Changed] Android: Modify behaviour of geofences-only mode to not periodically request location-updates. Will use a stationary-geofence of radius geofenceProximityRadius/2 as a trigger to re-evaluate geofences in proximity.
- [Changed] iOS: Prefix FMDB method-names `databasePool` -> `ts_databasePool` after reports of apps being falsely rejected by Apple for "private API usage".
- [Fixed] Android: Ensure that `location.hasSpeed()` before attempting to use it for distanceFilter elasticity calculations. There was a report of a Device returning `Nan` for speed.
- [Fixed] Android: Do not throttle http requests after http connect failure when configured with `maxRecordsToPersist`.
- [Fixed] Android: Respect `disableLocationAuthorizationAlert` for all cases, including `getCurrentPosition`.
- [Changed] Android: Modify behaviour of geofences-only mode to not periodically request location-updates. Will use a stationary-geofence of radius geofenceProximityRadius/2 as a trigger to re-evaluate geofences in proximity.
- [Changed] Authorization `refreshUrl` will post as application/x-www-form-urlencoded instead of form/multipart
- [Changed] iOS geofencing mode will not engage Significant Location Changes API when total geofence count <= 18 in order to prevent new iOS 13 "Location summary" popup from showing frequent location access.
- [Fixed] Android: Add hack for older devices to fix "GPS Week Rollover" bug where incorrect timestamp is recorded from GPS (typically where year is older by 20 years).
- [Fixed] When determining geofences within `geofenceProximityRadius`, add the `location.accuracy` as a buffer against low-accuracy locations.
- [Changed] Increase default `geofenceProximityRadius: 2000`.
## 3.4.2 - 2019-12-03
- [Fixed] iOS crash when launching first time `-[__NSDictionaryM setObject:forKey:]: object cannot be nil (key: authorization)'`
- [Changed] Remove Android warning `In order to enable encryption, you must provide the com.transistorsoft.locationmanager.ENCRYPTION_PASSWORD` when using `encrypt: false`.
- [Fixed] Added headless implementation for `geofenceschange` event.
## 3.4.1 - 2019-12-02
- [Fixed] Android bug rendering `Authorization.toJson` when no `Config.authorization` defined.
## 3.4.0 - 2019-12-02
- [Added] New `Config.authorization` option for automated authorization-token support. If the SDK receives an HTTP response status `401 Unauthorized` and you've provided an `authorization` config, the plugin will automatically send a request to your configured `refreshUrl` to request a new token. The SDK will take care of adding the required `Authorization` HTTP header with `Bearer accessToken`. In the past, one would manage token-refresh by listening to the SDK's `onHttp` listener for HTTP `401`. This can now all be managed by the SDK by providing a `Config.authorization`.
- [Added] Implemented strong encryption support via `Config.encrypt`. When enabled, the SDK will encrypt location data in its SQLite datbase, as well as the payload in HTTP requests. See API docs `Config.encrypt` for more information, including the configuration of encryption password.
- [Added] New JSON Web Token API for the Demo server at http://tracker.transistorsoft.com. It's now easier than ever to configure the plugin to post to the demo server. See API docs `Config.transistorAuthorizationToken`. The old method using `BackgroundGeolocation.transistorTrackerParams` is now deprecated.
- [Added] New `DeviceInfo` module for providing simple device-info (`model`, `manufacturer`, `version`, `platform`).
## 3.3.2 - 2019-10-25
- [Fixed] Android bug in params order to getLog. Thanks @mikehardy.
- [Fixed] Typo in Javascript API callback in `destroyLog`. Thanks @mikehardy.
## 3.3.1 - 2019-10-23
- [Fixed] Android NPE
```
Caused by: java.lang.NullPointerException:
at com.transistorsoft.locationmanager.service.TrackingService.b (TrackingService.java:172)
at com.transistorsoft.locationmanager.service.TrackingService.onStartCommand (TrackingService.java:135)
```
- [Added] new `uploadLog` feature for uploading logs directly to a server. This is an alternative to `emailLog`.
- [Changed] Migrated logging methods `getLog`, `destroyLog`, `emailLog` to new `Logger` module available at `BackgroundGeolocation.logger`. See docs for more information. Existing log methods on `BackgroundGeolocation` are now `@deprecated`.
- [Changed] All logging methods (`getLog`, `emailLog` and `uploadLog`) now accept an optional `SQLQuery`. Eg:
```javascript
let query = {
start: Date.parse('2019-10-23 09:00'),
end: Date.parse('2019-10-23 19:00'),
limit: 1000,
order: Logger.ORDER_ASC
};
let Logger = BackgroundGeolocation.logger;
let log = await Logger.getLog(query)
Logger.emailLog('foo@bar.com', query);
Logger.uploadLoad('http://your.server.com/logs', query);
```
## 3.3.0 - 2019-10-17
- [Fixed] Android: Fixed issue executing `#changePace` immediately after `#start`.
- [Fixed] Android: Add guard against NPR in `calculateMedianAccuracy`
- [Added] Add new Geofencing methods: `#getGeofence(identifier)` and `#geofenceExists(identifier)`.
- [Fixed] iOS issue using `disableMotionActivityUpdates: false` with `useSignificantChangesOnly: true` and `reset: true`. Plugin will accidentally ask for Motion Permission. Fixes #1992.
- [Fixed] Resolved a number of Android issues exposed by booting the app in [StrictMode](https://developer.android.com/reference/android/os/StrictMode). This should definitely help alleviate ANR issues related to `Context.startForegroundService`.
- [Added] Android now supports `disableMotionActivityUpdates` for Android 10 which now requires run-time permission for "Physical Activity". Setting to `true` will not ask user for this permission. The plugin will fallback to using the "stationary geofence" triggering, like iOS.
- [Changed] Android: Ensure all code that accesses the database is performed in background-threads, including all logging (addresses `Context.startForegroundService` ANR issue).
- [Changed] Android: Ensure all geofence event-handling is performed in background-threads (addresses `Context.startForegroundService` ANR issue).
- [Added] Android: implement logic to handle operation without Motion API on Android 10. v3 has always used a "stationary geofence" like iOS as a fail-safe, but this is now crucial for Android 10 which now requires run-time permission for "Physical Activity". For those users who [Deny] this permission, Android will trigger tracking in a manner similar to iOS (ie: requiring movement of about 200 meters). This also requires handling to detect when the device has become stationary.
## [3.2.2] - 2019-09-18
- [Changed] Android: move more location-handling code into background-threads to help mitigate against ANR referencing `Context.startForegroundService`
- [Changed] Android: If BackgroundGeolocation adapter is instantiated headless and is enabled, force ActivityRecognitionService to start.
- [Added] Add `mock` to `locationTemplate` data.
- [Changed] Android now hosts its own `proguard-rules.pro`. See Android setup docs for new integration of plugin's required Proguard Rules into your app.
Replace `@available` macro with `SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO`.
- [Fixed] iOS 13 preventSuspend was not working with iOS 13. iOS has once again decreased the max time for UIApplication beginBackgroundTask from 180s down to 30s.
- [Changed] Upgrade `android-logback` dependency to `2.0.0`
- [Changed] Android: move some plugin initialization into background-threads (eg: `performLogCleanup`) to help mitigate against ANR "`Context.startForegroundService` did not then call `Service.startForeground`".
- [Fixed] Android Initial headless events can be missed when app booted due to motion transition event.
- [Fixed] Android crash with EventBus `Subscriber already registered error`.
- [Fixed] iOS `Crash: [TSHttpService postBatch:error:] + 6335064 (TSHttpService.m:253)`
- [Changed] Minor changes to `build.gradle`: fetch `minSdkVersion` from `ext` instead of hard-coding, use `implementation` with `react` instead of `compileOnly`.
## [3.2.0] - 2019-08-16
- [Added] iOS 13 support.
- [Added] Auto-linking support. Do not use `react-native link` anymore. See the Setup docs for Android and iOS. Before installing `3.2.0`, first `react-native unlink` both `background-geolocation` and `background-fetch`.
:warning: If you have a previous version of **`react-native-background-geolocation-android < 3.2.0`** installed into **`react-native >= 0.60`**, you should first `unlink` your previous version as `react-native link` is no longer required.
```bash
$ react-native unlink react-native-background-geolocation-android
```
- [Fixed] Android Geofence `DWELL` transition (`notifyOnDwell: true`) not firing.
- [Fixed] iOS `logMaxDays` was hard-coded to `7`; Config option not being respected.
- [Added] Android `Q` support (API 29) with new iOS-like location permission model which now requests `When In Use` or `Always`. Android now supports the config option `locationAuthorizationRequest` which was traditionally iOS-only. Also, Android Q now requires runtime permission from user for `ACTIVITY_RECOGNITION`.
- [Changed] Another Android tweak to mitigate against error `Context.startForegroundService() did not then call Service.startForeground()`.
- [Added] Add new Android gradle config parameter `appCompatVersion` to replace `supportLibVersion` for better AndroidX compatibility. If `appCompatVersion` is not found, the plugin's gradle file falls back to `supportLibVersion`. For react-native@0.60, you should start using the new `appCompatVersion`.
## [3.0.9] - 2019-07-06
[Changed] Implement `react-native.config.js` ahead of deprecated `rnpm` config.
- [Fixed] Added logic to detect when app is configured to use **AndroidX** dependencies, adjusting the required `appcompat` dependency accordingly. If the gradle config `ext.supportLibVersion` corresponds to an AndroidX version (eg: `1.0.0`), the plugin assumes AndroidX.
- [Changed] Remove `cocoa-lumberjack` as a dependency since `react-native >= 0.60.0` iOS apps are all Cocoapods now. There's no longer a need for this dependency now since the plugin's podspec can import `CocoaLumberjack` pod directly. This is going to cause short-term pain for those using `< 0.60.0`, forcing one to manually install `cocao-lumberjack`.
- [Fixed] iOS / Android issues with odometer and `getCurrentPosition` when used with `maximumAge` constraint. Incorrect, old location was being returned instead of latest available.
- [Fixed] Some Android methods were executing the callback in background-thread, exposed when using flutter dev channel (`#insertLocation`, `#getLocations`, `#getGeofences`, `#sync`).
- [Fixed] Add `intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)` to `DeviceSettings` request for Android 9 compatibility.
- [Changed] Tweaks to Android services code to help guard against error `Context.startForegroundService() did not then call Service.startForeground()`.
- [Fixed] iOS manual `sync` crash in simulator while executing callback when error response is returned from server.
## [3.0.7] - 2019-06-17
- [Fixed] iOS & Android: Odometer issues: clear odometer reference location on `#stop`, `#startGeofences`.
- [Fixed] Odometer issues: Android must persist its odometer reference location since the foreground-service is no longer long-lived and the app may be terminated between motionchange events.
- [Fixed] Return `Service.START_REDELIVER_INTENT` from `HeartbeatService` to prevent `null` Intent being delivered to `HeartbeatService`, causing a crash.
- [Added] Implement Android [LocationSettingsRequest](https://developer.android.com/training/location/change-location-settings#get-settings). Determines if device settings is currently configured according to the plugin's desired-settings (eg: gps enabled, location-services enabled). If the device settings differs, an automatic dialog will perform the required settings changes automatically when user clicks [OK].
- [Fixed] Android `triggerActivities` was not implemented refactor of `3.x`.
## [3.0.6] - 2019-06-04
- [Changed] Bump `CocoaLumberjack` dependency to `~> 3.5.1`.
- [Fixed] Android `destroyLocations` callback was being executed in background-thread.
- [Fixed] When Android geofence API receives a `GEOFENCE_NOT_AVAILABLE` error (can occur if Wifi is disabled), geofences must be re-registered.
- [Fixed] Android `Config.disableStopDetection` was not implemented.
- [Added] Add new Android Config options `scheduleUseAlarmManager` for forcing scheduler to use `AlarmManager` insead of `JobService` for more precise scheduling.
## [3.0.5] - 2019-05-10
- [Changed] Rollback `android-permissions` version back to `0.1.8`. It relies on `support-annotations@28`. This isn't a problem if one simply upgrades their `targetSdkVersion` but the support calls aren't worth the hassle, since the latest version doesn't offer anything the plugin needs.
## [3.0.4] - 2019-05-08
- [Fixed] iOS: changing `pauseslocationUpdatesAutomatically` was not being applied.
- [Changed] `reset` parameter provided to `#ready` has now been default to `true`. This causes too many support issues for people using the plugin the first time.
- [Fixed] Android threading issue where 2 distinct `SingleLocationRequest` were issued the same id. This could result in the foreground service quickly starting/stopping until `locationTimeout` expired.
- [Fixed] Android issue where geofences could fail to query for new geofences-in-proximity after a restart.
- [Fixed] Android issues re-booting device with location-services disabled or location-authorization revoked.
- [Added] Implement support for [Custom Android Notification Layouts](/../../wiki/Android-Custom-Notification-Layout).
- [Fixed] Android bug where service repeatedly starts/stops after rebooting the device with plugin in *moving* state.
- [Fixed] Android headless `heartbeat` events were failing (incorrect `Context` was supplied to the event).
## [3.0.2] - 2019-04-18
- [Fixed] Windows bug in new `react-native link` script.
- [Fixed] Android scheduler bug. When app is terminated & restarted during a scheduled ON period, tracking-service does not restart.
## [3.0.1] - 2019-04-15
- [Added] Added android implementation for `react-native link` script to automatically add the required `maven url` and `ext.googlePlayServicesLocationVersion`.
## [3.0.0]
- [Changed] Promote `3.0.0-rc.5` to `3.0.0`.
## [3.0.0-rc.5] - 2019-03-31
- [Fixed] Android: Another `NullPointerException` with `Bundle#getExtras`.
## [3.0.0-rc.4] - 2019-03-29
- [Fixed] Android `NullPointerException` with `Bundle#getExtras`.
- [Fixed] Android not persisting `providerchange` location when location-services re-enabled.
## [3.0.0-rc.3] - 2019-03-27
- [Fixed] An Android foreground-service is launched on first install and fails to stop.
## [3.0.0-rc.2] - 2019-03-27
- [Changed] Remove unused Gradle function.
## [3.0.0-rc.1] - 2019-03-27
------------------------------------------------------------------------------
### :warning: Breaking Changes
#### [Changed] The license format has changed. New `3.0.0` licenses are now available for customers in the [product dashboard](https://www.transistorsoft.com/shop/customers).

- For versions `< 3.0.0`, use *old* license keys.
- For versions `>= 3.0.0`, use *new* license keys.
#### [Changed] Proguard Rules.
- For those minifying their generated Android APK by enabling the following in your `app/build.gradle`,
```
/**
* Run Proguard to shrink the Java bytecode in release builds.
*/
def enableProguardInReleaseBuilds = true
```
You must add the following line to your `proguard-rules.pro`:
```
-keepnames class com.facebook.react.ReactActivity
```
See the full required Proguard config in the Android Setup Doc.
------------------------------------------------------------------------------
### Fixes
- [Fixed] Logic bugs in MotionActivity triggering between *stationary* / *moving* states.
- [Fixed] Remove iOS react-native `#include` cruft `if __has_include(“XXX.h”)` for support RN libs during their transition to using Frameworks. Fixes #669.
- [Fixed] iOS crash with configured `schedule`: `index 2 beyond bounds [0 .. 1]' was thrown`. Fixes #666.
- [Fixed] `NullPointerException in logger`. References #661.
### New Features
- [Added] Android implementation for `useSignificantChangesOnly` Config option. Will request Android locations **without the persistent foreground service**. You will receive location updates only a few times per hour:
#### `useSignificantChangesOnly: true`:

#### `useSignificantChangesOnly: false`:

- [Added] Android now implements a "stationary geofence", just like iOS. It currently acts as a secondary triggering mechanism along with the current motion-activity API. You will hear the "zap" sound effect when it triggers. This also has the fortunate consequence of allowing mock-location apps (eg: Lockito) of being able to trigger tracking automatically.
- [Added] The SDK detects mock locations and skips trigging the `stopTimeout` system, improving location simulation workflow.
- [Added] Android-only Config option `geofenceModeHighAccuracy` for more control over geofence triggering responsiveness. Runs a foreground-service during geofences-only mode (`#startGeofences`). This will, of course, consume more power.
```dart
await BackgroundGeolocation.ready({
geofenceModeHighAccuracy: true,
desiredAccuracy: BackgroundGeolocation.DESIRED_ACCURACY_MEDIUM,
locationUpdateInterval: 5000,
distanceFilter: 50
));
BackgroundGeolocation.startGeofences();
```
#### `geofenceModeHighAccuracy: false` (Default)
- Transition events are delayed in favour of lower power consumption.

#### `geofenceModeHighAccuracy: true`
- Transition events are nearly instantaneous at the cost of higher power consumption.

- [Added] Android implementation of `startBackgroundTask` / `stopBackgroundTask`.
```dart
int taskId = await BackgroundGeolocation.startBackgroundTask();
// Do any work you like -- it's guaranteed to run, regardless of background/terminated.
// Your task has exactly 30s to do work before the service auto-stops itself.
getDataFromServer('https://foo.bar.com').then((result) => {
// Be sure to always signal completion of your taskId.
BackgroundGeolocation.stopBackgroundTask(taskId);
}).catch((error) => {
// Be sure to always signal completion of your taskId.
BackgroundGeolocation.stopBackgroundTask(taskId);
});
```
Logging for Android background-tasks looks like this (when you see an hourglass, a foreground-service is active)
```
[BackgroundTaskManager onStartJob] ⏳ startBackgroundTask: 6
.
.
.
[BackgroundTaskManager$Task stop] ⏳ stopBackgroundTask: 6
```
- [Added] New custom Android debug sound FX. See the [Config.debug](https://transistorsoft.github.io/cordova-background-geolocation/interfaces/_cordova_background_geolocation_.config.html#debug) for a new decription of iOS / Android sound FX **including a media player to play each.**

:warning: These debug sound FX consume about **1.4MB** in the plugin's `tslocationmanager.aar`. These assets can easily be stripped in your `release` builds by adding the following gradle task to your `app/build.gradle` (I'm working on an automated solution within the context of the plugin's `build.gradle`; so far, no luck). [Big thanks](https://github.com/transistorsoft/react-native-background-geolocation-android/issues/667#issuecomment-475928108) to @mikehardy.
```gradle
/**
* Purge Background Geolocation debug sounds from release build.
*/
def purgeBackgroundGeolocationDebugResources(applicationVariants) {
applicationVariants.all { variant ->
if (variant.buildType.name == 'release') {
variant.mergeResources.doLast {
delete(fileTree(dir: variant.mergeResources.outputDir, includes: ['raw_tslocationmanager*']))
}
}
}
}
android {
//Remove debug sounds from BackgroundGeolocation plugin
purgeBackgroundGeolocationDebugResources(applicationVariants)
compileSdkVersion rootProject.ext.compileSdkVersion
.
.
.
}
```
### Removed
- [Changed] Removed Android config option **`activityRecognitionInterval`** and **`minimumActivityRecognitionConfidence`**. The addition of the new "stationary geofence" for Android should alleviate issues with poor devices failing to initiate tracking. The Android SDK now uses the more modern [ActivityTransistionClient](https://medium.com/life360-engineering/beta-testing-googles-new-activity-transition-api-c9c418d4b553) API which is a higher level wrapper for the traditional [ActivityReconitionClient](https://developers.google.com/android/reference/com/google/android/gms/location/ActivityRecognitionClient). `AcitvityTransitionClient` does not accept a polling `interval`, thus `actiivtyRecognitionInterval` is now unused. Also, `ActivityTransitionClient` emits similar `on_foot`, `in_vehicle` events but no longer provides a `confidence`, thus `confidence` is now reported always as `100`. If you've been implementing your own custom triggering logic based upon `confidence`, it's now pointless. The `ActivityTransitionClient` will open doors for new features based upon transitions between activity states.
```
╔═════════════════════════════════════════════
║ Motion Transition Result
╠═════════════════════════════════════════════
╟─ 🔴 EXIT: walking
╟─ 🎾 ENTER: still
╚═════════════════════════════════════════════
```
### Maintenance
- [Changed] Update `android-permissions` dependency to `0.1.8`.
## [3.0.0-beta.5] - 2019-03-20
- [Fixed] Logic bugs in MotionActivity triggering between *stationary* / *moving* states.
- [Added] Android-only Config option `geofenceModeHighAccuracy` for more control over geofence triggering accuracy. Runs a foreground-service during geofences-only mode (`#startGeofences`).
- [Added] Android implementation for `useSignificantChangesOnly` Config option. Will request Android locations **without the persistent foreground service**. You will receive location updates only a few times per hour.
- [Changed] Update `android-permissions` dependency to `0.1.8`.
## [3.0.0-beta.4] - 2019-03-02
- [Fixed] Android bug in Config dirty-fields mechanism.
## [3.0.0-beta.3] - 2019-03-02
- [Changed] Improve trackingMode state-changes between location -> geofences-only.
- [Changed] Improvements to geofences-only tracking.
- [Changed] Improvements to stationary-geofence monitoring, detecting mock locations to prevent stopTimeout triggering.
## [3.0.0-beta.2] - 2019-02-28
- [Changed] Tweaking stationary region monitoring.
- [Changed] Tweaking bad vendor detection to force stopTimeout timer when device is stationary for long periods and motion api hasn't respon
ded.
## [3.0.0-beta.1] - 2019-02-27
- [Changed] Major refactor of Android Service architecture. The SDK no longer requires a foreground-service active at all times. The foreground-service (and cooresponding persistent notification) will only be active while the SDK is in the *moving* state. No breaking dart api changes.
- [Changed] Improved Android debug notifications.
- [Added] Added new Config options `persistMode` for specifying exactly which events get persisted: location | geofence | all | none.
- [Added] Experimental Android-only Config option `speedJumpFilter (default 300 meters/second)` for detecting location anomalies. The plugin will measure the distance and apparent speed of the current location relative to last location. If the apparent speed is > `speedJumpFilter`, the location will be ignored. Some users, particularly in Australia, curiously, have had locations suddenly jump hundreds of kilometers away, into the ocean.
- [Changed] iOS and Android will not perform odometer updates when the calculated distance is less than the average accuracy of the current and previous location. This is to prevent small odometer changes when the device is lingering around the same position.
- [Fixed] Added Android gradle dependency `appcompat-v7`
- [Fixed] Minor change to Android `HeadlessTask` to fix possible issue with `Looper`.
- [Added] New `DeviceSettings` API for redirecting user to Android Settings screens, including vendor-specific screens (eg: Huawei, OnePlus, Xiaomi, etc). This is an attempt to help direct the user to appropriate device-settings screens for poor Android vendors as detailed in the site [Don't kill my app](https://dontkillmyapp.com/).
- [Added] `schedule` can now be configured to optionally execute geofences-only mode (ie: `#startGeofences`) per schedule entry. See `schedule` docs.
- [Changed] Update Gradle config to use `implementation` instead of deprecated `compile`
- **[BREAKING]** Change Gradle `ext` configuration property `googlePlayServicesVersion` -> `googlePlayServicesLocationVersion`. Now that Google has decoupled all their libraries, `play-services:location` now has its own version, independant of all other libs.
`android/build.gradle`:
```diff
buildscript {
ext {
buildToolsVersion = "28.0.3"
minSdkVersion = 16
compileSdkVersion = 28
targetSdkVersion = 27
supportLibVersion = "28.0.0"
- googlePlayServicesVersion = "16.0.0"
+ googlePlayServicesLocationVersion = "16.0.0"
}
}
```
- [Changed] Android Service: Return `START_STICKY` instead of `START_REDELIVER_INTENT`.
- [Changed] Android: `setShowBadge(false)` on Android `NotificationChannel`. Some users reporting that Android shows a badge-count on app icon when service is started / stopped.
- [Fixed] Android `extras` provided to `watchPosition` were not being appended to location data.
- [Fixed] Android NPE in `watchPosition`
- [Added] Added method `getProviderState` for querying current state of location-services.
- [Added] Added method `requestPermission` for manually requesting location-permission (`#start`, `#getCurrentPosition`, `#watchPosition` etc, will already automatically request permission.
- [Changed] Upgrade Android logger dependency to latest version (`logback`).
- [Fixed] Prevent Android foreground-service from auto-starting when location permission is revoked via Settings screen.
- [Fixed] NPE in Android HTTP Service when manual sync is called. Probably a threading issue with multiple sync operations executed simultaneously.
## [2.14.2] 2018-11-20
- [Added] Android SDK 28 requires new permission to use foreground-service.
- [Fixed] Do not calculate odometer with geofence events. Android geofence event's location timestamp does not correspond with the actual time the geofence fires since Android is performing some heuristics in the background to ensure the potential geofence event is not a false positive. The actual geofence event can fire some minutes in the future (ie: the location timestamp will be some minutues in the past). Using geofence location in odometer calculations will corrupt the odometer value.
- [Fixed] Android could not dynamically update the `locationTemplate` / `geofenceTemplate` without `#stop` and application restart.
- [Fixed] Android `startGeofences` after revoking & re-granting permission would fail to launch the plugin's Service.
- [Fixed] iOS HTTP crash when using `batchSync: true`. At application boot, there was a threading issue if the server returned an HTTP error, multiple instances of the HTTP service could run, causing a crash.
## [2.14.1] 2018-10-29
- [Fixed] react-native link on Windows.
## [2.14.0] 2018-10-29
- [Fixed] Android `NullPointerException` on `WatchPositionCallback` with `watchPosition`.
## [2.14.0-beta.3] 2018-10-26
- [Fixed] Mistake in module-name in index.d.ts
## [2.14.0-beta.2] 2018-10-24
- [Fixed] Documentation issue with method signature `getCurrentPosition`.
- [iOS] Catch `NSInvalidArgumentException` when decoding `TSConfig`.
- [Fixed] `react-native link` scripts were accidentally `.npmignore`d causing error `Unhandled 'error' event` when linking.
## [2.14.0-beta.1] 2018-10-19
- [Added] Implement [Typescript API](https://facebook.github.io/react-native/blog/2018/05/07/using-typescript-with-react-native)
- [Added] Refactor documentation. Now auto-generated from Typescript api with [Typedoc](https://typedoc.org/) and served from https://transistorsoft.github.io/react-native-background-geolocation
- [Breaking] Change event-signature of `location` event: location-errors are now received in new `failure` callback rather than separate `error` event. The `error` event has been removed.
```javascript
BackgroundGeolocation.onLocation((location) => {
console.log('[location] -', location);
}, (errorCode) => {
// Location errors received here.
console.log('[location] ERROR -', errorCode);
});
```
- [Added] With the new Typescript API, it's necessary to add dedicated listener-methods for each method (in order for code-assist to work).
```javascript
// Old: No code-assist for event-signature with new Typescript API
BackgroundGeolocation.on('location', (location) => {}, (error) => {});
// New: use dedicated listener-method #onLocation
BackgroundGeolocation.onLocation((location) => {}, (error) => {});
// And every other event:
BackgroundGeolocation.onMotionChange(callback);
BackgroundGeolocation.onMotionProviderChange(callback);
BackgroundGeolocation.onActivityChange(callback);
BackgroundGeolocation.onHttp(callback);
BackgroundGeolocation.onGeofence(callback);
BackgroundGeolocation.onGeofencesChange(callback);
BackgroundGeolocation.onSchedule(callback);
BackgroundGeolocation.onConnectivityChange(callback);
BackgroundGeolocation.onPowerSaveChange(callback);
BackgroundGeolocation.onEnabledChange(callback);
```
- [Breaking] Change event-signature of `enabledchange` event to return simple `boolean` instead of `{enabled: true}`: It was pointless to return an `{}` for this event.
```javascript
// Old
BackgroundGeolocation.onEnabledChange((enabledChangeEvent) => {
console.log('[enabledchange] -' enabledChangeEvent.enabled);
})
// New
BackgroundGeolocation.onEnabledChange((enabled) => {
console.log('[enabledchange] -' enabled);
})
```
- [Breaking] Change signature of `#getCurrentPosition` method: Options `{}` is now first argument rather than last:
```javascript
// Old (Options as 3rd argument)
BackgroundGeolocation.getCurrentPosition((location) => {
console.log('[getCurrentPosition] -', location);
}, (error) => {
console.log('[getCurrentPosition] ERROR -', error);
}, { // <-- Options as 3rd argument
samples: 3,
extras: {foo: 'bar'}
})
// New (Options as 1st argument)
BackgroundGeolocation.getCurrentPosition({
samples: 3,
extras: {foo: 'bar'}
}, (location) => {
console.log('[getCurrentPosition] -', location);
}, (error) => {
console.log('[getCurrentPosition] ERROR -', error);
})
```
## [2.13.4] - 2018-10-01
- [Fixed] iOS was missing Firebase adapter hook for persisting geofences.
- [Changed] Android headless events are now posted with using `EventBus` instead of `JobScheduler`. Events posted via Android `JobScheduler` are subject to time-slicing by the OS so events could arrive late.
- [Fixed] Missing `removeListeners` for `connectivitychange`, `enabledchange` events.
- [Fixed] iOS was not calling `success` callback for `removeListeners`.
- [Fixed] iOS plugin was not parsing schedule in `#ready` event.
## [2.13.4] - 2018-10-01
- [Fixed] iOS was missing Firebase adapter hook for persisting geofences.
- [Changed] Android headless events are now posted with using `EventBus` instead of `JobScheduler`. Events posted via Android `JobScheduler` are subject to time-slicing by the OS so events could arrive late.
- [Fixed] Missing `removeListeners` for `connectivitychange`, `enabledchange` events.
- [Fixed] iOS was not calling `success` callback for `removeListeners`.
- [Fixed] iOS plugin was not parsing schedule in `#ready` event.
## [2.13.3] - 2018-08-30
- [Fixed] Minor error in plugin's `build.gradle`. `DEFAULT_BUILD_TOOLS_VERSION` was set incorrectly.
## [2.13.2] - 2018-08-29
- [Fixed] iOS scheduler not being initialized in `#ready` after reboot.
## [2.13.1] - 2018-08-17
- [Fixed] Android firebase plugin bug in release build.
## [2.13.0] - 2018-08-15
- [Added] New Android config-option `notificationChannelName` for configuring the notification-channel required by the foreground-service notification. See *Settings->Apps & Notificaitions->Your App->App Notifications*.
- [Added] Support for new [Firebase Adapter](https://github.com/transistorsoft/react-native-background-geolocation-firebase)
- [Added] iOS support for HTTP method `PATCH` (Android already supports it).
- [Fixed] Android was not using `httpTimeout` with latest `okht