Please support my work and support continuous development by your donation.
React Native fork of cordova-plugin-background-geolocation with battery-saving "circular region monitoring" and "stop detection".
Plugin can be used for geolocation when app is running in foreground or background.
You can choose from following location providers:
- DISTANCE_FILTER_PROVIDER
- ACTIVITY_PROVIDER (Android only)
- RAW_PROVIDER
See Which provider should I use? for more information about providers.
- start method doesn't accept callback (use .on("start") event)
- stop method doesn't accept callback (use .on("stop") event)
- for background syncing syncUrl option is required. In version 0.3.x if syncUrl was not set url was used.
- plugin constants are in directly BackgroundGeolocation namespace. (check index.js)
- location property locationId renamed to just id
- iOS pauseLocationUpdates now default to false (becuase iOS docs now states that you need to restart manually if you set it to true)
- iOS no more requires to call finish method. Instead you can optionally start long running task with startTask
Due to the rapid changes being made in the React Native ecosystem, this module will support only latest version of React Native. Older versions will only be supported, if they're compatible with this module.
Module | React Native |
---|---|
0.1.0 - 0.2.0 | 0.33 |
>=0.3.0 | >=0.47 |
If you are using an older version of React Native with this module some features may be buggy.
If you are using react-native-maps or another lib that requires react-native-maps such as Exponent.js or airbnb's react-native-maps then aditionally to the instalation steps described here, you must also change node_modules/react-native-mauron85-background-geolocation/android/lib/build.gradle
in order to gms:play-services-locations
match the same version used by those libraries. (in this case 9.8.0
)
dependencies {
...
compile 'com.google.android.gms:play-services-location:9.8.0'
...
}
All new issues should follow instructions in ISSUE_TEMPLATE.md.
Properly filled issue report will significantly reduce number of follow up questions and decrease issue resolving time.
Most issues cannot be resolved without debug logs. Please try to isolate debug lines related to your issue.
Instructions how to prepare debug logs can be found in section Debugging.
If you're reporting app crash, debug logs might not contain all needed informations about the cause of the crash.
In that case, also provide relevant parts of output of adb logcat
command.
Repository react-native-background-geolocation-example is hosting example app for both iOS and Android platform.
import React, { Component } from 'react';
import { Alert } from 'react-native';
import BackgroundGeolocation from 'react-native-mauron85-background-geolocation';
class BgTracking extends Component {
componentDidMount() {
BackgroundGeolocation.configure({
desiredAccuracy: 10,
stationaryRadius: 50,
distanceFilter: 50,
notificationTitle: 'Background tracking',
notificationText: 'enabled',
debug: true,
startOnBoot: false,
stopOnTerminate: false,
locationProvider: BackgroundGeolocation.ACTIVITY_PROVIDER,
interval: 10000,
fastestInterval: 5000,
activitiesInterval: 10000,
stopOnStillActivity: false,
url: 'http://192.168.81.15:3000/location',
httpHeaders: {
'X-FOO': 'bar'
}
});
BackgroundGeolocation.on('location', (location) => {
// handle your locations here
// to perform long running operation on iOS
// you need to create background task
BackgroundGeolocation.startTask(taskKey => {
// execute long running task
// eg. ajax post location
// IMPORTANT: task has to be ended by endTask
BackgroundGeolocation.endTask(taskKey);
});
});
BackgroundGeolocation.on('stationary', (stationaryLocation) => {
// handle stationary locations here
Actions.sendLocation(stationaryLocation);
});
BackgroundGeolocation.on('error', (error) => {
console.log('[ERROR] BackgroundGeolocation error:', error);
});
BackgroundGeolocation.on('start', () => {
console.log('[INFO] BackgroundGeolocation service has been started');
});
BackgroundGeolocation.on('stop', () => {
console.log('[INFO] BackgroundGeolocation service has been stopped');
});
BackgroundGeolocation.on('authorization', (status) => {
console.log('[INFO] BackgroundGeolocation authorization status: ' + status);
if (status !== BackgroundGeolocation.AUTHORIZED) {
Alert.alert('Location services are disabled', 'Would you like to open location settings?', [
{ text: 'Yes', onPress: () => BackgroundGeolocation.showLocationSettings() },
{ text: 'No', onPress: () => console.log('No Pressed'), style: 'cancel' }
]);
}
});
BackgroundGeolocation.on('background', () => {
console.log('[INFO] App is in background');
});
BackgroundGeolocation.on('foreground', () => {
console.log('[INFO] App is in foreground');
});
BackgroundGeolocation.checkStatus(status => {
console.log('[INFO] BackgroundGeolocation service is running', status.isRunning);
console.log('[INFO] BackgroundGeolocation service has permissions', status.hasPermissions);
console.log('[INFO] BackgroundGeolocation auth status: ' + status.authorization);
// you don't need to check status before start (this is just the example)
if (!status.isRunning) {
BackgroundGeolocation.start(); //triggers start on start event
}
});
// you can also just start without checking for status
// BackgroundGeolocation.start();
}
componentWillUnmount() {
// unregister all event listeners
BackgroundGeolocation.events.forEach(event => BackgroundGeolocation.removeAllListeners(event));
}
}
export default BgTracking;
Add package to your project
npm install react-native-mauron85-background-geolocation --save
In android/settings.gradle
...
include ':react-native-mauron85-background-geolocation', ':app'
project(':react-native-mauron85-background-geolocation').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-mauron85-background-geolocation/android/lib')
...
In android/app/build.gradle
dependencies {
...
compile project(':react-native-mauron85-background-geolocation')
...
}
In android/src/main/res/values/strings.xml
Properties @account_type
and @content_authority
should be prefixed with your application package class.
<resources>
<!-- Make sure you override following in your app res/values/strings.xml -->
<string name="app_name">APP_NAME</string>
<string name="account_type">com.yourcompany.account</string>
<string name="content_authority">com.yourcompany.authority</string>
</resources>
Register module (in MainApplication.java
)
import com.marianhello.react.BackgroundGeolocationPackage; // <--- Import Package
public class MainApplication extends Application implements ReactApplication {
...
/**
* A list of packages used by the app. If the app uses additional views
* or modules besides the default ones, add more packages here.
*/
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new BackgroundGeolocationPackage() // <---- Add the Package
);
}
...
}
You will need to ensure that you have installed the following items through the Android SDK Manager:
Name | Version |
---|---|
Android SDK Tools | 24.4.1 |
Android SDK Platform-tools | 23.1 |
Android SDK Build-tools | 23.0.1 |
Android Support Repository | 25 |
Android Support Library | 23.1.1 |
Google Play Services | 29 |
Google Repository | 24 |
- In XCode, in the project navigator, right click
Libraries
➜Add Files to [your project's name]
- add
./node_modules/react-native-mauron85-background-geolocation/ios/RCTBackgroundGeolocation.xcodeproj
- In the XCode project navigator, select your project, select the
Build Phases
tab and in theLink Binary With Libraries
section add libRCTBackgroundGeolocation.a - add
UIBackgroundModes
location toInfo.plist
For iOS before version 11:
- add
NSLocationAlwaysUsageDescription
App requires background tracking toInfo.plist
For iOS 11:
- add
NSLocationWhenInUseUsageDescription
App requires background tracking toInfo.plist
- add
NSLocationAlwaysAndWhenInUseUsageDescription
App requires background tracking toInfo.plist
Parameter | Type | Platform | Description |
---|---|---|---|
options |
JSON Object |
all | Configure options |
Configure options:
Parameter | Type | Platform | Description |
---|---|---|---|
locationProvider |
Number |
all | Set location provider @see PROVIDERS |
desiredAccuracy |
Number |
all | Desired accuracy in meters. Possible values [0, 10, 100, 1000]. The lower the number, the more power devoted to GeoLocation resulting in higher accuracy readings. 1000 results in lowest power drain and least accurate readings. @see Apple docs |
stationaryRadius |
Number |
all | Stationary radius in meters. When stopped, the minimum distance the device must move beyond the stationary location for aggressive background-tracking to engage. |
debug |
Boolean |
all | When enabled, the plugin will emit sounds for life-cycle events of background-geolocation! See debugging sounds table. |
distanceFilter |
Number |
all | The minimum distance (measured in meters) a device must move horizontally before an update event is generated. @see Apple docs. |
stopOnTerminate |
Boolean |
all | Enable this in order to force a stop() when the application terminated (e.g. on iOS, double-tap home button, swipe away the app). (default true) |
startOnBoot |
Boolean |
Android | Start background service on device boot. (default false) |
startForeground |
Boolean |
Android | If false location service will not be started in foreground and no notification will be shown. (default true) |
interval |
Number |
Android | The minimum time interval between location updates in milliseconds. @see [Android docs](http://developer.android.com/reference/android/location/LocationManager.html#requestLocationUpdates(long,%20float,%20android.location.Criteria,%20android.app.PendingIntent) for more information. |
notificationTitle |
String optional |
Android | Custom notification title in the drawer. |
notificationText |
String optional |
Android | Custom notification text in the drawer. |
notificationIconColor |
String optional |
Android | The accent color to use for notification. Eg. #4CAF50. |
notificationIconLarge |
String optional |
Android | The filename of a custom notification icon. See android quirks. |
notificationIconSmall |
String optional |
Android | The filename of a custom notification icon. See android quirks. |
activityType |
String |
iOS | [AutomotiveNavigation, OtherNavigation, Fitness, Other] Presumably, this affects iOS GPS algorithm. @see Apple docs for more information |
pauseLocationUpdates |
Boolean |
iOS | Pauses location updates when app is paused (default: false). *@see Apple docs |
saveBatteryOnBackground |
Boolean |
iOS | Switch to less accurate significant changes and region monitory when in background (default: true) |
url |
String |
all | Server url where to send HTTP POST with recorded locations @see HTTP locations posting |
syncUrl |
String |
all | Server url where to send fail to post locations @see HTTP locations posting |
syncThreshold |
Number |
all | Specifies how many previously failed locations will be sent to server at once (default: 100) |
httpHeaders |
Object |
all | Optional HTTP headers sent along in HTTP request |
maxLocations |
Number |
all | Limit maximum number of locations stored into db (default: 10000) |
Following options are specific to provider as defined by locationProvider option
Parameter | Type | Platform | Description |
---|---|---|---|
interval |
Number |
Android | Rate in milliseconds at which your app prefers to receive location updates. @see android docs |
fastestInterval |
Number |
Android | Fastest rate in milliseconds at which your app can handle location updates. @see android docs. |
activitiesInterval |
Number |
Android | Rate in milliseconds at which activity recognition occurs. Larger values will result in fewer activity detections while improving battery life. |
stopOnStillActivity |
Boolean |
Android | stop() is forced, when the STILL activity is detected (default is true) |
Location callback will be called with one argument - location object, which tries to mimic w3c Coordinates interface.
Callback parameter | Type | Description |
---|---|---|
id |
Number |
ID of location as stored in DB (or null) |
provider |
String |
gps, network, passive or fused |
locationProvider |
Number |
Location provider |
debug |
Boolean |
true if location recorded as part of debug |
time |
Number |
UTC time of this fix, in milliseconds since January 1, 1970. |
latitude |
Number |
latitude, in degrees. |
longitude |
Number |
longitude, in degrees. |
accuracy |
Number |
estimated accuracy of this location, in meters. |
speed |
Number |
speed if it is available, in meters/second over ground. |
altitude |
Number |
altitude if available, in meters above the WGS 84 reference ellipsoid. |
bearing |
Number |
bearing, in degrees. |
Note: Android currently returns time
as type of String (instead of Number) @see issue #9685
Platform: iOS, Android
Start background geolocation.
Platform: iOS, Android
Stop background geolocation.
Deprecated: This method is deprecated and will be removed in next major version.
Use checkStatus
as replacement.
Platform: iOS, Android
One time check for status of location services. In case of error, fail callback will be executed.
Success callback parameter | Type | Description |
---|---|---|
enabled |
Boolean |
true/false (true when location services are enabled) |
Check status of the service
Success callback parameter | Type | Description |
---|---|---|
isRunning |
Boolean |
true/false (true if service is running) |
hasPermissions |
Boolean |
true/false (true if service has permissions) |
authorization |
Number |
BackgroundGeolocation.{NOT_AUTHORIZED |
Platform: Android >= 6, iOS >= 8.0
Show app settings to allow change of app location permissions.
Platform: iOS, Android
Show system settings to allow configuration of current location sources.
Platform: iOS, Android
Method will return all stored locations. This method is useful for initial rendering of user location on a map just after application launch.
NOTE: Returned locations does not contain location.id.
Success callback parameter | Type | Description |
---|---|---|
locations |
Array |
collection of stored locations |
BackgroundGeolocation.getLocations(
function (locations) {
console.log(locations);
}
);
Platform: iOS, Android
Method will return locations, which has not been yet posted to server. NOTE: Locations does contain location.id.
Success callback parameter | Type | Description |
---|---|---|
locations |
Array |
collection of stored locations |
Platform: iOS, Android
Delete location with locationId.
Note: Locations are not actually deleted from database to avoid gaps in locationId numbering.
Instead locations are marked as deleted. Locations marked as deleted will not appear in output of BackgroundGeolocation.getLocations
.
Note: You don't need to delete all locations. Plugin manages number of locations automatically and location count never exceeds number as defined by option.maxLocations
.
Platform: iOS, Android
Delete all stored locations.
Platform: iOS
Normally plugin will handle switching between BACKGROUND and FOREGROUND mode itself. Calling switchMode you can override plugin behavior and force plugin to switch into other mode.
In FOREGROUND mode plugin uses iOS local manager to receive locations and behavior is affected
by option.desiredAccuracy
and option.distanceFilter
.
In BACKGROUND mode plugin uses significant changes and region monitoring to receive locations
and uses option.stationaryRadius
only.
// switch to FOREGROUND mode
BackgroundGeolocation.switchMode(BackgroundGeolocation.FOREGROUND_MODE);
// switch to BACKGROUND mode
BackgroundGeolocation.switchMode(BackgroundGeolocation.BACKGROUND_MODE);
Platform: Android, iOS
Return all logged events. Useful for plugin debugging.
Parameter limit
limits number of returned entries.
@see Debugging for more information.
Unregister all event listeners for given event
Event listeners can registered with:
const eventSubscription = BackgroundGeolocation.on('event', callbackFn);
And unregistered:
eventSubscription.remove();
Note: Components should unregister all event listeners in componentWillUnmount
method,
individually, or with removeAllListeners
Name | Callback param | Platform | Description |
---|---|---|---|
location |
Location |
all | on location update |
stationary |
Location |
all | on device entered stationary mode |
error |
{ code, message } |
all | on plugin error |
authorization |
status |
all | on user toggle location service |
start |
all | geolocation has been started | |
stop |
all | geolocation has been stopped | |
foreground |
android | app entered foreground state (visible) | |
background |
android | app entered background state |
All locations updates are recorded in local db at all times. When App is in foreground or background in addition to storing location in local db,
location callback function is triggered. Number of location stored in db is limited by option.maxLocations
a never exceeds this number.
Instead old locations are replaced by new ones.
When option.url
is defined, each location is also immediately posted to url defined by option.url
.
If post is successful, the location is marked as deleted in local db.
When option.syncUrl
is defined all failed to post locations will be coalesced and send in some time later in one single batch.
Batch sync takes place only when number of failed to post locations reaches option.syncTreshold
.
Locations are send only in single batch, when number of locations reaches option.syncTreshold
. (No individual location will be send)
Request body of posted locations is always array, even when only one location is sent.
Background-geolocation-server is a backend server written in nodejs. There are instructions how to run it and simulate locations on Android, iOS Simulator and Genymotion.
See DEBUGGING.md
Try using react-native-geo-fencing. Let's keep this plugin lightweight as much as possible.
See CHANGES.md