Commit 85b75257 authored by Chris Scott's avatar Chris Scott

Merge pull request #59 from christocracy/geofencing

Geofencing
parents b8b92c56 41ee596a
This diff is collapsed.
...@@ -138,26 +138,28 @@ var app = { ...@@ -138,26 +138,28 @@ var app = {
app.onClickHome(); app.onClickHome();
/**
* This would be your own callback for Ajax-requests after POSTing background geolocation to your server.
*/
var yourAjaxCallback = function(response) {
// Very important to call #finish -- it signals to the native plugin that it can destroy the background thread, which your callbackFn is running in.
// IF YOU DON'T, THE OS CAN KILL YOUR APP FOR RUNNING TOO LONG IN THE BACKGROUND
bgGeo.finish();
};
/** /**
* This callback will be executed every time a geolocation is recorded in the background. * This callback will be executed every time a geolocation is recorded in the background.
*/ */
var callbackFn = function(location) { var callbackFn = function(location, taskId) {
console.log('[js] BackgroundGeoLocation callback: ' + JSON.stringify(location)); console.log('[js] BackgroundGeoLocation callback: ' + JSON.stringify(location));
// Update our current-position marker. // Update our current-position marker.
app.setCurrentLocation(location); app.setCurrentLocation(location);
// After you Ajax callback is complete, you MUST signal to the native code, which is running a background-thread, that you're done and it can gracefully kill that thread. // After you Ajax callback is complete, you MUST signal to the native code, which is running a background-thread, that you're done and it can gracefully kill that thread.
yourAjaxCallback.call(this);
/**
* This would be your own callback for Ajax-requests after POSTing background geolocation to your server.
*/
var yourAjaxCallback = function(response) {
// Very important to call #finish -- it signals to the native plugin that it can destroy the background thread, which your callbackFn is running in.
// IF YOU DON'T, THE OS CAN KILL YOUR APP FOR RUNNING TOO LONG IN THE BACKGROUND
bgGeo.finish(taskId);
};
yourAjaxCallback.call(this, {status: 200});
}; };
var failureFn = function(error) { var failureFn = function(error) {
...@@ -165,7 +167,7 @@ var app = { ...@@ -165,7 +167,7 @@ var app = {
}; };
// Only ios emits this stationary event // Only ios emits this stationary event
bgGeo.onStationary(function(location) { bgGeo.onStationary(function(location, taskId) {
console.log('[js] BackgroundGeoLocation onStationary ' + JSON.stringify(location)); console.log('[js] BackgroundGeoLocation onStationary ' + JSON.stringify(location));
app.setCurrentLocation(location); app.setCurrentLocation(location);
...@@ -187,6 +189,8 @@ var app = { ...@@ -187,6 +189,8 @@ var app = {
var center = new google.maps.LatLng(coords.latitude, coords.longitude); var center = new google.maps.LatLng(coords.latitude, coords.longitude);
app.stationaryRadius.setRadius(radius); app.stationaryRadius.setRadius(radius);
app.stationaryRadius.setCenter(center); app.stationaryRadius.setCenter(center);
bgGeo.finish(taskId);
}); });
...@@ -195,22 +199,22 @@ var app = { ...@@ -195,22 +199,22 @@ var app = {
debug: true, // <-- enable this hear sounds for background-geolocation life-cycle. debug: true, // <-- enable this hear sounds for background-geolocation life-cycle.
desiredAccuracy: 0, desiredAccuracy: 0,
stationaryRadius: 50, stationaryRadius: 50,
distanceFilter: 25, distanceFilter: 50,
disableElasticity: false, // <-- [iOS] Default is 'false'. Set true to disable speed-based distanceFilter elasticity disableElasticity: false, // <-- [iOS] Default is 'false'. Set true to disable speed-based distanceFilter elasticity
locationUpdateInterval: 5000, locationUpdateInterval: 5000,
minimumActivityRecognitionConfidence: 80, // 0-100%. Minimum activity-confidence for a state-change minimumActivityRecognitionConfidence: 80, // 0-100%. Minimum activity-confidence for a state-change
fastestLocationUpdateInterval: 5000, fastestLocationUpdateInterval: 5000,
activityRecognitionInterval: 10000, activityRecognitionInterval: 10000,
stopTimeout: 0, stopTimeout: 0,
forceReload: true, // <-- [Android] If the user closes the app **while location-tracking is started** , reboot app (WARNING: possibly distruptive to user) forceReload: false, // <-- [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. stopOnTerminate: true, // <-- [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. startOnBoot: false, // <-- [Android] Auto start background-service in headless mode when device is powered-up.
activityType: 'AutomotiveNavigation', activityType: 'AutomotiveNavigation',
/** /**
* HTTP Feature: set an url to allow the native background service to POST locations to your server * 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', url: 'http://posttestserver.com/post.php?dir=cordova-background-geolocation',
batchSync: false, // <-- [Default: false] Set true to sync locations to server in a single HTTP request. 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. 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 maxDaysToPersist: 1, // <-- Maximum days to persist a location in plugin's SQLite database when HTTP fails
headers: { headers: {
...@@ -221,9 +225,10 @@ var app = { ...@@ -221,9 +225,10 @@ var app = {
} }
}); });
bgGeo.onGeofence(function(identifier) { bgGeo.onGeofence(function(identifier, taskId) {
alert('Enter Geofence: ' + identifier); alert('Enter Geofence: ' + identifier);
console.log('[js] Geofence ENTER: ', identifier); console.log('[js] Geofence ENTER: ', identifier, taskId);
bgGeo.finish(taskId);
}); });
// Add longpress event for adding GeoFence of hard-coded radius 200m. // Add longpress event for adding GeoFence of hard-coded radius 200m.
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
<service android:name="com.transistorsoft.locationmanager.BackgroundGeolocationService" /> <service android:name="com.transistorsoft.locationmanager.BackgroundGeolocationService" />
<service android:name="com.transistorsoft.locationmanager.LocationService" /> <service android:name="com.transistorsoft.locationmanager.LocationService" />
<service android:name="com.transistorsoft.locationmanager.ActivityRecognitionService" /> <service android:name="com.transistorsoft.locationmanager.ActivityRecognitionService" />
<service android:name="com.transistorsoft.locationmanager.GeofenceService" />
<receiver android:name="com.transistorsoft.locationmanager.BootReceiver" android:enabled="true" android:exported="false"> <receiver android:name="com.transistorsoft.locationmanager.BootReceiver" android:enabled="true" android:exported="false">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/> <action android:name="android.intent.action.BOOT_COMPLETED"/>
......
package com.transistorsoft.cordova.bggeo; package com.transistorsoft.cordova.bggeo;
import java.util.List;
import java.util.ArrayList;
import org.apache.cordova.CallbackContext; import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin; import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CordovaWebView; import org.apache.cordova.CordovaWebView;
...@@ -11,8 +13,8 @@ import android.os.Bundle; ...@@ -11,8 +13,8 @@ import android.os.Bundle;
import com.google.android.gms.location.ActivityRecognitionResult; import com.google.android.gms.location.ActivityRecognitionResult;
import com.google.android.gms.location.DetectedActivity; import com.google.android.gms.location.DetectedActivity;
import com.transistorsoft.locationmanager.BackgroundGeolocationService; import com.transistorsoft.locationmanager.BackgroundGeolocationService;
import com.transistorsoft.locationmanager.BackgroundGeolocationService.PaceChangeEvent; import com.google.android.gms.location.Geofence;
import com.transistorsoft.locationmanager.BackgroundGeolocationService.PausedEvent; import com.google.android.gms.location.GeofencingEvent;
//import com.transistorsoft.locationmanager.BackgroundGeolocationService.StationaryLocation; //import com.transistorsoft.locationmanager.BackgroundGeolocationService.StationaryLocation;
import de.greenrobot.event.EventBus; import de.greenrobot.event.EventBus;
...@@ -37,6 +39,8 @@ public class CDVBackgroundGeolocation extends CordovaPlugin { ...@@ -37,6 +39,8 @@ public class CDVBackgroundGeolocation extends CordovaPlugin {
public static final String ACTION_SYNC = "sync"; public static final String ACTION_SYNC = "sync";
public static final String ACTION_GET_ODOMETER = "getOdometer"; public static final String ACTION_GET_ODOMETER = "getOdometer";
public static final String ACTION_RESET_ODOMETER = "resetOdometer"; public static final String ACTION_RESET_ODOMETER = "resetOdometer";
public static final String ACTION_ADD_GEOFENCE = "addGeofence";
public static final String ACTION_ON_GEOFENCE = "onGeofence";
private Boolean isEnabled = false; private Boolean isEnabled = false;
private Boolean stopOnTerminate = false; private Boolean stopOnTerminate = false;
...@@ -48,16 +52,13 @@ public class CDVBackgroundGeolocation extends CordovaPlugin { ...@@ -48,16 +52,13 @@ public class CDVBackgroundGeolocation extends CordovaPlugin {
// Geolocation callback // Geolocation callback
private CallbackContext locationCallback; private CallbackContext locationCallback;
// Called when DetectedActivity is STILL
private CallbackContext stationaryCallback; private CallbackContext stationaryCallback;
private CallbackContext getLocationsCallback; private CallbackContext getLocationsCallback;
private CallbackContext syncCallback; private CallbackContext syncCallback;
private CallbackContext getOdometerCallback; private CallbackContext getOdometerCallback;
private CallbackContext resetOdometerCallback; private CallbackContext resetOdometerCallback;
private CallbackContext paceChangeCallback;
private List<CallbackContext> geofenceCallbacks = new ArrayList<CallbackContext>();
public static boolean isActive() { public static boolean isActive() {
return gWebView != null; return gWebView != null;
...@@ -70,7 +71,6 @@ public class CDVBackgroundGeolocation extends CordovaPlugin { ...@@ -70,7 +71,6 @@ public class CDVBackgroundGeolocation extends CordovaPlugin {
backgroundServiceIntent = new Intent(this.cordova.getActivity(), BackgroundGeolocationService.class); backgroundServiceIntent = new Intent(this.cordova.getActivity(), BackgroundGeolocationService.class);
// Register for events fired by our IntentService "LocationService" // Register for events fired by our IntentService "LocationService"
EventBus.getDefault().register(this);
} }
public boolean execute(String action, JSONArray data, CallbackContext callbackContext) throws JSONException { public boolean execute(String action, JSONArray data, CallbackContext callbackContext) throws JSONException {
...@@ -98,17 +98,22 @@ public class CDVBackgroundGeolocation extends CordovaPlugin { ...@@ -98,17 +98,22 @@ public class CDVBackgroundGeolocation extends CordovaPlugin {
Log.w(TAG, "- Cannot change pace while disabled"); Log.w(TAG, "- Cannot change pace while disabled");
result = false; result = false;
callbackContext.error("Cannot #changePace while disabled"); callbackContext.error("Cannot #changePace while disabled");
} else { } else {
PaceChangeEvent event = new PaceChangeEvent(data.getBoolean(0));
EventBus.getDefault().post(event);
result = true; result = true;
callbackContext.success(); paceChangeCallback = callbackContext;
Bundle event = new Bundle();
event.putString("name", action);
event.putBoolean("request", true);
event.putBoolean("isMoving", data.getBoolean(0));
EventBus.getDefault().post(event);
} }
} else if (ACTION_SET_CONFIG.equalsIgnoreCase(action)) { } else if (ACTION_SET_CONFIG.equalsIgnoreCase(action)) {
result = applyConfig(data); result = applyConfig(data);
// TODO reconfigure Service
if (result) { if (result) {
Bundle event = new Bundle();
event.putString("name", action);
event.putBoolean("request", true);
EventBus.getDefault().post(event);
callbackContext.success(); callbackContext.success();
} else { } else {
callbackContext.error("- Configuration error!"); callbackContext.error("- Configuration error!");
...@@ -144,6 +149,29 @@ public class CDVBackgroundGeolocation extends CordovaPlugin { ...@@ -144,6 +149,29 @@ public class CDVBackgroundGeolocation extends CordovaPlugin {
event.putBoolean("request", true); event.putBoolean("request", true);
resetOdometerCallback = callbackContext; resetOdometerCallback = callbackContext;
EventBus.getDefault().post(event); EventBus.getDefault().post(event);
} else if (ACTION_ADD_GEOFENCE.equalsIgnoreCase(action)) {
result = true;
JSONObject config = data.getJSONObject(0);
try {
Bundle event = new Bundle();
event.putString("name", action);
event.putBoolean("request", true);
event.putFloat("radius", (float) config.getLong("radius"));
event.putDouble("latitude", config.getDouble("latitude"));
event.putDouble("longitude", config.getDouble("longitude"));
event.putString("identifier", config.getString("identifier"));
EventBus.getDefault().post(event);
callbackContext.success();
} catch (JSONException e) {
Log.w(TAG, e);
callbackContext.error("Failed to add geofence");
result = false;
}
} else if (ACTION_ON_GEOFENCE.equalsIgnoreCase(action)) {
result = true;
geofenceCallbacks.add(callbackContext);
} }
return result; return result;
} }
...@@ -159,10 +187,12 @@ public class CDVBackgroundGeolocation extends CordovaPlugin { ...@@ -159,10 +187,12 @@ public class CDVBackgroundGeolocation extends CordovaPlugin {
editor.commit(); editor.commit();
if (isEnabled) { if (isEnabled) {
EventBus.getDefault().register(this);
if (!BackgroundGeolocationService.isInstanceCreated()) { if (!BackgroundGeolocationService.isInstanceCreated()) {
activity.startService(backgroundServiceIntent); activity.startService(backgroundServiceIntent);
} }
} else { } else {
EventBus.getDefault().unregister(this);
activity.stopService(backgroundServiceIntent); activity.stopService(backgroundServiceIntent);
} }
} }
...@@ -189,6 +219,9 @@ public class CDVBackgroundGeolocation extends CordovaPlugin { ...@@ -189,6 +219,9 @@ public class CDVBackgroundGeolocation extends CordovaPlugin {
if (config.has("locationUpdateInterval")) { if (config.has("locationUpdateInterval")) {
editor.putInt("locationUpdateInterval", config.getInt("locationUpdateInterval")); editor.putInt("locationUpdateInterval", config.getInt("locationUpdateInterval"));
} }
if (config.has("fastestLocationUpdateInterval")) {
editor.putInt("fastestLocationUpdateInterval", config.getInt("fastestLocationUpdateInterval"));
}
if (config.has("activityRecognitionInterval")) { if (config.has("activityRecognitionInterval")) {
editor.putLong("activityRecognitionInterval", config.getLong("activityRecognitionInterval")); editor.putLong("activityRecognitionInterval", config.getLong("activityRecognitionInterval"));
} }
...@@ -205,7 +238,8 @@ public class CDVBackgroundGeolocation extends CordovaPlugin { ...@@ -205,7 +238,8 @@ public class CDVBackgroundGeolocation extends CordovaPlugin {
editor.putInt("stopAfterElapsedMinutes", config.getInt("stopAfterElapsedMinutes")); editor.putInt("stopAfterElapsedMinutes", config.getInt("stopAfterElapsedMinutes"));
} }
if (config.has("stopOnTerminate")) { if (config.has("stopOnTerminate")) {
editor.putBoolean("stopOnTerminate", config.getBoolean("stopOnTerminate")); stopOnTerminate = config.getBoolean("stopOnTerminate");
editor.putBoolean("stopOnTerminate", stopOnTerminate);
} }
if (config.has("startOnBoot")) { if (config.has("startOnBoot")) {
editor.putBoolean("startOnBoot", config.getBoolean("startOnBoot")); editor.putBoolean("startOnBoot", config.getBoolean("startOnBoot"));
...@@ -296,7 +330,10 @@ public class CDVBackgroundGeolocation extends CordovaPlugin { ...@@ -296,7 +330,10 @@ public class CDVBackgroundGeolocation extends CordovaPlugin {
runInBackground(getOdometerCallback, result); runInBackground(getOdometerCallback, result);
} else if (ACTION_RESET_ODOMETER.equalsIgnoreCase(name)) { } else if (ACTION_RESET_ODOMETER.equalsIgnoreCase(name)) {
PluginResult result = new PluginResult(PluginResult.Status.OK); PluginResult result = new PluginResult(PluginResult.Status.OK);
runInBackground(resetOdometerCallback, result); resetOdometerCallback.sendPluginResult(result);
} else if (ACTION_ON_PACE_CHANGE.equalsIgnoreCase(name)) {
PluginResult result = new PluginResult(PluginResult.Status.OK);
paceChangeCallback.sendPluginResult(result);
} }
} }
...@@ -329,7 +366,30 @@ public class CDVBackgroundGeolocation extends CordovaPlugin { ...@@ -329,7 +366,30 @@ public class CDVBackgroundGeolocation extends CordovaPlugin {
runInBackground(locationCallback, result); runInBackground(locationCallback, result);
} }
} }
/**
* EventBus handler for Geofencing events
*/
public void onEventMainThread(GeofencingEvent geofenceEvent) {
Log.i(TAG, "- Rx GeofencingEvent: " + geofenceEvent);
if (!geofenceCallbacks.isEmpty()) {
for (Geofence geofence : geofenceEvent.getTriggeringGeofences()) {
JSONObject params = new JSONObject();
try {
params.put("identifier", geofence.getRequestId());
} catch (JSONException e) {
e.printStackTrace();
}
PluginResult result = new PluginResult(PluginResult.Status.OK, params);
result.setKeepCallback(true);
for (CallbackContext callback : geofenceCallbacks) {
runInBackground(callback, result);
}
}
}
}
/** /**
* Run a javascript callback in Background * Run a javascript callback in Background
* @param cb * @param cb
...@@ -356,6 +416,8 @@ public class CDVBackgroundGeolocation extends CordovaPlugin { ...@@ -356,6 +416,8 @@ public class CDVBackgroundGeolocation extends CordovaPlugin {
Activity activity = this.cordova.getActivity(); Activity activity = this.cordova.getActivity();
EventBus.getDefault().unregister(this);
SharedPreferences settings = activity.getSharedPreferences("TSLocationManager", 0); SharedPreferences settings = activity.getSharedPreferences("TSLocationManager", 0);
SharedPreferences.Editor editor = settings.edit(); SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("activityIsActive", false); editor.putBoolean("activityIsActive", false);
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
@interface CDVBackgroundGeolocation : CDVPlugin @interface CDVBackgroundGeolocation : CDVPlugin
@property (nonatomic, strong) NSString* syncCallbackId; @property (nonatomic, strong) NSString* syncCallbackId;
@property (nonatomic, strong) NSString* geofenceCallbackId; @property (nonatomic, strong) NSMutableArray* geofenceListeners;
@property (nonatomic, strong) NSMutableArray* stationaryRegionListeners; @property (nonatomic, strong) NSMutableArray* stationaryRegionListeners;
- (void) configure:(CDVInvokedUrlCommand*)command; - (void) configure:(CDVInvokedUrlCommand*)command;
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
NSDictionary *config; NSDictionary *config;
} }
@synthesize syncCallbackId, geofenceCallbackId, stationaryRegionListeners; @synthesize syncCallbackId, geofenceListeners, stationaryRegionListeners;
- (void)pluginInitialize - (void)pluginInitialize
{ {
...@@ -87,44 +87,61 @@ ...@@ -87,44 +87,61 @@
* location handler from BackgroundGeolocation * location handler from BackgroundGeolocation
*/ */
- (void)onLocationChanged:(NSNotification*)notification { - (void)onLocationChanged:(NSNotification*)notification {
CLLocation *location = notification.object; CLLocation *location = [notification.userInfo objectForKey:@"location"];
NSDictionary *locationData = [bgGeo locationToDictionary:location];
CDVPluginResult* result = nil; NSDictionary *params = @{
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:locationData]; @"location": [bgGeo locationToDictionary:location],
@"taskId": @([bgGeo createBackgroundTask])
};
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:params];
[result setKeepCallbackAsBool:YES]; [result setKeepCallbackAsBool:YES];
[self.commandDelegate sendPluginResult:result callbackId:self.syncCallbackId];
[self.commandDelegate runInBackground:^{
[self.commandDelegate sendPluginResult:result callbackId:self.syncCallbackId];
}];
} }
- (void) onStationaryLocation:(NSNotification*)notification - (void) onStationaryLocation:(NSNotification*)notification
{ {
CLLocation *location = notification.object;
NSDictionary *locationData = [bgGeo locationToDictionary:location];
if (![self.stationaryRegionListeners count]) { if (![self.stationaryRegionListeners count]) {
[bgGeo stopBackgroundTask];
return; return;
} }
CLLocation *location = [notification.userInfo objectForKey:@"location"];
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:locationData]; NSDictionary *locationData = [bgGeo locationToDictionary:location];
[result setKeepCallbackAsBool:YES];
for (NSString *callbackId in self.stationaryRegionListeners) for (NSString *callbackId in self.stationaryRegionListeners) {
{ NSDictionary *params = @{
[self.commandDelegate sendPluginResult:result callbackId:callbackId]; @"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];
}];
} }
[bgGeo stopBackgroundTask];
} }
- (void) onEnterGeofence:(NSNotification*)notification - (void) onEnterGeofence:(NSNotification*)notification
{ {
if (self.geofenceCallbackId == nil) { if (![self.geofenceListeners count]) {
return; return;
} }
CLCircularRegion *region = notification.object; CLCircularRegion *region = [notification.userInfo objectForKey:@"geofence"];
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:region.identifier]; for (NSString *callbackId in self.stationaryRegionListeners) {
[result setKeepCallbackAsBool:YES]; NSDictionary *params = @{
[self.commandDelegate sendPluginResult:result callbackId:self.geofenceCallbackId]; @"identifier": region.identifier,
@"taskId": @([bgGeo createBackgroundTask])
};
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:params];
[result setKeepCallbackAsBool:YES];
[self.commandDelegate runInBackground:^{
[self.commandDelegate sendPluginResult:result callbackId:callbackId];
}];
}
} }
/** /**
* Fetches current stationaryLocation * Fetches current stationaryLocation
...@@ -187,14 +204,18 @@ ...@@ -187,14 +204,18 @@
- (void) onGeofence:(CDVInvokedUrlCommand*)command - (void) onGeofence:(CDVInvokedUrlCommand*)command
{ {
self.geofenceCallbackId = command.callbackId; if (self.geofenceListeners == nil) {
self.geofenceListeners = [[NSMutableArray alloc] init];
}
[self.geofenceListeners addObject:command.callbackId];
} }
/** /**
* Called by js to signify the end of a background-geolocation event * Called by js to signify the end of a background-geolocation event
*/ */
-(void) finish:(CDVInvokedUrlCommand*)command -(void) finish:(CDVInvokedUrlCommand*)command
{ {
[bgGeo finish]; UIBackgroundTaskIdentifier taskId = [[command.arguments objectAtIndex: 0] integerValue];
[bgGeo stopBackgroundTask:taskId];
} }
/** /**
* If you don't stopMonitoring when application terminates, the app will be awoken still when a * If you don't stopMonitoring when application terminates, the app will be awoken still when a
......
...@@ -9,10 +9,10 @@ ...@@ -9,10 +9,10 @@
- (void) configure:(NSDictionary*)config; - (void) configure:(NSDictionary*)config;
- (void) start; - (void) start;
- (void) stop; - (void) stop;
- (void) finish;
- (NSArray*) sync; - (NSArray*) sync;
- (NSArray*) getLocations; - (NSArray*) getLocations;
- (void) stopBackgroundTask; - (UIBackgroundTaskIdentifier) createBackgroundTask;
- (void) stopBackgroundTask:(UIBackgroundTaskIdentifier)taskId;
- (void) onPaceChange:(BOOL)value; - (void) onPaceChange:(BOOL)value;
- (void) setConfig:(NSDictionary*)command; - (void) setConfig:(NSDictionary*)command;
- (NSDictionary*) getStationaryLocation; - (NSDictionary*) getStationaryLocation;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
<dict> <dict>
<key>Headers/TSLocationManager.h</key> <key>Headers/TSLocationManager.h</key>
<data> <data>
93eNJDqyN5vuBJn9oYeT7lb2x1w= w7pffjKj41qqtvUN0J6fOruESPM=
</data> </data>
<key>Info.plist</key> <key>Info.plist</key>
<data> <data>
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
<dict> <dict>
<key>Headers/TSLocationManager.h</key> <key>Headers/TSLocationManager.h</key>
<data> <data>
93eNJDqyN5vuBJn9oYeT7lb2x1w= w7pffjKj41qqtvUN0J6fOruESPM=
</data> </data>
<key>Modules/module.modulemap</key> <key>Modules/module.modulemap</key>
<data> <data>
......
...@@ -9,24 +9,30 @@ ...@@ -9,24 +9,30 @@
var exec = require("cordova/exec"); var exec = require("cordova/exec");
module.exports = { module.exports = {
/** /**
* @property {Object} stationaryRegion * @property {Object} stationaryLocation
*/ */
stationaryRegion: null, stationaryLocation: null,
/** /**
* @property {Object} config * @property {Object} config
*/ */
config: {}, config: {},
configure: function(success, failure, config) { configure: function(success, failure, config) {
var me = this;
config = config || {}; config = config || {};
this.config = config; this.config = config;
success = success || function(location) {}; success = success || function(location, taskId) {
var mySuccess = function(location) { me.finish(taskId);
};
var mySuccess = function(params) {
var location = params.location || params;
var taskId = params.taskId || 'task-id-undefined';
// Transform timestamp to Date instance. // Transform timestamp to Date instance.
if (location.timestamp) { if (location.timestamp) {
location.timestamp = new Date(location.timestamp); location.timestamp = new Date(location.timestamp);
} }
success.call(this, location); success.call(this, location, taskId);
} }
exec(mySuccess, exec(mySuccess,
failure || function() {}, failure || function() {},
...@@ -49,12 +55,15 @@ module.exports = { ...@@ -49,12 +55,15 @@ module.exports = {
'stop', 'stop',
[]); []);
}, },
finish: function(success, failure) { finish: function(taskId, success, failure) {
if (!taskId) {
throw "BackgroundGeolocation#finish must now be provided with a taskId as 1st param, eg: bgGeo.finish(taskId). taskId is provided by 2nd param in callback";
}
exec(success || function() {}, exec(success || function() {},
failure || function() {}, failure || function() {},
'BackgroundGeoLocation', 'BackgroundGeoLocation',
'finish', 'finish',
[]); [taskId]);
}, },
changePace: function(isMoving, success, failure) { changePace: function(isMoving, success, failure) {
exec(success || function() {}, exec(success || function() {},
...@@ -94,10 +103,15 @@ module.exports = { ...@@ -94,10 +103,15 @@ module.exports = {
*/ */
onStationary: function(success, failure) { onStationary: function(success, failure) {
var me = this; var me = this;
success = success || function() {}; success = success || function(location, taskId) {
var callback = function(region) { me.finish(taskId);
me.stationaryRegion = region; };
success.apply(me, arguments); var callback = function(params) {
var location = params.location || params,
taskId = params.taskId || 'task-id-undefined';
me.stationaryLocation = location;
success.call(me, location, taskId);
}; };
exec(callback, exec(callback,
failure || function() {}, failure || function() {},
...@@ -180,7 +194,13 @@ module.exports = { ...@@ -180,7 +194,13 @@ module.exports = {
if (!typeof(success) === 'function') { if (!typeof(success) === 'function') {
throw "#onGeofence requires a success callback"; throw "#onGeofence requires a success callback";
} }
exec(success, var me = this;
var mySuccess = function(params) {
var identifier = params.identifier,
taskId = params.taskId || 'task-id-undefined';
success.call(me, identifier, taskId);
}
exec(mySuccess,
failure || function() {}, failure || function() {},
'BackgroundGeoLocation', 'BackgroundGeoLocation',
'onGeofence', 'onGeofence',
......
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