cordova-background-geolocation-lt
Version:
Cordova / Capacitor Background Geolocation. The most sophisticated, cross-platform location-tracking and geofencing plugin with battery-conscious motion-detection intelligence.
615 lines (579 loc) • 20.4 kB
JavaScript
/**
* cordova-background-geolocation
* Copyright (c) 2015, Transistor Software (9224-2932 Quebec Inc)
* All rights reserved.
* sales@transistorsoft.com
* http://transistorsoft.com
* @see LICENSE
*/
var API = require('./API');
var DeviceSettings = require('./DeviceSettings');
var Logger = require('./Logger');
var TransistorAuthorizationToken = require('./TransistorAuthorizationToken');
var emptyFn = function() {};
module.exports = {
LOG_LEVEL_OFF: 0,
LOG_LEVEL_ERROR: 1,
LOG_LEVEL_WARNING: 2,
LOG_LEVEL_INFO: 3,
LOG_LEVEL_DEBUG: 4,
LOG_LEVEL_VERBOSE: 5,
// For #desiredAccuracy
DESIRED_ACCURACY_NAVIGATION: -2,
DESIRED_ACCURACY_HIGH: -1,
DESIRED_ACCURACY_MEDIUM: 10,
DESIRED_ACCURACY_LOW: 100,
DESIRED_ACCURACY_VERY_LOW: 1000,
DESIRED_ACCURACY_THREE_KILOMETER: 3000,
// For providerchange event
AUTHORIZATION_STATUS_NOT_DETERMINED: 0,
AUTHORIZATION_STATUS_RESTRICTED: 1,
AUTHORIZATION_STATUS_DENIED: 2,
AUTHORIZATION_STATUS_ALWAYS: 3,
AUTHORIZATION_STATUS_WHEN_IN_USE: 4,
// For android #notificationPriority
NOTIFICATION_PRIORITY_DEFAULT: 0,
NOTIFICATION_PRIORITY_HIGH: 1,
NOTIFICATION_PRIORITY_LOW: -1,
NOTIFICATION_PRIORITY_MAX: 2,
NOTIFICATION_PRIORITY_MIN: -2,
// For iOS #activityType
ACTIVITY_TYPE_OTHER: 1,
ACTIVITY_TYPE_AUTOMOTIVE_NAVIGATION: 2,
ACTIVITY_TYPE_FITNESS: 3,
ACTIVITY_TYPE_OTHER_NAVIGATION: 4,
ACTIVITY_TYPE_AIRBORNE: 5,
// For persistMode
PERSIST_MODE_ALL: 2,
PERSIST_MODE_LOCATION: 1,
PERSIST_MODE_GEOFENCE: -1,
PERSIST_MODE_NONE: 0,
ACCURACY_AUTHORIZATION_FULL: 0,
ACCURACY_AUTHORIZATION_REDUCED: 1,
deviceSettings: DeviceSettings,
logger: Logger,
ready: function(defaultConfig, success, failure) {
if (arguments.length <= 1) {
return API.ready(defaultConfig||{});
} else {
API.ready(defaultConfig).then(success).catch(failure);
}
},
configure: function(config, success, failure) {
config = config || {};
if (arguments.length == 1) {
return API.configure(config);
} else {
API.configure(config).then(success).catch(failure);
}
},
reset: function(config, success, failure) {
if ((typeof(config) === 'function') || (typeof(success) === 'function')) {
if (typeof(config) === 'function') {
success = config;
config = undefined;
}
API.reset(config).then(success).catch(failure);
} else {
return API.reset(config);
}
},
requestPermission: function(success, failure) {
if (!arguments.length) {
return API.requestPermission();
} else {
API.requestPermission().then(success).catch(failure);
}
},
requestTemporaryFullAccuracy: function(purpose) {
return API.requestTemporaryFullAccuracy(purpose);
},
getProviderState: function(success, failure) {
if (!arguments.length) {
return API.getProviderState();
} else {
API.getProviderState().then(success).catch(failure);
}
},
onLocation: function(success, failure) {
return this.on('location', success, failure);
},
onMotionChange: function(callback) {
return this.on('motionchange', callback);
},
onHttp: function(callback) {
return this.on('http', callback);
},
onHeartbeat: function(callback) {
return this.on('heartbeat', callback);
},
onProviderChange: function(callback) {
return this.on('providerchange', callback);
},
onActivityChange: function(callback) {
return this.on('activitychange', callback);
},
onGeofence: function(callback) {
return this.on('geofence', callback);
},
onGeofencesChange: function(callback) {
return this.on('geofenceschange', callback);
},
onSchedule: function(callback) {
return this.on('schedule', callback);
},
onEnabledChange: function(callback) {
return this.on('enabledchange', callback);
},
onConnectivityChange: function(callback) {
return this.on('connectivitychange', callback);
},
onPowerSaveChange: function(callback) {
return this.on('powersavechange', callback);
},
onNotificationAction: function(callback) {
return this.on('notificationaction', callback);
},
onAuthorization: function(callback) {
return this.on('authorization', callback);
},
on: function(event, success, failure) {
if (typeof(success) !== 'function') {
throw "BackgroundGeolocation event '" + event + "' was not provided with a success callback. If you're attempting to use Promise API to add an event-listener, that won't work, since a Promise can only evaluate once.";
}
failure = failure || emptyFn;
return API.addListener(event, success, failure);
},
/**
* @alias #removeListener
*/
un: function() {
return this.removeListener.apply(this, arguments);
},
removeListener: function(event, handler, success, failure) {
if (arguments.length == 2) {
return API.removeListener(event, handler);
} else {
API.removeListener(event, handler).then(success).catch(failure);
}
},
removeListeners: function(success, failure) {
if (!arguments.length) {
return API.removeListeners();
} else {
API.removeListeners().then(success).catch(failure);
}
},
getState: function(success, failure) {
if (!arguments.length) {
return API.getState();
} else {
API.getState().then(success).catch(failure);
}
},
start: function(success, failure) {
if (!arguments.length) {
return API.start();
} else {
API.start().then(success).catch(failure);
}
},
stop: function(success, failure) {
if (!arguments.length) {
return API.stop();
} else {
API.stop().then(success).catch(failure);
}
},
startSchedule: function(success, failure) {
if (!arguments.length) {
return API.startSchedule();
} else {
API.startSchedule().then(success).catch(failure);
}
},
stopSchedule: function(success, failure) {
if (!arguments.length) {
return API.stopSchedule();
} else {
API.stopSchedule().then(success).catch(failure);
}
},
startGeofences: function(success, failure) {
if (!arguments.length) {
return API.startGeofences();
} else {
API.startGeofences().then(success).catch(failure);
}
},
startBackgroundTask: function(success, failure) {
if (!arguments.length) {
return API.startBackgroundTask();
} else {
API.startBackgroundTask().then(success).catch(failure);
}
},
stopBackgroundTask: function(taskId, success, failure) {
if (arguments.length == 1) {
return API.stopBackgroundTask(taskId);
} else {
API.stopBackgroundTask(taskId).then(success).catch(failure);
}
},
finish: function(taskId, success, failure) {
return this.stopBackgroundTask.apply(this, arguments);
},
changePace: function(isMoving, success, failure) {
if (arguments.length == 1) {
return API.changePace(isMoving);
} else {
API.changePace(isMoving).then(success).catch(failure);
}
},
setConfig: function(config, success, failure) {
if (arguments.length == 1) {
return API.setConfig(config);
} else {
API.setConfig(config).then(success).catch(failure);
}
},
getLocations: function(success, failure) {
if (!arguments.length) {
return API.getLocations();
} else {
API.getLocations().then(success).catch(failure);
}
},
getCount: function(success, failure) {
if (!arguments.length) {
return API.getCount();
} else {
API.getCount().then(success).catch(failure);
}
},
destroyLocations: function(success, failure) {
if (!arguments.length) {
return API.destroyLocations();
} else {
API.destroyLocations().then(success).catch(failure);
}
},
destroyLocation: function(uuid) {
return API.destroyLocation(uuid);
},
// @deprecated
clearDatabase: function() {
return this.destroyLocations.apply(this, arguments);
},
insertLocation: function(location, success, failure) {
if (arguments.length == 1) {
return API.insertLocation(location);
} else {
API.insertLocation(location).then(success).catch(failure);
}
},
sync: function(success, failure) {
if (!arguments.length) {
return API.sync();
} else{
API.sync().then(success).catch(failure);
}
},
getOdometer: function(success, failure) {
if (!arguments.length) {
return API.getOdometer();
} else {
API.getOdometer().then(success).catch(failure);
}
},
resetOdometer: function(success, failure) {
if (!arguments.length) {
return API.setOdometer(0);
} else {
API.setOdometer(0).then(success).catch(failure);
}
},
setOdometer: function(value, success, failure) {
if (arguments.length == 1) {
return API.setOdometer(value);
} else {
API.setOdometer(value).then(success).catch(failure);
}
},
addGeofence: function(config, success, failure) {
if (arguments.length == 1) {
return API.addGeofence(config);
} else {
API.addGeofence(config).then(success).catch(failure);
}
},
removeGeofence: function(identifier, success, failure) {
if (arguments.length == 1) {
return API.removeGeofence(identifier);
} else {
API.removeGeofence(identifier).then(success).catch(failure);
}
},
addGeofences: function(geofences, success, failure) {
if (arguments.length == 1) {
return API.addGeofences(geofences);
} else {
API.addGeofences(geofences).then(success).catch(failure);
}
},
/**
* 1. removeGeofences() <-- Promise
* 2. removeGeofences(['foo']) <-- Promise
*
* 3. removeGeofences(success, [failure])
* 4. removeGeofences(['foo'], success, [failure])
*/
removeGeofences: function(identifiers, success, failure) {
if ( (arguments.length <= 1) && (typeof(identifiers) !== 'function') ) {
return API.removeGeofences(identifiers);
} else {
if (typeof(identifiers) === 'function') {
// 3. -> removeGeofences(success, failure?)
failure = success || emptyFn;
success = identifiers;
identifiers = [];
}
API.removeGeofences(identifiers).then(success).catch(failure);
}
},
getGeofences: function(success, failure) {
if (!arguments.length) {
return API.getGeofences();
} else {
API.getGeofences().then(success).catch(failure);
}
},
getGeofence: function(identifier, success, failure) {
if (arguments.length == 1) {
return API.getGeofence(identifier);
} else {
API.getGeofence(identifier).then(success).catch(failure);
}
},
geofenceExists: function(identifier, callback) {
if (arguments.length == 1) {
return API.geofenceExists(identifier);
} else {
API.geofenceExists(identifier).then(callback).catch(callback);
}
},
getCurrentPosition: function(options, success, failure) {
if (typeof (options) === 'function') {
throw "#getCurrentPosition requires options {} as first argument";
}
if (typeof(success) === 'function') {
options = options || {};
API.getCurrentPosition(options).then(success).catch(failure);
} else {
return API.getCurrentPosition.apply(API, arguments);
}
},
watchPosition: function(success, failure, options) {
if (typeof(success) === 'function') {
API.watchPosition.apply(API, arguments);
} else {
throw "BackgroundGeolocation#watchPosition does not support Promise API, since Promises cannot resolve multiple times. The #watchPosition callback *will* be run multiple times. Use the #watchPosition(success, failure, options) API.";
}
},
stopWatchPosition: function(success, failure) {
if (!arguments.length) {
return API.stopWatchPosition();
} else {
API.stopWatchPosition().then(success).catch(failure);
}
},
registerHeadlessTask: function(callback) {
console.warn('[BackgroundGeolocation registerHeadlessTask] -- Cordova has no Javascript mechanism for registering Headless-tasks. See Wiki https://github.com/transistorsoft/cordova-background-geolocation-lt/wiki/Android-Headless-Mode');
},
setLogLevel: function(logLevel, success, failure) {
if (arguments.length == 1) {
return API.setLogLevel(logLevel);
} else {
API.setLogLevel(logLevel).then(success).catch(failure);
}
},
getLog: function(success, failure) {
console.warn('[⚠️ deprecated BackgroundGeolocation.getLog] Use BackgroundGeolocation.logger.getLog');
if (!arguments.length) {
return Logger.getLog();
} else {
Logger.getLog().then(success).catch(failure);
}
},
destroyLog: function(success, failure) {
console.warn('[⚠️ deprecated BackgroundGeolocation.destroyLog] Use BackgroundGeolocation.logger.destroyLog');
if (!arguments.length) {
return Logger.destroyLog();
} else {
Logger.destroyLog().then(success).catch(failure);
}
},
emailLog: function(email, success, failure) {
console.warn('[⚠️ deprecated BackgroundGeolocation.emailLog] Use BackgroundGeolocation.logger.emailLog');
if (arguments.length == 1) {
return Logger.emailLog(email);
} else {
Logger.emailLog(email).then(success).catch(failure);
}
},
isPowerSaveMode: function(success, failure) {
if (!arguments.length) {
return API.isPowerSaveMode();
} else {
API.isPowerSaveMode().then(success).catch(failure);
}
},
getSensors: function(success, failure) {
if (!arguments.length) {
return API.getSensors();
} else {
API.getSensors().then(success).catch(failure);
}
},
getDeviceInfo: function() {
return API.getDeviceInfo();
},
/**
* Play a system sound. This is totally experimental.
* iOS http://iphonedevwiki.net/index.php/AudioServices
* Android:
*/
playSound: function(soundId) {
return API.playSound(soundId);
},
/**
* Returns a #params object suitable for recognition by tracker.transistorsoft.com
* @param {Device} cordova-plugin-device instance
* @return {Object}
*/
transistorTrackerParams: function(device) {
if (typeof(device) === undefined) { throw "An instance of cordova-plugin-device must be provided"; }
if (typeof(device.model) === undefined) { throw "Invalid instance of cordova-plugin-device"; }
return {
device: {
model: device.model,
platform: device.platform,
uuid: device.model.replace(/[\s\.,]/g, '-'),
version: device.version,
manufacturer: device.manufacturer,
framework: 'Cordova'
}
};
},
/**
* Register a device with tracker.transistorsoft.com. The server returns an authorization token (JWT)
* This behaviour is specific to the Demo app.
*/
findOrCreateTransistorAuthorizationToken: function(orgname, username, url) {
return TransistorAuthorizationToken.findOrCreate(orgname, username, url);
},
destroyTransistorAuthorizationToken: function(url) {
return TransistorAuthorizationToken.destroy(url);
},
test: function(delay) {
test(this, delay);
}
};
var test = function(bgGeo, delay) {
delay = delay || 250;
var methods = [
['reset', {debug: true, logLevel: 5}],
['setConfig', {distanceFilter: 50}],
['setLogLevel', 5],
['getLog', null],
['emailLog', 'foo@bar.com'],
['on', 'location'],
['ready', {}],
['configure', {debug: true, logLevel: 5, schedule: ['1-7 00:00-23:59']}],
['getState', null],
['startSchedule', null],
['stopSchedule', null],
['startGeofences', null],
['stop', null],
['start', null],
['startBackgroundTask', null],
['finish', 0],
['changePace', true],
['getLocations', null],
['insertLocation', {}],
['sync', null],
['getOdometer', null],
['setOdometer', 0],
['resetOdometer'],
['addGeofence', {identifier: 'test-geofence-1', radius: 100, latitude: 0, longitude:0, notifyOnEntry:true}],
['addGeofences', [{identifier: 'test-geofence-2', radius: 100, latitude: 0, longitude:0, notifyOnEntry:true}, {identifier: 'test-geofence-3', radius: 100, latitude: 0, longitude:0, notifyOnEntry:true}]],
['getGeofences', null],
['removeGeofence', 'test-geofence-1'],
['removeGeofences', null],
['getCurrentPosition', {}],
['watchPosition', {}],
['stopWatchPosition', null],
['isPowerSaveMode', null],
['getSensors', null],
['playSound', 1509],
['destroyLocations', null],
['clearDatabase', null],
['destroyLog', null],
['removeListeners', null]
];
var createCallback = function(type, method, params) {
return function(result) {
console.log('- ' + method + '(' + params + ') - ' + type + ': ', result);
}
}
var executeMethod = function(record) {
console.log('* Execute method: ', record)
var method = '' + record[0];
var params = record[1];
var success = createCallback('success', method, params);
var failure = createCallback('failure', method, params);
// Execute Standard API
try {
console.log('- Standard API: ' + method);
if (params == null) {
bgGeo[method](success, failure);
} else {
// Adjust params for different signatures.
switch (method) {
case 'watchPosition':
case 'getCurrentPosition':
bgGeo[method](success, failure, params);
break;
default:
bgGeo[method](params, success, failure);
break;
}
}
} catch (e) {
console.warn(e);
}
// Execute Promise API
setTimeout(function() {
console.log('- Promise API: ' + method);
try {
if (params == null) {
bgGeo[method]().then(success).catch(failure);
} else {
bgGeo[method](params).then(success).catch(failure);
}
} catch (e) {
console.warn(e);
}
}, 10);
}
// Begin fetching methods.
var intervalId = setInterval(function() {
var record = methods.shift();
if (!record || !methods.length) {
clearInterval(intervalId);
console.log('*** TEST COMPLETE ***');
return;
}
executeMethod(record);
}, delay);
}