├── .gitignore
├── CHANGELOG.md
├── ISSUE_TEMPLATE.md
├── LICENSE
├── README.md
├── background-geolocation.ts
├── demo
├── app
│ ├── App_Resources
│ │ ├── Android
│ │ │ ├── app.gradle
│ │ │ └── src
│ │ │ │ └── main
│ │ │ │ ├── AndroidManifest.xml
│ │ │ │ └── res
│ │ │ │ ├── drawable-hdpi
│ │ │ │ ├── background.png
│ │ │ │ ├── icon.png
│ │ │ │ └── logo.png
│ │ │ │ ├── drawable-ldpi
│ │ │ │ ├── background.png
│ │ │ │ ├── icon.png
│ │ │ │ └── logo.png
│ │ │ │ ├── drawable-mdpi
│ │ │ │ ├── background.png
│ │ │ │ ├── icon.png
│ │ │ │ └── logo.png
│ │ │ │ ├── drawable-nodpi
│ │ │ │ └── splash_screen.xml
│ │ │ │ ├── drawable-xhdpi
│ │ │ │ ├── background.png
│ │ │ │ ├── icon.png
│ │ │ │ └── logo.png
│ │ │ │ ├── drawable-xxhdpi
│ │ │ │ ├── background.png
│ │ │ │ ├── icon.png
│ │ │ │ └── logo.png
│ │ │ │ ├── drawable-xxxhdpi
│ │ │ │ ├── background.png
│ │ │ │ ├── icon.png
│ │ │ │ └── logo.png
│ │ │ │ ├── values-v21
│ │ │ │ ├── colors.xml
│ │ │ │ └── styles.xml
│ │ │ │ └── values
│ │ │ │ ├── colors.xml
│ │ │ │ └── styles.xml
│ │ └── iOS
│ │ │ ├── Assets.xcassets
│ │ │ ├── AppIcon.appiconset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── icon-1024.png
│ │ │ │ ├── icon-29.png
│ │ │ │ ├── icon-29@2x.png
│ │ │ │ ├── icon-29@3x.png
│ │ │ │ ├── icon-40.png
│ │ │ │ ├── icon-40@2x.png
│ │ │ │ ├── icon-40@3x.png
│ │ │ │ ├── icon-60@2x.png
│ │ │ │ ├── icon-60@3x.png
│ │ │ │ ├── icon-76.png
│ │ │ │ ├── icon-76@2x.png
│ │ │ │ └── icon-83.5@2x.png
│ │ │ ├── Contents.json
│ │ │ ├── LaunchImage.launchimage
│ │ │ │ ├── Contents.json
│ │ │ │ ├── Default-1125h.png
│ │ │ │ ├── Default-568h@2x.png
│ │ │ │ ├── Default-667h@2x.png
│ │ │ │ ├── Default-736h@3x.png
│ │ │ │ ├── Default-Landscape-X.png
│ │ │ │ ├── Default-Landscape.png
│ │ │ │ ├── Default-Landscape@2x.png
│ │ │ │ ├── Default-Landscape@3x.png
│ │ │ │ ├── Default-Portrait.png
│ │ │ │ ├── Default-Portrait@2x.png
│ │ │ │ ├── Default.png
│ │ │ │ └── Default@2x.png
│ │ │ ├── LaunchScreen.AspectFill.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── LaunchScreen-AspectFill.png
│ │ │ │ └── LaunchScreen-AspectFill@2x.png
│ │ │ └── LaunchScreen.Center.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── LaunchScreen-Center.png
│ │ │ │ └── LaunchScreen-Center@2x.png
│ │ │ ├── Info.plist
│ │ │ ├── LaunchScreen.storyboard
│ │ │ └── build.xcconfig
│ ├── README.md
│ ├── app-root.xml
│ ├── app.css
│ ├── app.ts
│ ├── bundle-config.ts
│ ├── css
│ │ └── ionicons.min.css
│ ├── fonts
│ │ └── ionicons.ttf
│ ├── main-page.ts
│ ├── main-page.xml
│ ├── main-view-model.ts
│ └── package.json
├── package.json
└── tsconfig.json
├── docs
├── README.md
├── geofencing.md
└── http.md
└── src
├── .npmignore
├── HeadlessBroadcastReceiver.android.d.ts
├── HeadlessBroadcastReceiver.android.ts
├── HeadlessJobService.android.d.ts
├── HeadlessJobService.android.ts
├── api.android.d.ts
├── api.android.ts
├── api.ios.d.ts
├── api.ios.ts
├── background-geolocation.d.ts
├── background-geolocation.ts
├── package.json
├── platforms
├── android
│ ├── AndroidManifest.xml
│ ├── include.gradle
│ ├── libs
│ │ └── tslocationmanager-2.12.19.aar
│ └── nativescript_background_geolocation_lt.aar
└── ios
│ ├── Info.plist
│ ├── Podfile
│ ├── TSLocationManager.framework
│ ├── Headers
│ │ ├── LocationManager.h
│ │ ├── TSActivityChangeEvent.h
│ │ ├── TSConfig.h
│ │ ├── TSConnectivityChangeEvent.h
│ │ ├── TSCurrentPositionRequest.h
│ │ ├── TSEnabledChangeEvent.h
│ │ ├── TSGeofence.h
│ │ ├── TSGeofenceEvent.h
│ │ ├── TSGeofencesChangeEvent.h
│ │ ├── TSHeartbeatEvent.h
│ │ ├── TSHttpEvent.h
│ │ ├── TSLocation.h
│ │ ├── TSLocationManager.h
│ │ ├── TSPowerSaveChangeEvent.h
│ │ ├── TSProviderChangeEvent.h
│ │ ├── TSSchedule.h
│ │ ├── TSScheduleEvent.h
│ │ └── TSWatchPositionRequest.h
│ ├── Info.plist
│ ├── Modules
│ │ └── module.modulemap
│ ├── TSLocationManager
│ └── _CodeSignature
│ │ ├── CodeDirectory
│ │ ├── CodeRequirements
│ │ ├── CodeRequirements-1
│ │ ├── CodeResources
│ │ └── CodeSignature
│ └── nativescript-background-geolocation-lt.podspec
├── references.d.ts
└── tsconfig.json
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | *.js
3 | *.js.map
4 | *.log
5 | demo/app/*.js
6 | demo/*.d.ts
7 | demo/platforms
8 | demo/node_modules
9 | demo/lib
10 | node_modules
11 | package-lock.json
12 | .DS_Store
13 |
--------------------------------------------------------------------------------
/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
6 |
7 |
10 | ## Your Environment
11 | * Plugin version:
12 | * Platform: iOS or Android
13 | * OS version:
14 | * Device manufacturer / model:
15 | * Nativescript version (`tns info`):
16 | * Plugin config
17 |
18 | ## Expected Behavior
19 |
22 |
23 | ## Actual Behavior
24 |
27 |
28 | ## Steps to Reproduce
29 |
32 | 1.
33 | 2.
34 | 3.
35 | 4.
36 |
37 | ## Context
38 |
41 |
42 | ## Debug logs
43 |
49 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Transistor Software
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Background Geolocation for NativeScript ·
2 | ==============================================================================
3 |
4 | No longer supported for NativeScript.
5 |
6 | See the [Cordova/Ionic](https://github.com/transistorsoft/cordova-background-geolocation-lt), [React Native](https://github.com/transistorsoft/react-native-background-geolocation) or [Flutter](https://github.com/transistorsoft/flutter_background_geolocation) versions.
7 |
--------------------------------------------------------------------------------
/background-geolocation.ts:
--------------------------------------------------------------------------------
1 | import {device} from "platform";
2 | import Platform = require('platform');
3 |
4 | const TAG = "TSLocationManager";
5 | let emptyFn = function(){};
6 |
7 | /**
8 | * Url to transistorsoft tracking test server. Configure the plugin with a #username to automatically post
9 | * locations to the test server, eg:
10 | {
11 | username: 'my-username'
12 | }
13 | * View your tracking online by visiting:
14 | * http://tracker.transistorsoft.com/username
15 | *
16 | */
17 | const TEST_SERVER_URL = 'http://tracker.transistorsoft.com/locations/';
18 |
19 | /**
20 | * Logger
21 | */
22 | export class Logger {
23 | private api:any;
24 |
25 | constructor(api:any) {
26 | this.api = api;
27 | }
28 | public error(msg:string) {
29 | this.log('error', msg);
30 | }
31 | public warn(msg:string) {
32 | this.log('warn', msg);
33 | }
34 | public debug(msg:string) {
35 | this.log('debug', msg);
36 | }
37 | public notice(msg:string) {
38 | this.log('notice', msg);
39 | }
40 | public header(msg:string) {
41 | this.log('header', msg);
42 | }
43 | public on(msg:string) {
44 | this.log('on', msg);
45 | }
46 | public off(msg:string) {
47 | this.log('off', msg);
48 | }
49 | public ok(msg:string) {
50 | this.log('ok', msg);
51 | }
52 | private log(level:string, msg:string) {
53 | this.api.log(level, msg);
54 | }
55 | }
56 |
57 | /**
58 | * BackgroundGeolocation
59 | */
60 | export class BackgroundGeolocation {
61 |
62 | private static api: any;
63 |
64 | public static logger:Logger;
65 |
66 | public static LOG_LEVEL_OFF:number = 0;
67 | public static LOG_LEVEL_ERROR:number = 1;
68 | public static LOG_LEVEL_WARNING:number = 2;
69 | public static LOG_LEVEL_INFO:number = 3;
70 | public static LOG_LEVEL_DEBUG:number = 4;
71 | public static LOG_LEVEL_VERBOSE:number = 5;
72 |
73 | public static DESIRED_ACCURACY_NAVIGATION:number = -2;
74 | public static DESIRED_ACCURACY_HIGH:number = -1;
75 | public static DESIRED_ACCURACY_MEDIUM:number = 10;
76 | public static DESIRED_ACCURACY_LOW:number = 100;
77 | public static DESIRED_ACCURACY_VERY_LOW:number = 1000;
78 | public static DESIRED_ACCURACY_LOWEST:number = 3000;
79 |
80 | public static AUTHORIZATION_STATUS_NOT_DETERMINED:number = 0;
81 | public static AUTHORIZATION_STATUS_RESTRICTED:number = 1;
82 | public static AUTHORIZATION_STATUS_DENIED:number = 2;
83 | public static AUTHORIZATION_STATUS_ALWAYS:number = 3;
84 | public static AUTHORIZATION_STATUS_WHEN_IN_USE:number = 4;
85 |
86 | public static NOTIFICATION_PRIORITY_DEFAULT:number = 0;
87 | public static NOTIFICATION_PRIORITY_HIGH:number = 1;
88 | public static NOTIFICATION_PRIORITY_LOW:number =-1;
89 | public static NOTIFICATION_PRIORITY_MAX:number = 2;
90 | public static NOTIFICATION_PRIORITY_MIN:number =-2;
91 |
92 | public static mountNativeApi(api) {
93 | this.api = api;
94 | this.logger = new Logger(api);
95 | }
96 |
97 | public static EVENTS:String[] = [
98 | 'heartbeat',
99 | 'http',
100 | 'location',
101 | 'error',
102 | 'motionchange',
103 | 'geofence',
104 | 'schedule',
105 | 'activitychange',
106 | 'providerchange',
107 | 'geofenceschange',
108 | 'watchposition',
109 | 'powersavechange',
110 | 'connectivitychange',
111 | 'enabledchange'
112 | ];
113 |
114 | private static listeners = {
115 | location: [],
116 | http: [],
117 | motionchange: [],
118 | error: [],
119 | heartbeat: [],
120 | schedule: [],
121 | activitychange: [],
122 | providerchange: [],
123 | geofence: [],
124 | geofenceschange: [],
125 | powersavechange: [],
126 | connectivitychange: [],
127 | enabledchange: []
128 | };
129 |
130 | private static headlessTask: Function;
131 |
132 | public static registerHeadlessTask(callback:Function) {
133 | this.headlessTask = callback;
134 | }
135 |
136 | public static runHeadlessTask(event:any, completionHandler:Function) {
137 | if (this.headlessTask) {
138 | this.headlessTask(event, completionHandler);
139 | }
140 | }
141 |
142 | /**
143 | * Core Plugin Control Methods
144 | */
145 | public static ready(config:any, success?:Function, failure?:Function) {
146 | config = this.validate(config);
147 | if (arguments.length <= 1) {
148 | return this.api.ready(config||{});
149 | } else {
150 | this.api.ready(config).then(success).catch(failure);
151 | }
152 | }
153 | /**
154 | * Reset plugin confg to default
155 | */
156 | static reset(config?:any, success?:Function, failure?:Function) {
157 | if ((typeof(config) === 'function') || (typeof(success) === 'function')) {
158 | if (typeof(config) === 'function') {
159 | success = config;
160 | config = {};
161 | }
162 | config = this.validate(config||{});
163 | this.api.reset(config).then(success).catch(failure);
164 | } else {
165 | return this.api.reset(this.validate(config||{}));
166 | }
167 | }
168 | /**
169 | * Perform initial configuration of plugin. Reset config to default before applying supplied configuration
170 | */
171 | public static configure(config:any, success?:Function, failure?:Function) {
172 | config = this.validate(config);
173 | if (arguments.length == 1) {
174 | return this.api.configure(config);
175 | } else {
176 | this.api.configure(config).then(success).catch(failure);
177 | }
178 | }
179 | /**
180 | * Listen to a plugin event
181 | */
182 | public static addListener(event:string, success:Function, failure?:Function) {
183 | if (this.EVENTS.indexOf(event) < 0) { throw "BackgroundGeolocation#on - Unknown event '" + event + "'" }
184 | let nativeCallback = this.api.addListener.apply(this.api, arguments);
185 | if (nativeCallback) {
186 | this.registerCallback(event, success, nativeCallback);
187 | }
188 | }
189 |
190 | private static registerCallback(event:string, clientCallback:Function, nativeCallback:Function) {
191 | this.listeners[event].push({
192 | clientCallback: clientCallback,
193 | nativeCallback: nativeCallback
194 | });
195 | }
196 |
197 | // @alias #addListener
198 | public static on(event:string, success:Function, failure?:Function) {
199 | this.addListener.apply(this, arguments);
200 | }
201 | /**
202 | * Remove a single plugin event-listener, supplying a reference to the handler initially supplied to #un
203 | */
204 | public static removeListener(event:string, clientCallback:Function, success?:Function, failure?:Function) {
205 | if (this.EVENTS.indexOf(event) < 0) { throw "BackgroundGeolocation#un - Unknown event '" + event + "'" }
206 | let listeners = this.listeners[event];
207 |
208 | let listener = listeners.find((i) => { return i.clientCallback === clientCallback; });
209 | if (listener) {
210 | listeners.splice(listeners.indexOf(listener), 1);
211 | if (arguments.length == 2) {
212 | return this.api.removeListener(event, listener.nativeCallback);
213 | } else {
214 | this.api.removeListener(event, listener.nativeCallback).then(success).catch(failure);
215 | }
216 | } else {
217 | let error = 'Failed to removeListener for event: ' + event;
218 | failure = failure || emptyFn;
219 | console.warn(error);
220 | if (arguments.length == 2) {
221 | return new Promise((resolve, reject) => {
222 | reject(error);
223 | });
224 | } else {
225 | failure(msg);
226 | }
227 | }
228 | }
229 |
230 | // @alias #removeListener
231 | public static un(event:string, handler:Function, success?:Function, failiure?:Function) {
232 | this.removeListener.apply(this, arguments);
233 | }
234 |
235 | /**
236 | * Remove all event listeners
237 | */
238 | public static removeListeners(event?:any, success?:Function, failure?:Function) {
239 | if (!arguments.length) {
240 | return this.api.removeListeners(); // #removeListeners()
241 | } else if(typeof(arguments[0]) === 'string') {
242 | if (this.EVENTS.indexOf(event) < 0) {
243 | throw "BackgroundGeolocation#removeListeners - Unknown event: " + event;
244 | }
245 | // Clear client-calllbacks.
246 | this.listeners[event] = [];
247 | if (typeof(arguments[1]) === 'function') { // #removeListeners(event, success, failure);
248 | this.api.removeListeners(event).then(success).catch(failure);
249 | } else { // #removeListeners(event)
250 | return this.api.removeListeners(event);
251 | }
252 | } else if (typeof(arguments[0]) === 'function') { // #removeListeners(success, failure)
253 | success = event;
254 | failure = success;
255 | this.api.removeListeners().then(success).catch(failure);
256 | }
257 | }
258 |
259 | /**
260 | * Fetch current plugin configuration
261 | */
262 | public static getState(success?:Function, failure?:Function) {
263 | if (!arguments.length) {
264 | return this.api.getState();
265 | } else {
266 | this.api.getState().then(success).catch(failure);
267 | }
268 | }
269 | /**
270 | * Start the plugin
271 | */
272 | public static start(success?:Function, failure?:Function) {
273 | if (!arguments.length) {
274 | return this.api.start();
275 | } else {
276 | this.api.start().then(success).catch(failure);
277 | }
278 | }
279 | /**
280 | * Stop the plugin
281 | */
282 | public static stop(success?:Function, failure?:Function) {
283 | if (!arguments.length) {
284 | return this.api.stop();
285 | } else {
286 | this.api.stop().then(success).catch(failure);
287 | }
288 | }
289 | /**
290 | * Start the scheduler
291 | */
292 | public static startSchedule(success?:Function, failure?:Function) {
293 | if (!arguments.length) {
294 | return this.api.startSchedule();
295 | } else {
296 | this.api.startSchedule().then(success).catch(failure);
297 | }
298 | }
299 | /**
300 | * Stop the scheduler
301 | */
302 | public static stopSchedule(success?:Function, failure?:Function) {
303 | if (!arguments.length) {
304 | return this.api.stopSchedule();
305 | } else {
306 | this.api.stopSchedule().then(success).catch(failure);
307 | }
308 | }
309 | /**
310 | * Initiate geofences-only mode
311 | */
312 | public static startGeofences(success?:Function, failure?:Function) {
313 | if (!arguments.length) {
314 | return this.api.startGeofences();
315 | } else {
316 | this.api.startGeofences().then(success).catch(failure);
317 | }
318 | }
319 | /**
320 | * Start an iOS background-task, provding 180s of background running time
321 | */
322 | public static startBackgroundTask(success?:Function, failure?:Function) {
323 | if (!arguments.length) {
324 | return this.api.startBackgroundTask();
325 | } else {
326 | if (typeof(success) !== 'function') {
327 | throw TAG + "#startBackgroundTask must be provided with a callback to recieve the taskId";
328 | }
329 | this.api.startBackgroundTask().then(success).catch(failure);
330 | }
331 | }
332 | /**
333 | * Signal to iOS that your background-task from #startBackgroundTask is complete
334 | */
335 | public static finish(taskId:number, success?:Function, failure?:Function) {
336 | // No taskId? Ignore it.
337 | if (arguments.length == 1) {
338 | return this.api.finish(taskId);
339 | } else {
340 | this.api.finish(taskId).then(success).catch(failure);
341 | }
342 | }
343 | /**
344 | * Toggle motion-state between stationary <-> moving
345 | */
346 | public static changePace(isMoving:boolean, success?:Function, failure?:Function) {
347 | if (arguments.length == 1) {
348 | return this.api.changePace(isMoving);
349 | } else {
350 | this.api.changePace(isMoving).then(success).catch(failure);
351 | }
352 | }
353 | /**
354 | * Provide new configuration to the plugin. This configuration will be *merged* to current configuration
355 | */
356 | public static setConfig(config:any, success?:Function, failure?:Function) {
357 | if (arguments.length == 1) {
358 | return this.api.setConfig(config);
359 | } else {
360 | this.api.setConfig(config).then(success).catch(failure);
361 | }
362 | }
363 | /**
364 | * HTTP & Persistence
365 | *
366 | */
367 | public static getLocations(success?:Function, failure?:Function) {
368 | if (!arguments.length) {
369 | return this.api.getLocations();
370 | } else {
371 | this.api.getLocations().then(success).catch(failure);
372 | }
373 | }
374 | /**
375 | * Fetch the current count of location records in database
376 | */
377 | public static getCount(success?:Function, failure?:Function) {
378 | if (!arguments.length) {
379 | return this.api.getCount();
380 | } else {
381 | this.api.getCount().then(success).catch(failure);
382 | }
383 | }
384 | /**
385 | * Destroy all records in locations database
386 | */
387 | public static destroyLocations(success?:Function, failure?:Function) {
388 | if (!arguments.length) {
389 | return this.api.destroyLocations();
390 | } else {
391 | this.api.destroyLocations().then(success).catch(failure);
392 | }
393 | }
394 | // @deprecated
395 | public static clearDatabase(success?:Function, failure?:Function) {
396 | return this.destroyLocations.apply(this, arguments);
397 | }
398 | /**
399 | * Insert a single record into locations database
400 | */
401 | public static insertLocation(location:any, success?:Function, failure?:Function) {
402 | if (arguments.length == 1) {
403 | return this.api.insertLocation(location);
404 | } else {
405 | this.api.insertLocation(location).then(success).catch(failure);
406 | }
407 | }
408 | /**
409 | * Manually initiate an HTTP sync operation
410 | */
411 | public static sync(success?:Function, failure?:Function) {
412 | if (!arguments.length) {
413 | return this.api.sync();
414 | } else {
415 | this.api.sync().then(success).catch(failure);
416 | }
417 | }
418 | /**
419 | * Fetch the current value of odometer
420 | */
421 | public static getOdometer(success?:Function, failure?:Function) {
422 | if (!arguments.length) {
423 | return this.api.getOdometer();
424 | } else {
425 | this.api.getOdometer().then(success).catch(failure);
426 | }
427 | }
428 | /**
429 | * Set the value of the odometer
430 | */
431 | public static setOdometer(value:number, success?:Function, failure?:Function) {
432 | if (arguments.length == 1) {
433 | return this.api.setOdometer(value);
434 | } else {
435 | this.api.setOdometer(value).then(success).catch(failure);
436 | }
437 | }
438 | /**
439 | * Reset the value of odometer to 0
440 | */
441 | public static resetOdometer(success?:Function, failure?:Function) {
442 | if (!arguments.length) {
443 | return this.api.setOdometer(0);
444 | } else {
445 | this.api.setOdometer(0).then(success).catch(failure);
446 | }
447 | }
448 |
449 | /**
450 | * Geofencing Methods
451 | */
452 |
453 | /**
454 | * Add a single geofence
455 | */
456 | public static addGeofence(config:any, success?:Function, failure?:Function) {
457 | if (arguments.length == 1) {
458 | return this.api.addGeofence(config);
459 | } else {
460 | this.api.addGeofence(config).then(success).catch(failure);
461 | }
462 | }
463 | /**
464 | * Remove a single geofence by identifier
465 | */
466 | public static removeGeofence(identifier:string, success?:Function, failure?:Function) {
467 | if (arguments.length == 1) {
468 | return this.api.removeGeofence(identifier);
469 | } else {
470 | this.api.removeGeofence(identifier).then(success).catch(failure);
471 | }
472 | }
473 | /**
474 | * Add a list of geofences
475 | */
476 | public static addGeofences(geofences:any, success?:Function, failure?:Function) {
477 | if (arguments.length == 1) {
478 | return this.api.addGeofences(geofences);
479 | } else {
480 | this.api.addGeofences(geofences).then(success).catch(failure);
481 | }
482 | }
483 | /**
484 | * Remove geofences. You may either supply an array of identifiers or nothing to destroy all geofences.
485 | * 1. removeGeofences() <-- Promise
486 | * 2. removeGeofences(['foo']) <-- Promise
487 | *
488 | * 3. removeGeofences(success, [failure])
489 | * 4. removeGeofences(['foo'], success, [failure])
490 | */
491 | public static removeGeofences(success?:Function, failure?:Function) {
492 | if (!arguments.length) {
493 | return this.api.removeGeofences();
494 | } else {
495 | this.api.removeGeofences().then(success).catch(failure);
496 | }
497 | }
498 | /**
499 | * Fetch all geofences from database
500 | */
501 | public static getGeofences(success?:Function, failure?:Function) {
502 | if (!arguments.length) {
503 | return this.api.getGeofences();
504 | } else {
505 | this.api.getGeofences().then(success).catch(failure);
506 | }
507 | }
508 | /**
509 | * Fetch the current position from location-services
510 | */
511 | public static getCurrentPosition(success:any, failure?:any, options?:any) {
512 | if (typeof(success) == 'function') {
513 | if (typeof(failure) == 'object') {
514 | options = failure;
515 | failure = emptyFn;
516 | }
517 | options = options || {};
518 | this.api.getCurrentPosition(options).then(success).catch(failure);
519 | } else {
520 | options = success || {};
521 | return this.api.getCurrentPosition(options);
522 | }
523 | }
524 | /**
525 | * Begin watching a stream of locations
526 | */
527 | public static watchPosition(success:Function, failure?:Function, options?:any) {
528 | this.api.watchPosition(success, failure||emptyFn, options||{});
529 | }
530 | /**
531 | * Stop watching location
532 | */
533 | public static stopWatchPosition(success?:Function, failure?:Function) {
534 | if (!arguments.length) {
535 | return this.api.stopWatchPosition();
536 | } else {
537 | this.api.stopWatchPosition().then(success).catch(failure);
538 | }
539 | }
540 | /**
541 | * Set the logLevel. This is just a helper method for setConfig({logLevel: level})
542 | */
543 | public static setLogLevel(value:number, success?:Function, failure?:Function) {
544 | if (arguments.length == 1) {
545 | return this.api.setLogLevel(value);
546 | } else {
547 | this.api.setLogLevel(value).then(success).catch(failure);
548 | }
549 | }
550 | /**
551 | * Fetch the entire contents of log database returned as a String
552 | */
553 | public static getLog(success?:Function, failure?:Function) {
554 | if (!arguments.length) {
555 | return this.api.getLog();
556 | } else {
557 | this.api.getLog().then(success).catch(failure);
558 | }
559 | }
560 | /**
561 | * Destroy all contents of log database
562 | */
563 | public static destroyLog(success?:Function, failure?:Function) {
564 | if (!arguments.length) {
565 | return this.api.destroyLog();
566 | } else {
567 | this.api.destroyLog().then(success).catch(failure);
568 | }
569 | }
570 | /**
571 | * Open deafult email client on device to email the contents of log database attached as a compressed file attachement
572 | */
573 | public static emailLog(email:string, success?:Function, failure?:Function) {
574 | if (typeof(email) != 'string') { throw TAG + "#emailLog requires an email address as 1st argument"}
575 | if (arguments.length == 1) {
576 | return this.api.emailLog(email);
577 | } else {
578 | this.api.emailLog(email).then(success).catch(failure);
579 | }
580 | }
581 | /**
582 | * Has device OS initiated power-saving mode?
583 | */
584 | public static isPowerSaveMode(success?:Function, failure?:Function) {
585 | if (!arguments.length) {
586 | return this.api.isPowerSaveMode();
587 | } else {
588 | this.api.isPowerSaveMode().then(success).catch(failure);
589 | }
590 | }
591 | /**
592 | * Fetch the state of this device's available motion-sensors
593 | */
594 | public static getSensors(success?:Function, failure?:Function) {
595 | if (!arguments.length) {
596 | return this.api.getSensors();
597 | } else {
598 | this.api.getSensors().then(success).catch(failure);
599 | }
600 | }
601 | /**
602 | * Play a system sound via the plugin's Sound API
603 | */
604 | public static playSound(soundId:number, success?:Function, failure?:Function) {
605 | if (arguments.length == 1) {
606 | return this.api.playSound(soundId);
607 | } else {
608 | this.api.playSound(soundId).then(success).catch(failure);
609 | }
610 | }
611 |
612 | private static validate(config:any):any {
613 | if (config.username) {
614 | config.url = TEST_SERVER_URL + config.username;
615 | config.params = {
616 | device: {
617 | uuid: Platform.device.uuid,
618 | model: Platform.device.model,
619 | platform: Platform.device.os,
620 | manufacturer: Platform.device.manufacturer,
621 | version: Platform.device.osVersion,
622 | framework: '{N}'
623 | }
624 | }
625 | delete config.username;
626 | }
627 | return config;
628 | }
629 | }
630 |
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/app.gradle:
--------------------------------------------------------------------------------
1 | // Add your native dependencies here:
2 |
3 | // Uncomment to add recyclerview-v7 dependency
4 | //dependencies {
5 | // compile 'com.android.support:recyclerview-v7:+'
6 | //}
7 |
8 | android {
9 | defaultConfig {
10 | generatedDensities = []
11 | applicationId = "com.transistorsoft.backgroundgeolocation.nativescript"
12 | }
13 | aaptOptions {
14 | additionalParameters "--no-version-vectors"
15 | }
16 | }
17 |
18 | project.ext {
19 | supportVersion = "27.0.1"
20 | googlePlayServicesVersion = "11.8.0"
21 | }
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
27 |
28 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/src/main/res/drawable-hdpi/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/Android/src/main/res/drawable-hdpi/background.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/src/main/res/drawable-hdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/Android/src/main/res/drawable-hdpi/icon.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/src/main/res/drawable-hdpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/Android/src/main/res/drawable-hdpi/logo.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/src/main/res/drawable-ldpi/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/Android/src/main/res/drawable-ldpi/background.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/src/main/res/drawable-ldpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/Android/src/main/res/drawable-ldpi/icon.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/src/main/res/drawable-ldpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/Android/src/main/res/drawable-ldpi/logo.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/src/main/res/drawable-mdpi/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/Android/src/main/res/drawable-mdpi/background.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/src/main/res/drawable-mdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/Android/src/main/res/drawable-mdpi/icon.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/src/main/res/drawable-mdpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/Android/src/main/res/drawable-mdpi/logo.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/src/main/res/drawable-nodpi/splash_screen.xml:
--------------------------------------------------------------------------------
1 |
2 | -
3 |
4 |
5 | -
6 |
7 |
8 |
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/src/main/res/drawable-xhdpi/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/Android/src/main/res/drawable-xhdpi/background.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/src/main/res/drawable-xhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/Android/src/main/res/drawable-xhdpi/icon.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/src/main/res/drawable-xhdpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/Android/src/main/res/drawable-xhdpi/logo.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/src/main/res/drawable-xxhdpi/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/Android/src/main/res/drawable-xxhdpi/background.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/src/main/res/drawable-xxhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/Android/src/main/res/drawable-xxhdpi/icon.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/src/main/res/drawable-xxhdpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/Android/src/main/res/drawable-xxhdpi/logo.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/src/main/res/drawable-xxxhdpi/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/Android/src/main/res/drawable-xxxhdpi/background.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/src/main/res/drawable-xxxhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/Android/src/main/res/drawable-xxxhdpi/icon.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/src/main/res/drawable-xxxhdpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/Android/src/main/res/drawable-xxxhdpi/logo.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/src/main/res/values-v21/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3d5afe
4 |
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
11 |
14 |
15 |
16 |
19 |
20 |
23 |
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #F5F5F5
4 | #757575
5 | #33B5E5
6 | #272734
7 |
--------------------------------------------------------------------------------
/demo/app/App_Resources/Android/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
18 |
19 |
21 |
22 |
23 |
31 |
32 |
34 |
35 |
36 |
42 |
43 |
45 |
46 |
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "29x29",
5 | "idiom" : "iphone",
6 | "filename" : "icon-29.png",
7 | "scale" : "1x"
8 | },
9 | {
10 | "size" : "29x29",
11 | "idiom" : "iphone",
12 | "filename" : "icon-29@2x.png",
13 | "scale" : "2x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "icon-29@3x.png",
19 | "scale" : "3x"
20 | },
21 | {
22 | "size" : "40x40",
23 | "idiom" : "iphone",
24 | "filename" : "icon-40@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "40x40",
29 | "idiom" : "iphone",
30 | "filename" : "icon-40@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "60x60",
35 | "idiom" : "iphone",
36 | "filename" : "icon-60@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "60x60",
41 | "idiom" : "iphone",
42 | "filename" : "icon-60@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "29x29",
47 | "idiom" : "ipad",
48 | "filename" : "icon-29.png",
49 | "scale" : "1x"
50 | },
51 | {
52 | "size" : "29x29",
53 | "idiom" : "ipad",
54 | "filename" : "icon-29@2x.png",
55 | "scale" : "2x"
56 | },
57 | {
58 | "size" : "40x40",
59 | "idiom" : "ipad",
60 | "filename" : "icon-40.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "40x40",
65 | "idiom" : "ipad",
66 | "filename" : "icon-40@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "76x76",
71 | "idiom" : "ipad",
72 | "filename" : "icon-76.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "76x76",
77 | "idiom" : "ipad",
78 | "filename" : "icon-76@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "83.5x83.5",
83 | "idiom" : "ipad",
84 | "filename" : "icon-83.5@2x.png",
85 | "scale" : "2x"
86 | },
87 | {
88 | "size" : "1024x1024",
89 | "idiom" : "ios-marketing",
90 | "filename" : "icon-1024.png",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-1024.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "extent" : "full-screen",
5 | "idiom" : "iphone",
6 | "subtype" : "2436h",
7 | "filename" : "Default-1125h.png",
8 | "minimum-system-version" : "11.0",
9 | "orientation" : "portrait",
10 | "scale" : "3x"
11 | },
12 | {
13 | "orientation" : "landscape",
14 | "idiom" : "iphone",
15 | "extent" : "full-screen",
16 | "filename" : "Default-Landscape-X.png",
17 | "minimum-system-version" : "11.0",
18 | "subtype" : "2436h",
19 | "scale" : "3x"
20 | },
21 | {
22 | "extent" : "full-screen",
23 | "idiom" : "iphone",
24 | "subtype" : "736h",
25 | "filename" : "Default-736h@3x.png",
26 | "minimum-system-version" : "8.0",
27 | "orientation" : "portrait",
28 | "scale" : "3x"
29 | },
30 | {
31 | "extent" : "full-screen",
32 | "idiom" : "iphone",
33 | "subtype" : "736h",
34 | "filename" : "Default-Landscape@3x.png",
35 | "minimum-system-version" : "8.0",
36 | "orientation" : "landscape",
37 | "scale" : "3x"
38 | },
39 | {
40 | "extent" : "full-screen",
41 | "idiom" : "iphone",
42 | "subtype" : "667h",
43 | "filename" : "Default-667h@2x.png",
44 | "minimum-system-version" : "8.0",
45 | "orientation" : "portrait",
46 | "scale" : "2x"
47 | },
48 | {
49 | "orientation" : "portrait",
50 | "idiom" : "iphone",
51 | "filename" : "Default@2x.png",
52 | "extent" : "full-screen",
53 | "minimum-system-version" : "7.0",
54 | "scale" : "2x"
55 | },
56 | {
57 | "extent" : "full-screen",
58 | "idiom" : "iphone",
59 | "subtype" : "retina4",
60 | "filename" : "Default-568h@2x.png",
61 | "minimum-system-version" : "7.0",
62 | "orientation" : "portrait",
63 | "scale" : "2x"
64 | },
65 | {
66 | "orientation" : "portrait",
67 | "idiom" : "ipad",
68 | "filename" : "Default-Portrait.png",
69 | "extent" : "full-screen",
70 | "minimum-system-version" : "7.0",
71 | "scale" : "1x"
72 | },
73 | {
74 | "orientation" : "landscape",
75 | "idiom" : "ipad",
76 | "filename" : "Default-Landscape.png",
77 | "extent" : "full-screen",
78 | "minimum-system-version" : "7.0",
79 | "scale" : "1x"
80 | },
81 | {
82 | "orientation" : "portrait",
83 | "idiom" : "ipad",
84 | "filename" : "Default-Portrait@2x.png",
85 | "extent" : "full-screen",
86 | "minimum-system-version" : "7.0",
87 | "scale" : "2x"
88 | },
89 | {
90 | "orientation" : "landscape",
91 | "idiom" : "ipad",
92 | "filename" : "Default-Landscape@2x.png",
93 | "extent" : "full-screen",
94 | "minimum-system-version" : "7.0",
95 | "scale" : "2x"
96 | },
97 | {
98 | "orientation" : "portrait",
99 | "idiom" : "iphone",
100 | "filename" : "Default.png",
101 | "extent" : "full-screen",
102 | "scale" : "1x"
103 | },
104 | {
105 | "orientation" : "portrait",
106 | "idiom" : "iphone",
107 | "filename" : "Default@2x.png",
108 | "extent" : "full-screen",
109 | "scale" : "2x"
110 | },
111 | {
112 | "orientation" : "portrait",
113 | "idiom" : "iphone",
114 | "filename" : "Default-568h@2x.png",
115 | "extent" : "full-screen",
116 | "subtype" : "retina4",
117 | "scale" : "2x"
118 | },
119 | {
120 | "orientation" : "portrait",
121 | "idiom" : "ipad",
122 | "extent" : "to-status-bar",
123 | "scale" : "1x"
124 | },
125 | {
126 | "orientation" : "portrait",
127 | "idiom" : "ipad",
128 | "filename" : "Default-Portrait.png",
129 | "extent" : "full-screen",
130 | "scale" : "1x"
131 | },
132 | {
133 | "orientation" : "landscape",
134 | "idiom" : "ipad",
135 | "extent" : "to-status-bar",
136 | "scale" : "1x"
137 | },
138 | {
139 | "orientation" : "landscape",
140 | "idiom" : "ipad",
141 | "filename" : "Default-Landscape.png",
142 | "extent" : "full-screen",
143 | "scale" : "1x"
144 | },
145 | {
146 | "orientation" : "portrait",
147 | "idiom" : "ipad",
148 | "extent" : "to-status-bar",
149 | "scale" : "2x"
150 | },
151 | {
152 | "orientation" : "portrait",
153 | "idiom" : "ipad",
154 | "filename" : "Default-Portrait@2x.png",
155 | "extent" : "full-screen",
156 | "scale" : "2x"
157 | },
158 | {
159 | "orientation" : "landscape",
160 | "idiom" : "ipad",
161 | "extent" : "to-status-bar",
162 | "scale" : "2x"
163 | },
164 | {
165 | "orientation" : "landscape",
166 | "idiom" : "ipad",
167 | "filename" : "Default-Landscape@2x.png",
168 | "extent" : "full-screen",
169 | "scale" : "2x"
170 | }
171 | ],
172 | "info" : {
173 | "version" : 1,
174 | "author" : "xcode"
175 | }
176 | }
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-1125h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-1125h.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-568h@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-667h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-667h@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-736h@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-736h@3x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape-X.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape-X.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape@3x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Portrait.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Portrait.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Portrait@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Portrait@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchScreen-AspectFill.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchScreen-AspectFill@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchScreen-Center.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchScreen-Center@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center@2x.png
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIRequiresFullScreen
28 |
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 | NSAppTransportSecurity
47 |
48 | NSAllowsArbitraryLoads
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/demo/app/App_Resources/iOS/build.xcconfig:
--------------------------------------------------------------------------------
1 | // You can add custom settings here
2 | // for example you can uncomment the following line to force distribution code signing
3 | // CODE_SIGN_IDENTITY = iPhone Distribution
4 | // To build for device with XCode 8 you need to specify your development team. More info: https://developer.apple.com/library/prerelease/content/releasenotes/DeveloperTools/RN-Xcode/Introduction.html
5 | // DEVELOPMENT_TEAM = YOUR_TEAM_ID;
6 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
7 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
8 |
9 | DEVELOPMENT_TEAM = 32A636YFGZ
10 |
--------------------------------------------------------------------------------
/demo/app/README.md:
--------------------------------------------------------------------------------
1 | # NativeScript TypeScript Template
2 |
3 | This template creates a NativeScript app with the NativeScript hello world example,
4 | however, in this template the example is built with TypeScript.
5 |
6 | You can create a new app that uses this template with either the `--template` option.
7 |
8 | ```
9 | tns create my-app-name --template tns-template-hello-world-ts
10 | ```
11 |
12 | Or the `--tsc` shorthand.
13 |
14 | ```
15 | tns create my-app-name --tsc
16 | ```
17 |
18 | > Note: Both commands will create a new NativeScript app that uses the latest version of this template published to [npm] (https://www.npmjs.com/package/tns-template-hello-world-ts).
19 |
20 | If you want to create a new app that uses the source of the template from the `master` branch, you can execute the following:
21 |
22 | ```
23 | tns create my-app-name --template https://github.com/NativeScript/template-hello-world-ts.git#master
24 | ```
25 |
--------------------------------------------------------------------------------
/demo/app/app-root.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/demo/app/app.css:
--------------------------------------------------------------------------------
1 | /*
2 | In NativeScript, the app.css file is where you place CSS rules that
3 | you would like to apply to your entire application. Check out
4 | http://docs.nativescript.org/ui/styling for a full list of the CSS
5 | selectors and properties you can use to style UI components.
6 |
7 | /*
8 | In many cases you may want to use the NativeScript core theme instead
9 | of writing your own CSS rules. For a full list of class names in the theme
10 | refer to http://docs.nativescript.org/ui/theme.
11 | The imported CSS rules must precede all other types of rules.
12 | */
13 | @import '~nativescript-theme-core/css/core.light.css';
14 |
15 | /*
16 | The following CSS rule changes the font size of all UI
17 | components that have the btn class name.
18 | */
19 | .btn {
20 | font-size: 18;
21 | }
22 |
23 |
24 | .ion {
25 | font-family: Ionicons, ionicons;
26 | }
27 |
28 | label.location {
29 | font-family: monospace;
30 | font-size: 12;
31 | }
32 |
33 | button.ion-play {
34 | color: white;
35 | background-color: green;
36 | }
37 | button.ion-pause {
38 | color: white;
39 | background-color: red;
40 | }
41 |
42 | .transistor-toolbar {
43 | background-color: #fedd1e;
44 | }
45 |
--------------------------------------------------------------------------------
/demo/app/app.ts:
--------------------------------------------------------------------------------
1 | /*
2 | In NativeScript, the app.ts file is the entry point to your application.
3 | You can use this file to perform app-level initialization, but the primary
4 | purpose of the file is to pass control to the app’s first module.
5 | */
6 |
7 | import "./bundle-config";
8 | import * as application from 'application';
9 |
10 | import {BackgroundFetch} from "nativescript-background-fetch";
11 | import {BackgroundGeolocation} from "nativescript-background-geolocation-lt";
12 |
13 | // fonticon setup
14 | import {TNSFontIcon, fonticon} from 'nativescript-fonticon';
15 | TNSFontIcon.debug = false;
16 | TNSFontIcon.paths = {
17 | 'ion': 'css/ionicons.min.css'
18 | };
19 | TNSFontIcon.loadCss();
20 |
21 | let resources = application.getResources();
22 | resources['fonticon'] = fonticon;
23 | application.setResources(resources);
24 |
25 |
26 | // iOS BackgroundFetch Setup
27 | if (application.ios) {
28 | class MyDelegate extends UIResponder implements UIApplicationDelegate {
29 | public static ObjCProtocols = [UIApplicationDelegate];
30 |
31 | public applicationPerformFetchWithCompletionHandler(application: UIApplication, completionHandler:any) {
32 | BackgroundFetch.performFetchWithCompletionHandler(completionHandler, application.applicationState);
33 | }
34 | }
35 | application.ios.delegate = MyDelegate;
36 | }
37 |
38 | application.run({ moduleName: 'app-root' });
39 |
40 |
41 | // Android HeadlessTask Setup
42 | if (application.android) {
43 | // BackgroundGeolocation Headless Setup
44 | BackgroundGeolocation.registerHeadlessTask((event, completionHandler) => {
45 | console.log('[My Headless BackgroundGeolocation Task: ', event.name, event.params);
46 | // Do stuff.
47 | completionHandler(); // <-- signal completion of your HeadlessTask
48 | });
49 |
50 | // BackgroundFetch Headless Setup
51 | BackgroundFetch.registerHeadlessTask(() => {
52 | console.log('[My Headless BackgroundFetch Task]');
53 | BackgroundFetch.finish();
54 | });
55 | }
56 | /*
57 | Do not place any code after the application has been started as it will not
58 | be executed on iOS.
59 | */
60 |
--------------------------------------------------------------------------------
/demo/app/bundle-config.ts:
--------------------------------------------------------------------------------
1 | if ((global).TNS_WEBPACK) {
2 | // Register tns-core-modules UI framework modules
3 | require("bundle-entry-points");
4 |
5 | // Register application modules
6 | // This will register each `root`, `page`, `fragment` postfixed xml, css, js, ts, scss file in the app/ folder
7 | const context = (require).context("~/", true, /(root|page|fragment)\.(xml|css|js|ts|scss|less|sass)$/);
8 | global.registerWebpackModules(context);
9 | }
10 |
--------------------------------------------------------------------------------
/demo/app/fonts/ionicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/transistorsoft/nativescript-background-geolocation-lt/ef747a31d6e168045dfed161929cd8cc0df3eca4/demo/app/fonts/ionicons.ttf
--------------------------------------------------------------------------------
/demo/app/main-page.ts:
--------------------------------------------------------------------------------
1 | /*
2 | In NativeScript, a file with the same name as an XML file is known as
3 | a code-behind file. The code-behind is a great place to place your view
4 | logic, and to set up your page’s data binding.
5 | */
6 |
7 | import { EventData } from 'data/observable';
8 | import { Page } from 'ui/page';
9 | import { HelloWorldModel } from './main-view-model';
10 |
11 | // Event handler for Page "navigatingTo" event attached in main-page.xml
12 | export function navigatingTo(args: EventData) {
13 | /*
14 | This gets a reference this page’s UI component. You can
15 | view the API reference of the Page to see what’s available at
16 | https://docs.nativescript.org/api-reference/classes/_ui_page_.page.html
17 | */
18 | let page = args.object;
19 |
20 | /*
21 | A page’s bindingContext is an object that should be used to perform
22 | data binding between XML markup and TypeScript code. Properties
23 | on the bindingContext can be accessed using the {{ }} syntax in XML.
24 | In this example, the {{ message }} and {{ onTap }} bindings are resolved
25 | against the object returned by createViewModel().
26 |
27 | You can learn more about data binding in NativeScript at
28 | https://docs.nativescript.org/core-concepts/data-binding.
29 | */
30 | page.bindingContext = new HelloWorldModel();
31 | }
--------------------------------------------------------------------------------
/demo/app/main-page.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/demo/app/main-view-model.ts:
--------------------------------------------------------------------------------
1 | import { Observable } from 'data/observable';
2 | import Platform = require('platform');
3 |
4 | import {BackgroundGeolocation} from "nativescript-background-geolocation-lt";
5 |
6 | const ICONS = {
7 | play: 'ion-play',
8 | pause: 'ion-pause',
9 | activity_unknown: 'ion-ios-help',
10 | activity_still: 'ion-man',
11 | activity_on_foot: 'ion-android-walk',
12 | activity_walking: 'ion-android-walk',
13 | activity_running: 'ion-android-walk',
14 | activity_in_vehicle: 'ion-android-car',
15 | activity_on_bicycle: 'ion-android-bicycle'
16 | };
17 |
18 | export class HelloWorldModel extends Observable {
19 |
20 | private _location: string;
21 | private _counter: number;
22 | private _message: string;
23 | private _isMoving: boolean;
24 | private _enabled: boolean;
25 | private _paceButtonIcon: string;
26 |
27 | constructor() {
28 | super();
29 |
30 | // First listen to desired events:
31 | BackgroundGeolocation.on("location", (location) => {
32 | console.log('[event] location: ', location);
33 | this.location = JSON.stringify(location, null, 2);
34 | });
35 | BackgroundGeolocation.on("motionchange", (isMoving:boolean, location:any) => {
36 | console.log('[motionchange] -', isMoving, location);
37 | });
38 | BackgroundGeolocation.on('http', (response) => {
39 | console.log('[http] -', response.status, response.responseText);
40 | });
41 | BackgroundGeolocation.on('providerchange', (provider) => {
42 | console.log('[providerchange] -', provider);
43 | });
44 | BackgroundGeolocation.on('powersavechange', (isPowerSaveMode) => {
45 | console.log('[powersavechange] -', isPowerSaveMode);
46 | });
47 | BackgroundGeolocation.on('schedule', (state) => {
48 | console.log('[schedule] -', state.enabled);
49 | });
50 | BackgroundGeolocation.on('activitychange', (event) => {
51 | console.log('[eveactivitychangent] -', event.activity, event.confidence);
52 | });
53 | BackgroundGeolocation.on('heartbeat', (event) => {
54 | console.log('[heartbeat] -', event);
55 | });
56 | BackgroundGeolocation.on('geofence', (geofence) => {
57 | console.log('[geofence] -', geofence);
58 | });
59 | BackgroundGeolocation.on('geofenceschange', (event) => {
60 | console.log('[geofenceschange] - ON:', JSON.stringify(event.on), ', OFF:', JSON.stringify(event.off));
61 | });
62 | BackgroundGeolocation.on('connectivitychange', (event) => {
63 | console.log('[connectivitychange] -', event);
64 | });
65 | BackgroundGeolocation.on('enabledchange', (event) => {
66 | console.log('[enabledchange] - ', event);
67 | });
68 | BackgroundGeolocation.getSensors((sensors) => {
69 | console.log('[getSensors] -', JSON.stringify(sensors, null, 2));
70 | });
71 | BackgroundGeolocation.isPowerSaveMode((mode) => {
72 | console.log('[isPowerSaveMode] -', mode);
73 | });
74 |
75 | // Now configure the plugin.
76 | BackgroundGeolocation.ready({
77 | reset: true,
78 | debug: true,
79 | logLevel: BackgroundGeolocation.LOG_LEVEL_VERBOSE,
80 | desiredAccuracy: BackgroundGeolocation.DESIRED_ACCURACY_HIGH,
81 | distanceFilter: 50,
82 | stopTimeout: 1,
83 | autoSync: true,
84 | stopOnTerminate: false,
85 | startOnBoot: true,
86 | foregroundService: true,
87 | heartbeatInterval: 60,
88 | username: 'transistor-ns',
89 | enableHeadless: true
90 | }, (state) => {
91 | console.log('[ready] success -', state);
92 | this.paceButtonIcon = (state.isMoving) ? ICONS.pause : ICONS.play;
93 | this.enabled = state.enabled;
94 | }, (error:string) => {
95 | console.warn('[ready] FAILURE -', error);
96 | });
97 | }
98 |
99 | set enabled(value:boolean) {
100 | console.log('- setEnabled: ', value);
101 | this.notifyPropertyChange('enabled', value);
102 | this._enabled = value;
103 | if (value) {
104 | BackgroundGeolocation.start();
105 | } else {
106 | BackgroundGeolocation.stop();
107 | }
108 | }
109 |
110 | get enabled():boolean {
111 | return this._enabled;
112 | }
113 |
114 | get paceButtonIcon(): string {
115 | return this._paceButtonIcon;
116 | }
117 |
118 | set paceButtonIcon(value:string) {
119 | if (this._paceButtonIcon !== value) {
120 | this._paceButtonIcon = value;
121 | this.notifyPropertyChange("paceButtonIcon", value);
122 | }
123 | }
124 |
125 | set location(location:string) {
126 | this._location = location;
127 | this.notifyPropertyChange('location', this._location);
128 | }
129 |
130 | get location():string {
131 | return this._location;
132 | }
133 |
134 | public onChangePace() {
135 | console.log('[changePace] -', this._isMoving);
136 | this._isMoving = !this._isMoving;
137 | this.paceButtonIcon = (this._isMoving) ? ICONS.pause : ICONS.play;
138 | BackgroundGeolocation.changePace(this._isMoving);
139 | }
140 |
141 | public onGetCurrentPosition() {
142 | BackgroundGeolocation.getCurrentPosition({
143 | samples: 3,
144 | persist: true
145 | }).then((location) => {
146 | console.log('[getCurrentPosition] -', location);
147 | }).catch((error) => {
148 | console.warn('[getCurrentPosition] ERROR -', error);
149 | });
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/demo/app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "android": {
3 | "v8Flags": "--expose_gc"
4 | },
5 | "main": "app.js",
6 | "name": "tns-template-hello-world-ts",
7 | "version": "4.1.0"
8 | }
--------------------------------------------------------------------------------
/demo/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "description": "NativeScript Application",
3 | "license": "SEE LICENSE IN ",
4 | "readme": "NativeScript Application",
5 | "repository": "",
6 | "nativescript": {
7 | "id": "com.transistorsoft.backgroundgeolocation.nativescript",
8 | "tns-ios": {
9 | "version": "4.1.1"
10 | },
11 | "tns-android": {
12 | "version": "4.1.3"
13 | }
14 | },
15 | "dependencies": {
16 | "nativescript-background-fetch": "^1.2.0",
17 | "nativescript-background-geolocation-lt": "file:../src",
18 | "nativescript-fonticon": "^1.1.1",
19 | "nativescript-theme-core": "~1.0.4",
20 | "tns-core-modules": "~4.1.0"
21 | },
22 | "devDependencies": {
23 | "babel-traverse": "6.26.0",
24 | "babel-types": "6.26.0",
25 | "babylon": "6.18.0",
26 | "lazy": "1.0.11",
27 | "nativescript-dev-typescript": "~0.7.0",
28 | "tns-platform-declarations": "^4.1.0",
29 | "typescript": "~2.7.2"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/demo/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "target": "es5",
5 | "experimentalDecorators": true,
6 | "emitDecoratorMetadata": true,
7 | "noEmitHelpers": true,
8 | "noEmitOnError": true,
9 | "lib": [
10 | "es6",
11 | "dom"
12 | ],
13 | "baseUrl": ".",
14 | "paths": {
15 | "~/*": [
16 | "app/*"
17 | ],
18 | "*": [
19 | "./node_modules/tns-core-modules/*",
20 | "./node_modules/*"
21 | ]
22 | }
23 | },
24 | "exclude": [
25 | "node_modules",
26 | "platforms"
27 | ]
28 | }
--------------------------------------------------------------------------------
/docs/geofencing.md:
--------------------------------------------------------------------------------
1 | # Infinite Geofencing
2 |
3 | The Background Geolocation contains powerful geofencing features that allow you to monitor any number of circular geofences you wish (thousands even), in spite of limits imposed by the native platform APIs (**20 for iOS; 100 for Android**).
4 |
5 | The plugin achieves this by storing your geofences in its database, using a [geospatial query](https://en.wikipedia.org/wiki/Spatial_query) to determine those geofences in proximity (@see config [geofenceProximityRadius](./README.md/#param-integer-geofenceproximityradius-meters)), activating only those geofences closest to the device's current location (according to limit imposed by the corresponding platform).
6 |
7 | 
8 |
9 | When the device is determined to be moving, the plugin periodically queries for geofences in proximity (eg. every minute) using the latest recorded location. This geospatial query is **very fast**, even with tens-of-thousands geofences in the database.
10 |
11 | ## Event: `geofenceschange`
12 |
13 | When a proximity-query detects a change in the list of monitored geofences, it will fire the `geofenceschanged` event, providing information about which geofences were activiated as well as those which were de-activiated.
14 |
15 | The parameter provided to your event-handler takes the following form:
16 | ####@param {Array} on The list of geofences just activated.
17 | ####@param {Array off The list of geofences just de-activated
18 |
19 | ```Javascript
20 | bgGeo.on('geofenceschange', function(event) {
21 | var on = event.on; //<-- new geofences activiated.
22 | var off = event.off; //<-- geofences that were de-activated.
23 |
24 | // Create map circles
25 | for (var n=0,len=on.length;n geofenceschange fired! {on: [], off: []}
57 |
58 | ```
59 |
60 | ## Config: [`geofenceProximityRadius`](./README.md/#param-integer-geofenceproximityradius-meters)
61 |
62 | [`@config geofenceProximityRadius {Integer} [1000] meters`](./README.md/#param-integer-geofenceproximityradius-meters) controls the circular area around the device's current position where geofences will be activated. As the device moves, the plugin periodically queries for geofences in proximity of the last-recorded location (default once-per-minute).
63 |
64 | You can change the [`geofenceProximityRadius`](./README.md/#param-integer-geofenceproximityradius-meters) at run-time; the `geofenceschange` event will immediately fire if the monitored list-of-geofences changed as a result:
65 |
66 | ```Javascript
67 | bgGeo.on('geofenceschange', function(event) {
68 | console.log('geofenceschange fired! ', event);
69 | });
70 |
71 | bgGeo.setConfig({geofenceProximityRadius: 1000});
72 | => geofenceschange fired! {on: [{}, {}, ...], off: []}
73 |
74 | bgGeo.setConfig({geofenceProximityRadius: 0});
75 | => geofenceschange fired! {on: [], off: ['foo', 'bar', ...]}
76 |
77 | bgGeo.setConfig({geofenceProximityRadius: 0});
78 | => geofenceschange fired! {}
79 | ```
80 |
81 | ## Adding large lists of geofences
82 |
83 | The plugin is perfectly capable of monitoring **large** lists of geofences (tested with tens-of-thousands). However, when adding geofences, it's over **10* faster** to use the method `addGeofences`(plural) rather than looping and executing `#addGeofence`
84 |
85 | ```Javascript
86 | var geofences = [...]; // <-- list of thousands-of-geofences
87 |
88 | // 1. slow
89 | for (var n=0,len-geofences.length;n
101 | ```
102 |
103 | Example:
104 |
105 | ```javascript
106 | bgGeo.configure({
107 | url: 'http://my_url',
108 | httpRootProperty: 'data',
109 | params: {
110 | myParams: {foo: 'bar'}
111 | },
112 | locationTemplate: '{ "lat":<%= latitude %>, "lng":<%= longitude %> }',
113 | extras: {
114 | "location_extra_foo": "extra location data"
115 | }
116 | })
117 | ```
118 |
119 | ```javascript
120 | POST /my_url
121 | {
122 | "data": {
123 | "lat": 45.5192657,
124 | "lng": -73.6169116,
125 | "location_extra_foo": "extra location data"
126 | },
127 | "myParams": {
128 | "foo": "bar"
129 | }
130 | }
131 | ```
132 |
133 | ### Template Tags
134 |
135 | #### Common Tags
136 |
137 | The following template tags are common to both **`locationTemplate`** and **`geofenceTemplate`**:
138 |
139 | | Tag | Type | Description |
140 | |-----|------|-------------|
141 | | `latitude` | `Float` ||
142 | | `longitude` | `Float` ||
143 | | `speed` | `Float` | Meters|
144 | | `heading` | `Float` | Degress|
145 | | `accuracy` | `Float` | Meters|
146 | | `altitude` | `Float` | Meters|
147 | | `altitude_accuracy` | `Float` | Meters|
148 | | `timestamp` | `String` |ISO-8601|
149 | | `uuid` | `String` |Unique ID|
150 | | `event` | `String` |`motionchange|geofence|heartbeat`
151 | | `odometer` | `Float` | Meters|
152 | | `activity.type` | `String` | `still|on_foot|running|on_bicycle|in_vehicle|unknown`|
153 | | `activity.confidence` | `Integer` | 0-100%|
154 | | `battery.level` | `Float` | 0-100%|
155 | | `battery.is_charging` | `Boolean` | Is device plugged in?|
156 |
157 | #### Geofence Tags
158 |
159 | The following template tags are specific to **`geofenceTemplate`** only:
160 |
161 | | Tag | Type | Description |
162 | |-----|------|-------------|
163 | | `geofence.identifier` | `String` | Which geofence?|
164 | | `geofence.action` | `String` | `ENTER|EXIT`|
165 |
166 | #### Quoting String Values
167 |
168 | You're completely responsible for `"quoting"` your own `String` values. The following will generate a JSON parsing error:
169 |
170 | ```javascript
171 | bgGeo.configure({
172 | locationTemplate: '{ "event":<%= event %> }',
173 | });
174 | ```
175 |
176 | In the logs, you'll find:
177 | ```
178 | ‼️-[TSLocation templateError:template:] locationTemplate error: Invalid value around character 10.
179 | { "event":<%= event %> }
180 | ```
181 |
182 | To fix this, the `String` tag `<%= event %>` must be wrapped in `""`:
183 |
184 | ```javascript
185 | bgGeo.configure({
186 | locationTemplate: '{ "event":"<%= event %>" }',
187 | });
188 | ```
189 |
190 | #### Boolean, Float and Integer Values
191 |
192 | `Boolean`, `Float` and `Integer` values do **not** require quoting:
193 |
194 | ```
195 | bgGeo.configure({
196 | locationTemplate: '{ "is_moving":<%= is_moving %>, "odometer":<%= odometer %> }',
197 | });
198 | ```
199 |
200 | #### Array Templates
201 |
202 | You're not forced to define your templates as an **`{Object}`** — You can define them as an **`[Array]`** too.
203 |
204 | ```javascript
205 | bgGeo.configure({
206 | url: 'http://my_url',
207 | httpRootProperty: 'data',
208 | params: {
209 | myParams: {foo: 'bar'}
210 | },
211 | locationTemplate: '[ <%= latitude %>, <%= longitude %> ]',
212 | extras: {
213 | "location_extra_foo": "extra location data"
214 | }
215 | })
216 | ```
217 |
218 | ```javascript
219 | POST /my_url
220 | {
221 | "data": [
222 | 45.5192657,
223 | -73.6169116,
224 | {"location_extra_foo": "extra location data"} // <-- appended #extras
225 | ],
226 | "myParams": {
227 | "foo": "bar"
228 | }
229 | }
230 | ```
231 |
232 | :exclamation: `#extras` are automatically appened to the last element of the array as an `{Object}`.
233 |
234 | #### Array Template with `httpRootProperty: "."`
235 |
236 | :warning: This case is tricky and should probably be avoided, particularly if you have configured `#params`, since there no place in the request JSON to append them.
237 |
238 | ```javascript
239 | bgGeo.configure({
240 | url: 'http://my_url',
241 | httpRootProperty: '.',
242 | params: {
243 | myParams: {foo: 'bar'}
244 | },
245 | locationTemplate: '[<%=latitude%>, <%=longitude%>]',
246 | extras: {
247 | "location_extra_foo": "extra location data"
248 | }
249 | })
250 | ```
251 |
252 | ```javascript
253 | - POST /my_url
254 | [ // <-- #params are lost. There's no place in the data-structure to append them.
255 | 45.5192657,
256 | -73.6169116,
257 | {
258 | "location_extra_foo": "extra location data"
259 | }
260 | ]
261 | ```
262 |
263 |
264 |
--------------------------------------------------------------------------------
/src/.npmignore:
--------------------------------------------------------------------------------
1 | demo/
2 | *.png
3 | *.log
4 | *.ts
5 | !*.d.ts
6 |
--------------------------------------------------------------------------------
/src/HeadlessBroadcastReceiver.android.d.ts:
--------------------------------------------------------------------------------
1 | export {};
2 |
--------------------------------------------------------------------------------
/src/HeadlessBroadcastReceiver.android.ts:
--------------------------------------------------------------------------------
1 | import {BackgroundGeolocation} from "./background-geolocation";
2 |
3 | @JavaProxy("com.transistorsoft.backgroundgeolocation.HeadlessBroadcastReceiver")
4 | class HeadlessBroadcastReceiver extends android.content.BroadcastReceiver {
5 | public onReceive(context:android.content.Context, intent:android.content.Intent) {
6 | let extras = intent.getExtras();
7 | let event = extras.getString("event");
8 | let params = JSON.parse(extras.getString("params"));
9 |
10 | BackgroundGeolocation.invokeHeadlessTask({name: event, params: params}, () => {
11 | // Do nothing for BroadcastReceiver. This is only for JobService
12 | });
13 | }
14 | }
--------------------------------------------------------------------------------
/src/HeadlessJobService.android.d.ts:
--------------------------------------------------------------------------------
1 | export {};
2 |
--------------------------------------------------------------------------------
/src/HeadlessJobService.android.ts:
--------------------------------------------------------------------------------
1 | import {BackgroundGeolocation} from "./background-geolocation";
2 |
3 | @JavaProxy("com.transistorsoft.backgroundgeolocation.HeadlessJobService")
4 | class HeadlessJobService extends android.app.job.JobService {
5 | public onStartJob(params:android.app.job.JobParameters):boolean {
6 | console.log('[BackgroundGeolocationHeadlessJobService] - onStartJob');
7 | let extras = params.getExtras();
8 | let event = extras.getString('event');
9 | let data = JSON.parse(extras.getString('params'));
10 |
11 | BackgroundGeolocation.invokeHeadlessTask({name: event, params: data}, () => {
12 | this.jobFinished(params, false);
13 | });
14 |
15 | return true;
16 | }
17 | public onStopJob(params:android.app.job.JobParameters):boolean {
18 | this.jobFinished(params, false);
19 | return true;
20 | }
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/src/api.android.d.ts:
--------------------------------------------------------------------------------
1 | import 'nativescript-tslib';
2 | import { BackgroundGeolocation } from "./background-geolocation";
3 | import "./HeadlessJobService";
4 | import "./HeadlessBroadcastReceiver";
5 | export { BackgroundGeolocation };
6 |
--------------------------------------------------------------------------------
/src/api.ios.d.ts:
--------------------------------------------------------------------------------
1 | import { BackgroundGeolocation } from "./background-geolocation";
2 | export { BackgroundGeolocation };
3 |
--------------------------------------------------------------------------------
/src/api.ios.ts:
--------------------------------------------------------------------------------
1 |
2 | import {BackgroundGeolocation} from "./background-geolocation";
3 |
4 | import * as utils from "utils/utils";
5 |
6 | declare var TSLocationManager: any;
7 | declare var TSConfig: any;
8 | declare var NSString: any;
9 | declare var NSDictionary: any;
10 | declare var NSArray: any;
11 | declare var NSUTF8StringEncoding: any;
12 | declare var CLCircularRegion: any;
13 | declare var UIApplication: any;
14 | declare var CLAuthorizationStatus: any;
15 | declare var TSCurrentPositionRequest: any;
16 | declare var TSWatchPositionRequest: any;
17 | declare var TSGeofence: any;
18 |
19 | let TS_LOCATION_TYPE_MOTIONCHANGE = 0;
20 | let TS_LOCATION_TYPE_CURRENT = 1;
21 | let TS_LOCATION_TYPE_SAMPLE = 2;
22 |
23 | let emptyFn = () => {};
24 |
25 | class Api {
26 |
27 | private static adapter:any;
28 |
29 | /**
30 | * Configuration Methods
31 | */
32 | public static addListener(event:any, success:Function, failure?:Function) {
33 | let callback;
34 | failure = failure || emptyFn;
35 | switch (event) {
36 | case 'location':
37 | callback = (tsLocation:any) => {
38 | let location = this.getJsObjectFromNSDictionary(tsLocation.toDictionary());
39 | success(location);
40 | };
41 | this.getAdapter().onLocationFailure(callback, failure);
42 | break;
43 | case 'motionchange':
44 | callback = (tsLocation:any) => {
45 | let location = this.getJsObjectFromNSDictionary(tsLocation.toDictionary());
46 | let isMoving = tsLocation.isMoving;
47 | success(isMoving, location);
48 | };
49 | this.getAdapter().onMotionChange(callback);
50 | break;
51 | case 'activitychange':
52 | callback = (event:any) => {
53 | let params = {activity: event.activity, confidence: event.confidence};
54 | success(params);
55 | }
56 | this.getAdapter().onActivityChange(callback);
57 | break;
58 | case 'heartbeat':
59 | callback = (event:any) => {
60 | let location = this.getJsObjectFromNSDictionary(event.location.toDictionary());
61 | let params = {location: location};
62 | success(params);
63 | };
64 | this.getAdapter().onHeartbeat(callback);
65 | break;
66 | case 'geofence':
67 | callback = (event:any) => {
68 | let params = event.toDictionary().mutableCopy();
69 | params.setObjectForKey(event.location.toDictionary(), "location");
70 | success(this.getJsObjectFromNSDictionary(params));
71 | };
72 | this.getAdapter().onGeofence(callback);
73 | break;
74 | case 'geofenceschange':
75 | callback = (event:any) => {
76 | let params = this.getJsObjectFromNSDictionary(event.toDictionary());
77 | success(params);
78 | };
79 | this.getAdapter().onGeofencesChange(callback);
80 | break;
81 | case 'http':
82 | callback = (event:any) => {
83 | let params = {
84 | "success": event.isSuccess,
85 | "status": event.statusCode,
86 | "responseText": event.responseText
87 | };
88 | if (event.isSuccess) {
89 | success(params);
90 | } else {
91 | failure(params);
92 | }
93 | };
94 | this.getAdapter().onHttp(callback);
95 | break;
96 | case 'providerchange':
97 | callback = (event:any) => {
98 | let params = this.getJsObjectFromNSDictionary(event.toDictionary());
99 | success(params);
100 | };
101 | this.getAdapter().onProviderChange(callback);
102 | break;
103 | case 'schedule':
104 | callback = (event:any) => {
105 | let state = this.getJsObjectFromNSDictionary(event.state);
106 | success(state);
107 | };
108 | this.getAdapter().onSchedule(callback);
109 | break;
110 | case 'powersavechange':
111 | callback = (event:any) => {
112 | success(event.isPowerSaveMode);
113 | };
114 | this.getAdapter().onPowerSaveChange(callback);
115 | break;
116 | case 'enabledchange':
117 | callback = (event:any) => {
118 | let params = {
119 | enabled: event.enabled
120 | };
121 | success(params);
122 | };
123 | this.getAdapter().onEnabledChange(callback);
124 | break;
125 | case 'connectivitychange':
126 | callback = (event:any) => {
127 | let params = {
128 | connected: event.hasConnection
129 | };
130 | success(params);
131 | }
132 | this.getAdapter().onConnectivityChange(callback);
133 | break;
134 | }
135 | return callback;
136 | }
137 |
138 | public static removeListener(event:string, callback:Function) {
139 | return new Promise((resolve, reject) => {
140 | this.getAdapter().removeListenerCallback(event, callback);
141 | // It's not possible to remove single event-listener with NativeScript since the native block is wrapped in a Javascript function
142 | reject("BackgroundGeolocation#removeListener - Unfortunately it's not possible to remove a single event-listener with NativeScript. You can only remove ALL listeners for a particular event, eg: removeListeners('location')");
143 | });
144 | }
145 |
146 | public static removeListeners(event?:string) {
147 | return new Promise((resolve, reject) => {
148 | if (event) {
149 | this.getAdapter().removeListenersForEvent(event);
150 | } else {
151 | this.getAdapter().removeListeners();
152 | }
153 | resolve();
154 | });
155 | }
156 |
157 | public static ready(params:any) {
158 | return new Promise((resolve, reject) => {
159 | let config = TSConfig.sharedInstance();
160 | if (config.isFirstBoot) {
161 | config.updateWithDictionary(params);
162 | } else if (params.reset === true) {
163 | config.reset();
164 | config.updateWithDictionary(params);
165 | }
166 | let locationManager = this.getAdapter();
167 | locationManager.ready();
168 | resolve(this.getJsObjectFromNSDictionary(config.toDictionary()));
169 | });
170 | }
171 |
172 | public static configure(params:any) {
173 | return new Promise((resolve, reject) => {
174 | let config = TSConfig.sharedInstance();
175 | let locationManager = this.getAdapter();
176 | locationManager.configure(params);
177 | resolve(this.getJsObjectFromNSDictionary(config.toDictionary()));
178 | });
179 | }
180 |
181 | public static setConfig(params:any) {
182 | return new Promise((resolve, reject) => {
183 | let config = TSConfig.sharedInstance();
184 | config.updateWithDictionary(params);
185 | resolve(this.getJsObjectFromNSDictionary(config.toDictionary()));
186 | });
187 | }
188 |
189 | public static reset(params:any) {
190 | return new Promise((resolve, reject) => {
191 | let config = TSConfig.sharedInstance();
192 | config.reset();
193 | config.updateWithDictionary(params);
194 | resolve(this.getJsObjectFromNSDictionary(config.toDictionary()));
195 | });
196 | }
197 |
198 | public static getState() {
199 | return new Promise((resolve, reject) => {
200 | let config = TSConfig.sharedInstance();
201 | resolve(this.getJsObjectFromNSDictionary(config.toDictionary()));
202 | });
203 | }
204 |
205 | /**
206 | * Tracking Methods
207 | */
208 | public static start() {
209 | return new Promise((resolve, reject) => {
210 | this.getAdapter().start();
211 | let config = TSConfig.sharedInstance();
212 | resolve(this.getJsObjectFromNSDictionary(config.toDictionary()));
213 | });
214 | }
215 |
216 | public static stop(success?:Function, failure?:Function) {
217 | return new Promise((resolve, reject) => {
218 | this.getAdapter().stop();
219 | let config = TSConfig.sharedInstance();
220 | resolve(this.getJsObjectFromNSDictionary(config.toDictionary()));
221 | });
222 | }
223 |
224 | public static startGeofences(success?:Function, failure?:Function) {
225 | return new Promise((resolve, reject) => {
226 | this.getAdapter().startGeofences();
227 | let config = TSConfig.sharedInstance();
228 | resolve(this.getJsObjectFromNSDictionary(config.toDictionary()));
229 | });
230 | }
231 |
232 | public static changePace(value: boolean, success?:any, failure?:any) {
233 | return new Promise((resolve, reject) => {
234 | this.getAdapter().changePace(value);
235 | resolve(value);
236 | });
237 | }
238 |
239 | public static startSchedule(success?:Function, failure?:Function) {
240 | return new Promise((resolve, reject) => {
241 | this.getAdapter().startSchedule();
242 | let config = TSConfig.sharedInstance();
243 | resolve(this.getJsObjectFromNSDictionary(config.toDictionary()));
244 | });
245 | }
246 |
247 | public static stopSchedule(success?:Function, failure?:Function) {
248 | return new Promise((resolve, reject) => {
249 | this.getAdapter().stopSchedule();
250 | let config = TSConfig.sharedInstance();
251 | resolve(this.getJsObjectFromNSDictionary(config.toDictionary()));
252 | });
253 | }
254 |
255 | public static getCurrentPosition(options:any) {
256 | return new Promise((resolve, reject) => {
257 | let request = new TSCurrentPositionRequest();
258 | request.success = (tsLocation:any) => {
259 | resolve(this.getJsObjectFromNSDictionary(tsLocation.toDictionary()));
260 | };
261 | request.failure = (error) => {
262 | reject(error);
263 | };
264 |
265 | if (typeof(options.timeout) === 'number') {
266 | request.timeout = options.timeout;
267 | }
268 | if (typeof(options.maximumAge) === 'number') {
269 | request.maximumAge = options.maximumAge;
270 | }
271 | if (typeof(options.persist) === 'boolean') {
272 | request.persist = options.persist;
273 | }
274 | if (typeof(options.samples) === 'number') {
275 | request.samples = options.samples;
276 | }
277 | if (typeof(options.desiredAccuracy) === 'number') {
278 | request.desiredAccuracy = options.desiredAccuracy;
279 | }
280 | if (typeof(options.extras) === 'object') {
281 | request.extras = options.extras;
282 | }
283 | this.getAdapter().getCurrentPosition(request);
284 | });
285 | }
286 |
287 | public static watchPosition(success:Function, failure:Function, options:any) {
288 | let request = new TSWatchPositionRequest();
289 | request.success = (tsLocation:any) => {
290 | success(this.getJsObjectFromNSDictionary(tsLocation.toDictionary()));
291 | };
292 | request.failure = (error) => {
293 | failure(error);
294 | };
295 | if (typeof(options.interval) === 'number') {
296 | request.interval = options.interval;
297 | }
298 | if (typeof(options.desiredAccuracy) === 'number') {
299 | request.desiredAccuracy = options.desiredAccuracy;
300 | }
301 | if (typeof(options.persist) === 'boolean') {
302 | request.persist = options.persist;
303 | }
304 | if (typeof(options.extras) === 'object') {
305 | request.extras = options.extras;
306 | }
307 | if (typeof(options.timeout) === 'number') {
308 | request.timeout = options.timeout;
309 | }
310 | this.getAdapter().watchPosition(request);
311 | }
312 |
313 | public static stopWatchPosition(success?:Function, failure?:Function) {
314 | return new Promise((resolve, reject) => {
315 | this.getAdapter().stopWatchPosition();
316 | resolve(true);
317 | });
318 | }
319 |
320 | public static getOdometer() {
321 | return new Promise((resolve, reject) => {
322 | resolve(this.getAdapter().getOdometer());
323 | });
324 | }
325 |
326 | public static setOdometer(value:number) {
327 | return new Promise((resolve, reject) => {
328 | let request = new TSCurrentPositionRequest();
329 | request.success = (tsLocation:any) => {
330 | resolve(this.getJsObjectFromNSDictionary(tsLocation.toDictionary()));
331 | }
332 | request.failure = (error) => { reject(error) }
333 | this.getAdapter().setOdometerRequest(value, request);
334 | });
335 | }
336 | public static resetOdometer() {
337 | return this.setOdometer(0);
338 | }
339 | /**
340 | * HTTP & Persistence Methods
341 | */
342 | public static sync() {
343 | return new Promise((resolve, reject) => {
344 | this.getAdapter().syncFailure((records) => {
345 | resolve(this.getJsArrayFromNSArray(records));
346 | }, (error:any) => {
347 | reject(error.code);
348 | });
349 | });
350 | }
351 |
352 | public static getLocations(success:Function, failure?:Function) {
353 | return new Promise((resolve, reject) => {
354 | this.getAdapter().getLocationsFailure((rs:any) => {
355 | resolve(this.getJsArrayFromNSArray(rs));
356 | }, (error:any) => {
357 | reject(error);
358 | });
359 | });
360 | }
361 |
362 | public static getCount(success: Function) {
363 | return new Promise((resolve, reject) => {
364 | resolve(this.getAdapter().getCount());
365 | });
366 | }
367 |
368 | public static insertLocation(data:any) {
369 | return new Promise((resolve, reject) => {
370 | this.getAdapter().insertLocationSuccessFailure(data, (uuid:string) => {
371 | resolve(uuid);
372 | }, (error:string) => {
373 | reject(error);
374 | });
375 | });
376 | }
377 |
378 | // @deprecated
379 | public static clearDatabase() {
380 | return this.destroyLocations();
381 | }
382 |
383 | public static destroyLocations() {
384 | return new Promise((resolve, reject) => {
385 | this.getAdapter().destroyLocationsFailure(() => {
386 | resolve();
387 | }, (error) => {
388 | reject(error);
389 | });
390 | });
391 | }
392 |
393 | /**
394 | * Geofencing Methods
395 | */
396 | public static addGeofence(params:any) {
397 | return new Promise((resolve, reject) => {
398 | let success = () => { resolve() }
399 | let failure = (error) => { reject(error) }
400 | let geofence = this.buildGeofence(params);
401 | if (geofence) {
402 | this.getAdapter().addGeofenceSuccessFailure(geofence, success, failure);
403 | } else {
404 | reject('Invalid geofence data');
405 | }
406 | });
407 | }
408 |
409 | public static removeGeofence(identifier:string) {
410 | return new Promise((resolve, reject) => {
411 | let success = () => { resolve() }
412 | let failure = (error) => { reject(error) }
413 | this.getAdapter().removeGeofenceSuccessFailure(identifier, success, failure);
414 | });
415 | }
416 |
417 | public static addGeofences(geofences?:Array) {
418 | return new Promise((resolve, reject) => {
419 | let rs = [];
420 | for (let n=0,len=geofences.length;n { resolve() }
430 | let failure = (error) => { reject(error) }
431 | this.getAdapter().addGeofencesSuccessFailure(rs, success, failure);
432 | });
433 | }
434 |
435 | public static removeGeofences(geofences?:Array) {
436 | return new Promise((resolve, reject) => {
437 | let success = () => { resolve() }
438 | let failure = (error) => { reject(error) }
439 | this.getAdapter().removeGeofencesSuccessFailure(geofences, success, failure);
440 | });
441 | }
442 |
443 | public static getGeofences() {
444 | return new Promise((resolve, reject) => {
445 | this.getAdapter().getGeofencesFailure((geofences:any) => {
446 | let rs = [];
447 | for (let loop = 0; loop < geofences.count; loop ++) {
448 | let geofence = geofences.objectAtIndex(loop);
449 | rs.push(this.getJsObjectFromNSDictionary(geofence.toDictionary()));
450 | }
451 | resolve(rs);
452 | }, (error:string) => {
453 | reject(error);
454 | });
455 | });
456 | }
457 |
458 | public static startBackgroundTask() {
459 | return new Promise((resolve, reject) => {
460 | resolve(this.getAdapter().createBackgroundTask());
461 | });
462 | }
463 |
464 | public static finish(taskId:number) {
465 | return new Promise((resolve, reject) => {
466 | this.getAdapter().stopBackgroundTask(taskId);
467 | resolve();
468 | });
469 | }
470 |
471 | /**
472 | * Logging & Debug methods
473 | */
474 | public static playSound(soundId:number) {
475 | return new Promise((resolve, reject) => {
476 | this.getAdapter().playSound(soundId);
477 | resolve();
478 | });
479 | }
480 |
481 | public static getLog() {
482 | return new Promise((resolve, reject) => {
483 | let success = (log) => { resolve(log) }
484 | let failure = (error) => { reject(error) }
485 | this.getAdapter().getLogFailure(success, failure);
486 | });
487 | }
488 |
489 | public static destroyLog() {
490 | return new Promise((resolve, reject) => {
491 | if (this.getAdapter().destroyLog()) {
492 | resolve();
493 | } else {
494 | reject();
495 | }
496 | });
497 | }
498 |
499 | public static emailLog(email:string) {
500 | return new Promise((resolve, reject) => {
501 | let success = () => { resolve() }
502 | let failure = (error) => { reject(error) }
503 | this.getAdapter().emailLogSuccessFailure(email, success, failure);
504 | });
505 |
506 | }
507 |
508 | public static getSensors() {
509 | return new Promise((resolve, reject) => {
510 | let adapter = this.getAdapter();
511 | let result = {
512 | "platform": "ios",
513 | "accelerometer": adapter.isAccelerometerAvailable(),
514 | "gyroscope": adapter.isGyroAvailable(),
515 | "magnetometer": adapter.isMagnetometerAvailable(),
516 | "motion_hardware": adapter.isMotionHardwareAvailable()
517 | };
518 | resolve(result);
519 | });
520 | }
521 |
522 | public static isPowerSaveMode(success: Function, failure?:Function) {
523 | return new Promise((resolve, reject) => {
524 | resolve(this.getAdapter().isPowerSaveMode());
525 | });
526 | }
527 |
528 | public static log(level, msg) {
529 | this.getAdapter().logMessage(level, msg);
530 | }
531 |
532 | /**
533 | * Private
534 | */
535 | private static buildGeofence(params:any) {
536 | if (!params.identifier || !params.radius || !params.latitude || !params.longitude) {
537 | return null;
538 | }
539 | let geofence = new TSGeofence();
540 | geofence.identifier = params.identifier;
541 | geofence.radius = params.radius;
542 | geofence.latitude = params.latitude;
543 | geofence.longitude = params.longitude;
544 | if (typeof(params.notifyOnEntry) === 'boolean') {
545 | geofence.notifyOnEntry = params.notifyOnEntry;
546 | }
547 | if (typeof(params.notifyOnExit) === 'boolean') {
548 | geofence.notifyOnExit = params.notifyOnExit;
549 | }
550 | if (typeof(params.notifyOnDwell) === 'boolean') {
551 | geofence.notifyOnDwell = params.notifyOnDwell;
552 | }
553 | if (typeof(params.loiteringDelay) === 'number') {
554 | geofence.loiteringDelay = params.loiteringDelay;
555 | }
556 | if (typeof(params.extras) === 'object') {
557 | geofence.extras = params.extras;
558 | }
559 | return geofence;
560 | }
561 |
562 | private static getAdapter() {
563 | if (!this.adapter) {
564 | let app = utils.ios.getter(UIApplication, UIApplication.sharedApplication);
565 | this.adapter = TSLocationManager.sharedInstance();
566 | this.adapter.viewController = app.keyWindow.rootViewController;
567 | }
568 | return this.adapter;
569 | }
570 |
571 | private static getJsObjectFromNSDictionary(dictionary:any) {
572 | let keys = dictionary.allKeys;
573 | let result = {};
574 |
575 | for (let loop = 0; loop < keys.count; loop++) {
576 | let key = keys[loop];
577 | let item = dictionary.objectForKey(key);
578 |
579 | result[key] = this.getJsObject(item);
580 | }
581 | return result;
582 | }
583 |
584 | private static getJsArrayFromNSArray(array: any): Array