UNPKG

30.1 kBMarkdownView Raw
1# react-native-mauron85-background-geolocation
2
3# Donation
4
5Please support my work and support continuous development by your donation.
6
7[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6GW8FPTE6TV5J)
8
9## Description
10React Native fork of [cordova-plugin-background-geolocation](https://github.com/mauron85/cordova-plugin-background-geolocation)
11with battery-saving "circular region monitoring" and "stop detection".
12
13Plugin can be used for geolocation when app is running in foreground or background.
14
15You can choose from following location providers:
16* **DISTANCE_FILTER_PROVIDER**
17* **ACTIVITY_PROVIDER** (Android only)
18* **RAW_PROVIDER**
19
20See [Which provider should I use?](/PROVIDERS.md) for more information about providers.
21
22## Breaking changes
23
24### 0.4.x:
25
26* start method doesn't accept callback (use .on("start") event)
27* stop method doesn't accept callback (use .on("stop") event)
28* for background syncing syncUrl option is required. In version 0.3.x if syncUrl was not set url was used.
29* plugin constants are in directly BackgroundGeolocation namespace. (check index.js)
30* location property locationId renamed to just id
31* iOS pauseLocationUpdates now default to false (becuase iOS docs now states that you need to restart manually if you set it to true)
32* iOS no more requires to call finish method. Instead you can optionally start long running task with startTask
33
34## Compatibility
35
36Due to the rapid changes being made in the React Native ecosystem, this module will support
37only latest version of React Native. Older versions will only be supported, if they're
38compatible with this module.
39
40| Module | React Native |
41|------------------|-------------------|
42| 0.1.0 - 0.2.0 | 0.33 |
43| >=0.3.0 | >=0.47 |
44
45If you are using an older version of React Native with this module some features may be buggy.
46
47If 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`)
48
49```
50dependencies {
51 ...
52 compile 'com.google.android.gms:play-services-location:9.8.0'
53 ...
54}
55```
56
57## Submitting issues
58
59All new issues should follow instructions in [ISSUE_TEMPLATE.md](https://raw.githubusercontent.com/mauron85/react-native-background-geolocation/master/ISSUE_TEMPLATE.md).
60Properly filled issue report will significantly reduce number of follow up questions and decrease issue resolving time.
61Most issues cannot be resolved without debug logs. Please try to isolate debug lines related to your issue.
62Instructions how to prepare debug logs can be found in section [Debugging](#debugging).
63If you're reporting app crash, debug logs might not contain all needed informations about the cause of the crash.
64In that case, also provide relevant parts of output of `adb logcat` command.
65
66## Example Apps
67
68Repository [react-native-background-geolocation-example](https://github.com/mauron85/react-native-background-geolocation-example) is hosting example app for both iOS and Android platform.
69
70## Quick example
71
72```javascript
73import React, { Component } from 'react';
74import { Alert } from 'react-native';
75import BackgroundGeolocation from 'react-native-mauron85-background-geolocation';
76
77class BgTracking extends Component {
78 componentDidMount() {
79 BackgroundGeolocation.configure({
80 desiredAccuracy: 10,
81 stationaryRadius: 50,
82 distanceFilter: 50,
83 locationTimeout: 30,
84 notificationTitle: 'Background tracking',
85 notificationText: 'enabled',
86 debug: true,
87 startOnBoot: false,
88 stopOnTerminate: false,
89 locationProvider: BackgroundGeolocation.ACTIVITY_PROVIDER,
90 interval: 10000,
91 fastestInterval: 5000,
92 activitiesInterval: 10000,
93 stopOnStillActivity: false,
94 url: 'http://192.168.81.15:3000/location',
95 httpHeaders: {
96 'X-FOO': 'bar'
97 }
98 });
99
100 BackgroundGeolocation.on('location', (location) => {
101 // handle your locations here
102 // to perform long running operation on iOS
103 // you need to create background task
104 BackgroundGeolocation.startTask(taskKey => {
105 // execute long running task
106 // eg. ajax post location
107 // IMPORTANT: task has to be ended by endTask
108 BackgroundGeolocation.endTask(taskKey);
109 });
110 });
111
112 BackgroundGeolocation.on('stationary', (stationaryLocation) => {
113 // handle stationary locations here
114 Actions.sendLocation(stationaryLocation);
115 });
116
117 BackgroundGeolocation.on('error', (error) => {
118 console.log('[ERROR] BackgroundGeolocation error:', error);
119 });
120
121 BackgroundGeolocation.on('start', () => {
122 console.log('[INFO] BackgroundGeolocation service has been started');
123 });
124
125 BackgroundGeolocation.on('stop', () => {
126 console.log('[INFO] BackgroundGeolocation service has been stopped');
127 });
128
129 BackgroundGeolocation.on('authorization', (status) => {
130 console.log('[INFO] BackgroundGeolocation authorization status: ' + status);
131 if (status !== BackgroundGeolocation.AUTHORIZED) {
132 Alert.alert('Location services are disabled', 'Would you like to open location settings?', [
133 { text: 'Yes', onPress: () => BackgroundGeolocation.showLocationSettings() },
134 { text: 'No', onPress: () => console.log('No Pressed'), style: 'cancel' }
135 ]);
136 }
137 });
138
139 BackgroundGeolocation.on('background', () => {
140 console.log('[INFO] App is in background');
141 });
142
143 BackgroundGeolocation.on('foreground', () => {
144 console.log('[INFO] App is in foreground');
145 });
146
147 BackgroundGeolocation.checkStatus(status => {
148 console.log('[INFO] BackgroundGeolocation service is running', status.isRunning);
149 console.log('[INFO] BackgroundGeolocation service has permissions', status.hasPermissions);
150 console.log('[INFO] BackgroundGeolocation auth status: ' + status.authorization);
151
152 // you don't need to check status before start (this is just the example)
153 if (!status.isRunning) {
154 BackgroundGeolocation.start(); //triggers start on start event
155 }
156 });
157
158 // you can also just start without checking for status
159 // BackgroundGeolocation.start();
160 }
161
162 componentWillUnmount() {
163 // unregister all event listeners
164 BackgroundGeolocation.events.forEach(event => BackgroundGeolocation.removeAllListeners(event));
165 }
166}
167
168export default BgTracking;
169```
170
171## Instalation
172
173Add package to your project
174
175```
176npm install react-native-mauron85-background-geolocation --save
177```
178
179### Android setup
180
181In `android/settings.gradle`
182
183```gradle
184...
185include ':react-native-mauron85-background-geolocation', ':app'
186project(':react-native-mauron85-background-geolocation').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-mauron85-background-geolocation/android/lib')
187...
188```
189
190In `android/app/build.gradle`
191
192```gradle
193dependencies {
194 ...
195 compile project(':react-native-mauron85-background-geolocation')
196 ...
197}
198```
199
200In `android/src/main/res/values/strings.xml`
201
202Properties `@account_type` and `@content_authority` should be prefixed with your application package class.
203
204```xml
205<resources>
206<!-- Make sure you override following in your app res/values/strings.xml -->
207 <string name="app_name">APP_NAME</string>
208 <string name="account_type">com.yourcompany.account</string>
209 <string name="content_authority">com.yourcompany.authority</string>
210</resources>
211```
212
213Register module (in `MainApplication.java`)
214
215```java
216import com.marianhello.react.BackgroundGeolocationPackage; // <--- Import Package
217
218public class MainApplication extends Application implements ReactApplication {
219 ...
220 /**
221 * A list of packages used by the app. If the app uses additional views
222 * or modules besides the default ones, add more packages here.
223 */
224 @Override
225 protected List<ReactPackage> getPackages() {
226 return Arrays.<ReactPackage>asList(
227 new MainReactPackage(),
228 new BackgroundGeolocationPackage() // <---- Add the Package
229 );
230 }
231 ...
232}
233```
234
235#### Dependencies
236You will need to ensure that you have installed the following items through the Android SDK Manager:
237
238| Name | Version |
239|----------------------------|---------|
240| Android SDK Tools | 24.4.1 |
241| Android SDK Platform-tools | 23.1 |
242| Android SDK Build-tools | 23.0.1 |
243| Android Support Repository | 25 |
244| Android Support Library | 23.1.1 |
245| Google Play Services | 29 |
246| Google Repository | 24 |
247
248
249### iOS setup
250
2511. In XCode, in the project navigator, right click `Libraries``Add Files to [your project's name]`
2522. add `./node_modules/react-native-mauron85-background-geolocation/ios/RCTBackgroundGeolocation.xcodeproj`
2533. In the XCode project navigator, select your project, select the `Build Phases` tab and in the `Link Binary With Libraries` section add **libRCTBackgroundGeolocation.a**
2544. add `UIBackgroundModes` **location** to `Info.plist`
255
256For iOS before version 11:
257
2585. add `NSLocationAlwaysUsageDescription` **App requires background tracking** to `Info.plist`
259
260For iOS 11:
261
2625. add `NSLocationWhenInUseUsageDescription` **App requires background tracking** to `Info.plist`
2636. add `NSLocationAlwaysAndWhenInUseUsageDescription` **App requires background tracking** to `Info.plist`
264
265## API
266
267### configure(success, fail, options)
268
269| Parameter | Type | Platform | Description |
270|-----------|---------------|----------|---------------------------------------------------------------------------------|
271| `options` | `JSON Object` | all | Configure options |
272
273Configure options:
274
275| Parameter | Type | Platform | Description |
276|---------------------------|-------------------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
277| `locationProvider` | `Number` | all | Set location provider **@see** [PROVIDERS](/PROVIDERS.md) |
278| `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 |
279| `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. |
280| `debug` | `Boolean` | all | When enabled, the plugin will emit sounds for life-cycle events of background-geolocation! See debugging sounds table. |
281| `distanceFilter` | `Number` | all | The minimum distance (measured in meters) a device must move horizontally before an update event is generated. **@see** [Apple docs](https://developer.apple.com/library/ios/documentation/CoreLocation/Reference/CLLocationManager_Class/CLLocationManager/CLLocationManager.html#//apple_ref/occ/instp/CLLocationManager/distanceFilter). |
282| `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) |
283| `startOnBoot` | `Boolean` | Android | Start background service on device boot. (default false) |
284| `startForeground` | `Boolean` | Android | If false location service will not be started in foreground and no notification will be shown. (default true) |
285| `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. |
286| `notificationTitle` | `String` optional | Android | Custom notification title in the drawer. |
287| `notificationText` | `String` optional | Android | Custom notification text in the drawer. |
288| `notificationIconColor` | `String` optional | Android | The accent color to use for notification. Eg. **#4CAF50**. |
289| `notificationIconLarge` | `String` optional | Android | The filename of a custom notification icon. See android quirks. |
290| `notificationIconSmall` | `String` optional | Android | The filename of a custom notification icon. See android quirks. |
291| `activityType` | `String` | iOS | [AutomotiveNavigation, OtherNavigation, Fitness, Other] Presumably, this affects iOS GPS algorithm. **@see** [Apple docs](https://developer.apple.com/library/ios/documentation/CoreLocation/Reference/CLLocationManager_Class/CLLocationManager/CLLocationManager.html#//apple_ref/occ/instp/CLLocationManager/activityType) for more information |
292| `pauseLocationUpdates` | `Boolean` | iOS | Pauses location updates when app is paused (default: false). **@see* [Apple docs](https://developer.apple.com/documentation/corelocation/cllocationmanager/1620553-pauseslocationupdatesautomatical?language=objc)
293| `saveBatteryOnBackground` | `Boolean` | iOS | Switch to less accurate significant changes and region monitory when in background (default: true) |
294| `url` | `String` | all | Server url where to send HTTP POST with recorded locations **@see** [HTTP locations posting](#http-locations-posting) |
295| `syncUrl` | `String` | all | Server url where to send fail to post locations **@see** [HTTP locations posting](#http-locations-posting) |
296| `syncThreshold` | `Number` | all | Specifies how many previously failed locations will be sent to server at once (default: 100) |
297| `httpHeaders` | `Object` | all | Optional HTTP headers sent along in HTTP request |
298| `maxLocations` | `Number` | all | Limit maximum number of locations stored into db (default: 10000) |
299
300Following options are specific to provider as defined by locationProvider option
301#### ACTIVITY_PROVIDER provider options
302
303| Parameter | Type | Platform | Description |
304|-----------------------|-----------|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
305| `interval` | `Number` | Android | Rate in milliseconds at which your app prefers to receive location updates. **@see** [android docs](https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest.html#getInterval()) |
306| `fastestInterval` | `Number` | Android | Fastest rate in milliseconds at which your app can handle location updates. **@see** [android docs](https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest.html#getFastestInterval()). |
307| `activitiesInterval` | `Number` | Android | Rate in milliseconds at which activity recognition occurs. Larger values will result in fewer activity detections while improving battery life. |
308| `stopOnStillActivity` | `Boolean` | Android | stop() is forced, when the STILL activity is detected (default is true) |
309
310Location callback will be called with one argument - location object, which tries to mimic w3c [Coordinates interface](http://dev.w3.org/geo/api/spec-source.html#coordinates_interface).
311
312| Callback parameter | Type | Description |
313|--------------------|-----------|------------------------------------------------------------------------|
314| `id` | `Number` | ID of location as stored in DB (or null) |
315| `provider` | `String` | gps, network, passive or fused |
316| `locationProvider` | `Number` | Location provider |
317| `debug` | `Boolean` | true if location recorded as part of debug |
318| `time` | `Number` | UTC time of this fix, in milliseconds since January 1, 1970. |
319| `latitude` | `Number` | latitude, in degrees. |
320| `longitude` | `Number` | longitude, in degrees. |
321| `accuracy` | `Number` | estimated accuracy of this location, in meters. |
322| `speed` | `Number` | speed if it is available, in meters/second over ground. |
323| `altitude` | `Number` | altitude if available, in meters above the WGS 84 reference ellipsoid. |
324| `bearing` | `Number` | bearing, in degrees. |
325
326Note: Android currently returns `time` as type of String (instead of Number) [@see issue #9685](https://github.com/facebook/react-native/issues/9685)
327
328### start()
329Platform: iOS, Android
330
331Start background geolocation.
332
333### stop()
334Platform: iOS, Android
335
336Stop background geolocation.
337
338### isLocationEnabled(success, fail)
339Deprecated: This method is deprecated and will be removed in next major version.
340Use `checkStatus` as replacement.
341
342Platform: iOS, Android
343
344One time check for status of location services. In case of error, fail callback will be executed.
345
346| Success callback parameter | Type | Description |
347|----------------------------|-----------|------------------------------------------------------|
348| `enabled` | `Boolean` | true/false (true when location services are enabled) |
349
350### checkStatus(success, fail)
351
352Check status of the service
353
354| Success callback parameter | Type | Description |
355|----------------------------|-----------|------------------------------------------------------|
356| `isRunning` | `Boolean` | true/false (true if service is running) |
357| `hasPermissions` | `Boolean` | true/false (true if service has permissions) |
358| `authorization` | `Number` | BackgroundGeolocation.{NOT_AUTHORIZED | AUTHORIZED} |
359
360### showAppSettings()
361Platform: Android >= 6, iOS >= 8.0
362
363Show app settings to allow change of app location permissions.
364
365### showLocationSettings()
366Platform: iOS, Android
367
368Show system settings to allow configuration of current location sources.
369
370### getLocations(success, fail)
371Platform: iOS, Android
372
373Method will return all stored locations.
374This method is useful for initial rendering of user location on a map just after application launch.
375
376NOTE: Returned locations does not contain location.id.
377
378| Success callback parameter | Type | Description |
379|----------------------------|---------|--------------------------------|
380| `locations` | `Array` | collection of stored locations |
381
382```javascript
383BackgroundGeolocation.getLocations(
384 function (locations) {
385 console.log(locations);
386 }
387);
388```
389
390### getValidLocations(success, fail)
391Platform: iOS, Android
392
393Method will return locations, which has not been yet posted to server.
394NOTE: Locations does contain location.id.
395
396| Success callback parameter | Type | Description |
397|----------------------------|---------|--------------------------------|
398| `locations` | `Array` | collection of stored locations |
399
400### deleteLocation(locationId, success, fail)
401Platform: iOS, Android
402
403Delete location with locationId.
404
405Note: Locations are not actually deleted from database to avoid gaps in locationId numbering.
406Instead locations are marked as deleted. Locations marked as deleted will not appear in output of `BackgroundGeolocation.getLocations`.
407
408### deleteAllLocations(success, fail)
409Note: 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`.
410
411Platform: iOS, Android
412
413Delete all stored locations.
414
415### switchMode(modeId, success, fail)
416Platform: iOS
417
418Normally plugin will handle switching between **BACKGROUND** and **FOREGROUND** mode itself.
419Calling switchMode you can override plugin behavior and force plugin to switch into other mode.
420
421In **FOREGROUND** mode plugin uses iOS local manager to receive locations and behavior is affected
422by `option.desiredAccuracy` and `option.distanceFilter`.
423
424In **BACKGROUND** mode plugin uses significant changes and region monitoring to receive locations
425and uses `option.stationaryRadius` only.
426
427```
428// switch to FOREGROUND mode
429BackgroundGeolocation.switchMode(BackgroundGeolocation.FOREGROUND_MODE);
430
431// switch to BACKGROUND mode
432BackgroundGeolocation.switchMode(BackgroundGeolocation.BACKGROUND_MODE);
433```
434
435### getLogEntries(limit, success, fail)
436Platform: Android, iOS
437
438Return all logged events. Useful for plugin debugging.
439Parameter `limit` limits number of returned entries.
440**@see [Debugging](#debugging)** for more information.
441
442### removeAllListeners(event)
443
444Unregister all event listeners for given event
445
446## Events
447
448Event listeners can registered with:
449
450```
451const eventSubscription = BackgroundGeolocation.on('event', callbackFn);
452```
453
454And unregistered:
455
456```
457eventSubscription.remove();
458```
459
460Note: Components should unregister all event listeners in `componentWillUnmount` method,
461individually, or with `removeAllListeners`
462
463| Name | Callback param | Platform | Description |
464|---------------------|---------------------|----------|----------------------------------------|
465| `location` | `Location` | all | on location update |
466| `stationary` | `Location` | all | on device entered stationary mode |
467| `error` | `{ code, message }` | all | on plugin error |
468| `authorization` | `status` | all | on user toggle location service |
469| `foreground` | | android | app entered foreground state (visible) |
470| `background` | | android | app entered background state |
471
472
473## HTTP locations posting
474
475All 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,
476location callback function is triggered. Number of location stored in db is limited by `option.maxLocations` a never exceeds this number.
477Instead old locations are replaced by new ones.
478
479When `option.url` is defined, each location is also immediately posted to url defined by `option.url`.
480If post is successful, the location is marked as deleted in local db.
481
482When `option.syncUrl` is defined all failed to post locations will be coalesced and send in some time later in one single batch.
483Batch sync takes place only when number of failed to post locations reaches `option.syncTreshold`.
484Locations are send only in single batch, when number of locations reaches `option.syncTreshold`. (No individual location will be send)
485
486Request body of posted locations is always array, even when only one location is sent.
487
488### Example of backend server
489
490[Background-geolocation-server](https://github.com/mauron85/background-geolocation-server) is a backend server written in nodejs.
491There are instructions how to run it and simulate locations on Android, iOS Simulator and Genymotion.
492
493## Debugging
494
495See [DEBUGGING.md](/DEBUGGING.md)
496
497## Geofencing
498Try using [react-native-geo-fencing](https://github.com/surialabs/react-native-geo-fencing). Let's keep this plugin lightweight as much as possible.
499
500## Changelog
501
502See [CHANGES.md](/CHANGES.md)