Commit 6baff327 authored by Chris Scott's avatar Chris Scott

Merge conflicts with edge

parents 3560e27d d6319eb3
......@@ -20,9 +20,7 @@ The plugin creates the object `window.plugins.backgroundGeoLocation` with the me
`changePace(true) // engages aggressive monitoring immediately`
`getCurrentPosition(success, fail)`
`onMotionChange(callback, fail)`
`onStationary(callback, fail)`
`addGeofence(config, callback, fail)`
......@@ -91,7 +89,7 @@ function onDeviceReady() {
// BackgroundGeoLocation is highly configurable.
bgGeo.configure(callbackFn, failureFn, {
// Geolocation config
debug: true, // <-- enable this hear sounds for background-geolocation life-cycle.
desiredAccuracy: 0,
stationaryRadius: 50,
distanceFilter: 50,
......@@ -101,19 +99,15 @@ function onDeviceReady() {
fastestLocationUpdateInterval: 5000,
activityRecognitionInterval: 10000,
stopTimeout: 0,
activityType: 'AutomotiveNavigation',
// Application config
debug: true, // <-- enable this hear sounds for background-geolocation life-cycle.
forceReloadOnLocationChange: false, // <-- [Android] If the user closes the app **while location-tracking is started** , reboot app when a new location is recorded (WARNING: possibly distruptive to user)
forceReloadOnMotionChange: false, // <-- [Android] If the user closes the app **while location-tracking is started** , reboot app when device changes stationary-state (stationary->moving or vice-versa) --WARNING: possibly distruptive to user)
forceReloadOnGeofence: false, // <-- [Android] If the user closes the app **while location-tracking is started** , reboot app when a geofence crossing occurs --WARNING: possibly distruptive to user)
forceReload: true, // <-- [Android] If the user closes the app **while location-tracking is started** , reboot app (WARNING: possibly distruptive to user)
stopOnTerminate: false, // <-- [Android] Allow the background-service to run headless when user closes the app.
startOnBoot: true, // <-- [Android] Auto start background-service in headless mode when device is powered-up.
// HTTP / SQLite config
activityType: 'AutomotiveNavigation',
/**
* HTTP Feature: set an url to allow the native background service to POST locations to your server
*/
url: 'http://posttestserver.com/post.php?dir=cordova-background-geolocation',
batchSync: true, // <-- [Default: false] Set true to sync locations to server in a single HTTP request.
batchSync: false, // <-- [Default: false] Set true to sync locations to server in 1 HTTP request.
autoSync: true, // <-- [Default: true] Set true to sync each location to server as it arrives.
maxDaysToPersist: 1, // <-- Maximum days to persist a location in plugin's SQLite database when HTTP fails
headers: {
......@@ -138,8 +132,7 @@ function onDeviceReady() {
A fully-featured [SampleApp](https://github.com/christocracy/cordova-background-geolocation-SampleApp) is available in its own public repo. After first cloning that repo, follow the installation instructions in the **README** there. This SampleApp includes a settings-screen allowing you to quickly experiment with all the different settings available for each platform.
![Home](/assets/images/iphone/screenshot-iphone5-geofences-framed.png "Home")
![Settings](/assets/images/iphone/screenshot-iphone5-settings-framed.png "Settings")
![SampleApp](/resources/sampleapp-ionic-home.png "SampleApp")
## Simple Sample Application
......@@ -300,29 +293,7 @@ bgGeo.changePace(true); // <-- Aggressive GPS monitoring immediately engaged.
bgGeo.changePace(false); // <-- Disable aggressive GPS monitoring. Engages stationary-mode.
```
####`onMotionChange(callbackFn, failureFn)`
Your ```callbackFn``` will be executed each time the device has changed-state between **MOVING** or **STATIONARY. The ```callbackFn``` will be provided with a ```Location``` object as the 1st param, with the usual params (```latitude, longitude, accuracy, speed, bearing, altitude```), in addition to a ```taskId``` used to signal that your callback is finished.
######@param {Boolean} isMoving `false` if entered **STATIONARY** mode; `true` if entered **MOVING** mode.
######@param {Object} location The location at the state-change.
######@param {Integer} taskId The taskId used to send to bgGeo.finish(taskId) in order to signal completion of your callbackFn
```
bgGeo.onMotionChange(function(isMoving, location, taskId) {
if (isMoving) {
console.log('Device has just started MOVING', location);
} else {
console.log('Device has just STOPPED', location);
}
bgGeo.finish(taskId);
})
```
####`onStationary(callbackFn, failureFn)`
**DEPRECATED** &mdash; Use [onMotionChange](https://github.com/christocracy/cordova-background-geolocation/tree/trigger-activities#onmotionchangecallbackfn-failurefn) instead.
Your ```callbackFn``` will be executed each time the device has entered stationary-monitoring mode. The ```callbackFn``` will be provided with a ```Location``` object as the 1st param, with the usual params (```latitude, longitude, accuracy, speed, bearing, altitude```), in addition to a ```taskId``` used to signal that your callback is finished.
######@param {Object} location The Location data
......@@ -697,29 +668,13 @@ An interval of 0 is allowed, but not recommended, since location updates may be
the desired time between activity detections. Larger values will result in fewer activity detections while improving battery life. A value of 0 will result in activity detections at the fastest possible rate.
####`@param {Integer millis} minimumActivityRecognitionConfidence`
Each activity-recognition-result returned by the API is tagged with a "confidence" level expressed as a %. You can set your desired confidence to trigger a state-change. Defaults to `80`.
####`@param {String} triggerActivities`
These are the comma-delimited list of [activity-names](https://developers.google.com/android/reference/com/google/android/gms/location/DetectedActivity) returned by the `ActivityRecognition` API which will trigger a state-change from **stationary** to **moving**. By default, this list is set to all five **moving-states**: `"in_vehicle, on_bicycle, on_foot, running, walking"`. If you wish, you could configure the plugin to only engage **moving-mode** for vehicles by providing only `"in_vehicle"`.
####`@param {Integer minutes} stopTimeout`
The number of miutes to wait before turning off the GPS after the ActivityRecognition System (ARS) detects the device is ```STILL``` (defaults to 0, no timeout). If you don't set a value, the plugin is eager to turn off the GPS ASAP. An example use-case for this configuration is to delay GPS OFF while in a car waiting at a traffic light.
####`@param {Boolean} forceReloadOnMotionChange`
If the user closes the application while the background-tracking has been started, location-tracking will continue on if ```stopOnTerminate: false```. You may choose to force the foreground application to reload (since this is where your Javascript runs). `forceReloadOnMotionChange: true` will reload the app only when a state-change occurs from **stationary -> moving** or vice-versa. (**WARNING** possibly disruptive to user).
####`@param {Boolean} forceReloadOnLocationChange`
If the user closes the application while the background-tracking has been started, location-tracking will continue on if ```stopOnTerminate: false```. You may choose to force the foreground application to reload (since this is where your Javascript runs). `forceReloadOnLocationChange: true` will reload the app when a new location is recorded.
####`@param {Boolean} forceReloadOnGeofence`
####`@param {Boolean} forceReload`
If the user closes the application while the background-tracking has been started, location-tracking will continue on if ```stopOnTerminate: false```. You may choose to force the foreground application to reload (since this is where your Javascript runs). `forceReloadOnGeolocation: true` will reload the app only when a geofence crossing event has occurred.
If the user closes the application while the background-tracking has been started, location-tracking will continue on if ```stopOnTerminate: false```. You may choose to force the foreground application to reload (since this is where your Javascript runs) by setting ```foreceReload: true```. This will guarantee that locations are always sent to your Javascript callback (**WARNING** possibly disruptive to user).
####`@param {Boolean} startOnBoot`
......
......@@ -166,45 +166,9 @@ var app = {
console.log('BackgroundGeoLocation error');
};
// BackgroundGeoLocation is highly configurable.
bgGeo.configure(callbackFn, failureFn, {
// Geolocation config
desiredAccuracy: 0,
stationaryRadius: 50,
distanceFilter: 50,
disableElasticity: false, // <-- [iOS] Default is 'false'. Set true to disable speed-based distanceFilter elasticity
locationUpdateInterval: 5000,
minimumActivityRecognitionConfidence: 80, // 0-100%. Minimum activity-confidence for a state-change
fastestLocationUpdateInterval: 5000,
activityRecognitionInterval: 10000,
stopTimeout: 0,
activityType: 'AutomotiveNavigation',
// Application config
debug: true, // <-- enable this hear sounds for background-geolocation life-cycle.
forceReloadOnLocationChange: false, // <-- [Android] If the user closes the app **while location-tracking is started** , reboot app when a new location is recorded (WARNING: possibly distruptive to user)
forceReloadOnMotionChange: false, // <-- [Android] If the user closes the app **while location-tracking is started** , reboot app when device changes stationary-state (stationary->moving or vice-versa) --WARNING: possibly distruptive to user)
forceReloadOnGeofence: false, // <-- [Android] If the user closes the app **while location-tracking is started** , reboot app when a geofence crossing occurs --WARNING: possibly distruptive to user)
stopOnTerminate: false, // <-- [Android] Allow the background-service to run headless when user closes the app.
startOnBoot: true, // <-- [Android] Auto start background-service in headless mode when device is powered-up.
// HTTP / SQLite config
url: 'http://posttestserver.com/post.php?dir=cordova-background-geolocation',
batchSync: true, // <-- [Default: false] Set true to sync locations to server in a single HTTP request.
autoSync: true, // <-- [Default: true] Set true to sync each location to server as it arrives.
maxDaysToPersist: 1, // <-- Maximum days to persist a location in plugin's SQLite database when HTTP fails
headers: {
"X-FOO": "bar"
},
params: {
"auth_token": "maybe_your_server_authenticates_via_token_YES?"
}
});
// Listen to motion-state changes (stationary / moving)
bgGeo.onMotionChange(function(isMoving, location, taskId) {
console.log('[js] BackgroundGeoLocation stationary-state changed ' + isMoving);
console.log('[js] location: ' + JSON.stringify(location));
// Only ios emits this stationary event
bgGeo.onStationary(function(location, taskId) {
console.log('[js] BackgroundGeoLocation onStationary ' + JSON.stringify(location));
app.setCurrentLocation(location);
......@@ -213,7 +177,6 @@ var app = {
// Center ourself on map
app.onClickHome();
if (!isMoving) {
if (!app.stationaryRadius) {
app.stationaryRadius = new google.maps.Circle({
fillColor: '#cc0000',
......@@ -226,15 +189,45 @@ var app = {
var center = new google.maps.LatLng(coords.latitude, coords.longitude);
app.stationaryRadius.setRadius(radius);
app.stationaryRadius.setCenter(center);
}
bgGeo.finish(taskId);
});
// Listen to Geofence events.
bgGeo.onGeofence(function(params, taskId) {
console.log('[js] Geofence crossed: ', params.action, params.identifier);
// BackgroundGeoLocation is highly configurable.
bgGeo.configure(callbackFn, failureFn, {
debug: true, // <-- enable this hear sounds for background-geolocation life-cycle.
desiredAccuracy: 0,
stationaryRadius: 50,
distanceFilter: 50,
disableElasticity: false, // <-- [iOS] Default is 'false'. Set true to disable speed-based distanceFilter elasticity
locationUpdateInterval: 5000,
minimumActivityRecognitionConfidence: 80, // 0-100%. Minimum activity-confidence for a state-change
fastestLocationUpdateInterval: 5000,
activityRecognitionInterval: 10000,
stopTimeout: 0,
forceReload: false, // <-- [Android] If the user closes the app **while location-tracking is started** , reboot app (WARNING: possibly distruptive to user)
stopOnTerminate: true, // <-- [Android] Allow the background-service to run headless when user closes the app.
startOnBoot: false, // <-- [Android] Auto start background-service in headless mode when device is powered-up.
activityType: 'AutomotiveNavigation',
/**
* HTTP Feature: set an url to allow the native background service to POST locations to your server
*/
url: 'http://posttestserver.com/post.php?dir=cordova-background-geolocation',
batchSync: true, // <-- [Default: false] Set true to sync locations to server in a single HTTP request.
autoSync: true, // <-- [Default: true] Set true to sync each location to server as it arrives.
maxDaysToPersist: 1, // <-- Maximum days to persist a location in plugin's SQLite database when HTTP fails
headers: {
"X-FOO": "bar"
},
params: {
"auth_token": "maybe_your_server_authenticates_via_token_YES?"
}
});
bgGeo.onGeofence(function(identifier, taskId) {
alert('Enter Geofence: ' + identifier);
console.log('[js] Geofence ENTER: ', identifier, taskId);
bgGeo.finish(taskId);
});
......@@ -247,8 +240,7 @@ var app = {
identifier: 'MyGeofence',
radius: 200,
latitude: e.latLng.lat(),
longitude: e.latLng.lng(),
notifyOnEntry: true
longitude: e.latLng.lng()
}, function() {
app.geofence = new google.maps.Circle({
fillColor: '#00cc00',
......
This diff is collapsed.
......@@ -12,20 +12,17 @@
@property (nonatomic, strong) NSString* syncCallbackId;
@property (nonatomic) UIBackgroundTaskIdentifier syncTaskId;
@property (nonatomic, strong) NSString* locationCallbackId;
@property (nonatomic, strong) NSMutableArray* currentPositionListeners;
@property (nonatomic, strong) NSMutableArray* geofenceListeners;
@property (nonatomic, strong) NSMutableArray* stationaryRegionListeners;
@property (nonatomic, strong) NSMutableArray* motionChangeListeners;
- (void) configure:(CDVInvokedUrlCommand*)command;
- (void) start:(CDVInvokedUrlCommand*)command;
- (void) stop:(CDVInvokedUrlCommand*)command;
- (void) finish:(CDVInvokedUrlCommand*)command;
- (void) error:(CDVInvokedUrlCommand*)command;
- (void) changePace:(CDVInvokedUrlCommand*)command;
- (void) onPaceChange:(CDVInvokedUrlCommand*)command;
- (void) setConfig:(CDVInvokedUrlCommand*)command;
- (void) addStationaryRegionListener:(CDVInvokedUrlCommand*)command;
- (void) addMotionChangeListener:(CDVInvokedUrlCommand*)command;
- (void) getStationaryLocation:(CDVInvokedUrlCommand *)command;
- (void) getLocations:(CDVInvokedUrlCommand *)command;
- (void) sync:(CDVInvokedUrlCommand *)command;
......@@ -35,7 +32,6 @@
- (void) removeGeofence:(CDVInvokedUrlCommand *)command;
- (void) getGeofences:(CDVInvokedUrlCommand *)command;
- (void) onGeofence:(CDVInvokedUrlCommand *)command;
- (void) getCurrentPosition:(CDVInvokedUrlCommand *)command;
- (void) playSound:(CDVInvokedUrlCommand *)command;
@end
......@@ -10,14 +10,14 @@
NSDictionary *config;
}
@synthesize syncCallbackId, syncTaskId, locationCallbackId, geofenceListeners, stationaryRegionListeners, motionChangeListeners, currentPositionListeners;
@synthesize syncCallbackId, syncTaskId, locationCallbackId, geofenceListeners, stationaryRegionListeners;
- (void)pluginInitialize
{
bgGeo = [[TSLocationManager alloc] init];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onLocationChanged:) name:@"TSLocationManager.location" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMotionChange:) name:@"TSLocationManager.motionchange" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onStationaryLocation:) name:@"TSLocationManager.stationary" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onEnterGeofence:) name:@"TSLocationManager.geofence" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onSyncComplete:) name:@"TSLocationManager.sync" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onLocationManagerError:) name:@"TSLocationManager.error" object:nil];
......@@ -84,7 +84,7 @@
* Change pace to moving/stopped
* @param {Boolean} isMoving
*/
- (void) changePace:(CDVInvokedUrlCommand *)command
- (void) onPaceChange:(CDVInvokedUrlCommand *)command
{
BOOL moving = [[command.arguments objectAtIndex: 0] boolValue];
[bgGeo changePace:moving];
......@@ -98,9 +98,8 @@
- (void)onLocationChanged:(NSNotification*)notification {
CLLocation *location = [notification.userInfo objectForKey:@"location"];
NSDictionary *locationData = [bgGeo locationToDictionary:location];
NSDictionary *params = @{
@"location": locationData,
@"location": [bgGeo locationToDictionary:location],
@"taskId": @([bgGeo createBackgroundTask])
};
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:params];
......@@ -109,52 +108,18 @@
[self.commandDelegate runInBackground:^{
[self.commandDelegate sendPluginResult:result callbackId:self.locationCallbackId];
}];
if ([self.currentPositionListeners count]) {
for (NSString *callbackId in self.currentPositionListeners) {
NSDictionary *params = @{
@"location": locationData,
@"taskId": @([bgGeo createBackgroundTask])
};
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:params];
[result setKeepCallbackAsBool:NO];
[self.commandDelegate runInBackground:^{
[self.commandDelegate sendPluginResult:result callbackId:callbackId];
}];
}
[self.currentPositionListeners removeAllObjects];
}
}
- (void) onMotionChange:(NSNotification*)notification
- (void) onStationaryLocation:(NSNotification*)notification
{
if (![self.stationaryRegionListeners count] && ![self.motionChangeListeners count]) {
if (![self.stationaryRegionListeners count]) {
return;
}
BOOL isMoving = [[notification.userInfo objectForKey:@"isMoving"] boolValue];
CLLocation *location = [notification.userInfo objectForKey:@"location"];
NSDictionary *locationData = [bgGeo locationToDictionary:location];
// @deprecated stationaryRegionListeners in favour of dual-function motionChangeListeners
if (!isMoving) {
for (NSString *callbackId in self.stationaryRegionListeners) {
NSLog(@"- CALLBACK: %@", callbackId);
NSDictionary *params = @{
@"isMoving": @(isMoving),
@"location": locationData,
@"taskId": @([bgGeo createBackgroundTask])
};
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:params];
[result setKeepCallbackAsBool:YES];
[self.commandDelegate runInBackground:^{
[self.commandDelegate sendPluginResult:result callbackId:callbackId];
}];
}
}
for (NSString *callbackId in self.motionChangeListeners) {
NSDictionary *params = @{
@"isMoving": @(isMoving),
@"location": locationData,
@"taskId": @([bgGeo createBackgroundTask])
};
......@@ -163,6 +128,7 @@
[self.commandDelegate runInBackground:^{
[self.commandDelegate sendPluginResult:result callbackId:callbackId];
}];
}
}
......@@ -191,9 +157,6 @@
- (void) onSyncComplete:(NSNotification*)notification
{
if (syncCallbackId == nil) {
return;
}
NSDictionary *params = @{
@"locations": [notification.userInfo objectForKey:@"locations"],
@"taskId": @(syncTaskId)
......@@ -262,14 +225,6 @@
[self.stationaryRegionListeners addObject:command.callbackId];
}
- (void) addMotionChangeListener:(CDVInvokedUrlCommand*)command
{
if (self.motionChangeListeners == nil) {
self.motionChangeListeners = [[NSMutableArray alloc] init];
}
[self.motionChangeListeners addObject:command.callbackId];
}
- (void) addGeofence:(CDVInvokedUrlCommand*)command
{
NSDictionary *cfg = [command.arguments objectAtIndex:0];
......
......@@ -83,7 +83,7 @@ module.exports = {
exec(success || function() {},
failure || function() {},
'BackgroundGeoLocation',
'changePace',
'onPaceChange',
[isMoving]);
},
/**
......@@ -112,7 +112,6 @@ module.exports = {
},
/**
* Add a stationary-region listener. Whenever the devices enters "stationary-mode", your #success callback will be executed with #location param containing #radius of region
* @deprecated in favour of dual-function #onMotionChange
* @param {Function} success
* @param {Function} failure [optional] NOT IMPLEMENTED
*/
......@@ -137,35 +136,6 @@ module.exports = {
'addStationaryRegionListener',
[]);
},
/**
* Add a movement-state-change listener. Whenever the devices enters "stationary" or "moving" mode, your #success callback will be executed with #location param containing #radius of region
* @param {Function} success
* @param {Function} failure [optional] NOT IMPLEMENTED
*/
onMotionChange: function(success, failure) {
var me = this;
success = success || function(isMoving, location, taskId) {
me.finish(taskId);
};
var callback = function(params) {
var isMoving = params.isMoving;
var location = params.location;
var taskId = params.taskId || 'task-id-undefined';
if (!isMoving) {
me.stationaryLocation = location;
}
me._runBackgroundTask(taskId, function() {
success.call(me, isMoving, location, taskId);
}, failure);
};
exec(callback,
failure || function() {},
'BackgroundGeoLocation',
'addMotionChangeListener',
[]);
},
getLocations: function(success, failure) {
if (typeof(success) !== 'function') {
throw "BackgroundGeolocation#getLocations requires a success callback";
......@@ -293,31 +263,6 @@ module.exports = {
[]);
},
/**
* Fetch the current position
*/
getCurrentPosition: function(success, failure) {
var me = this;
success = success || function(location, taskId) {
me.finish(taskId);
};
var mySuccess = function(params) {
var location = params.location || params;
var taskId = params.taskId || 'task-id-undefined';
// Transform timestamp to Date instance.
if (location.timestamp) {
location.timestamp = new Date(location.timestamp);
}
me._runBackgroundTask(taskId, function() {
success.call(this, location, taskId);
});
}
exec(mySuccess || function() {},
failure || function() {},
'BackgroundGeoLocation',
'getCurrentPosition',
[]);
},
/**
* Play a system sound. This is totally experimental.
* iOS http://iphonedevwiki.net/index.php/AudioServices
* Android:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment