@josuelmm/cordova-background-geolocation 4.2.2 → 4.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.npmignore +11 -0
- package/CHANGELOG.md +213 -0
- package/HISTORY.md +73 -0
- package/README.md +45 -74
- package/android/CDVBackgroundGeolocation/src/main/java/com/marianhello/bgloc/cordova/ConfigMapper.java +24 -0
- package/android/CDVBackgroundGeolocation/src/main/java/com/tenforwardconsulting/bgloc/cordova/BackgroundGeolocationPlugin.java +61 -1
- package/android/common/src/main/AndroidManifest.xml +1 -1
- package/android/common/src/main/java/com/marianhello/bgloc/BootCompletedReceiver.java +6 -3
- package/android/common/src/main/java/com/marianhello/bgloc/Config.java +65 -1
- package/android/common/src/main/java/com/marianhello/bgloc/PostLocationTask.java +1 -1
- package/android/common/src/main/java/com/marianhello/bgloc/data/BackgroundLocation.java +94 -0
- package/android/common/src/main/java/com/marianhello/bgloc/data/ConfigJsonMapper.java +205 -0
- package/android/common/src/main/java/com/marianhello/bgloc/data/LocationTemplateFactory.java +6 -0
- package/android/common/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteConfigurationContract.java +5 -1
- package/android/common/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteConfigurationDAO.java +32 -1
- package/android/common/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteLocationContract.java +12 -2
- package/android/common/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteLocationDAO.java +33 -2
- package/android/common/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteOpenHelper.java +15 -1
- package/android/common/src/main/java/com/marianhello/bgloc/provider/DistanceFilterLocationProvider.java +23 -8
- package/android/common/src/main/java/com/marianhello/bgloc/service/LocationServiceImpl.java +246 -21
- package/android/common/src/main/java/com/marianhello/bgloc/service/LocationServiceProxy.java +5 -2
- package/android/common/src/main/java/com/marianhello/bgloc/sync/BatchManager.java +46 -13
- package/ios/CDVBackgroundGeolocation/CDVBackgroundGeolocation.m +23 -1
- package/ios/common/BackgroundGeolocation/MAURBackgroundGeolocationFacade.m +111 -5
- package/ios/common/BackgroundGeolocation/MAURBackgroundSync.m +20 -0
- package/ios/common/BackgroundGeolocation/MAURConfig.h +2 -0
- package/ios/common/BackgroundGeolocation/MAURConfig.m +16 -2
- package/ios/common/BackgroundGeolocation/MAURConfigurationContract.h +3 -0
- package/ios/common/BackgroundGeolocation/MAURConfigurationContract.m +3 -1
- package/ios/common/BackgroundGeolocation/MAURGeolocationOpenHelper.m +15 -1
- package/ios/common/BackgroundGeolocation/MAURLocation.h +12 -0
- package/ios/common/BackgroundGeolocation/MAURLocation.m +33 -4
- package/ios/common/BackgroundGeolocation/MAURLocationContract.h +4 -0
- package/ios/common/BackgroundGeolocation/MAURLocationContract.m +5 -1
- package/ios/common/BackgroundGeolocation/MAURPostLocationTask.h +9 -0
- package/ios/common/BackgroundGeolocation/MAURPostLocationTask.m +59 -1
- package/ios/common/BackgroundGeolocation/MAURSQLiteConfigurationDAO.m +54 -4
- package/ios/common/BackgroundGeolocation/MAURSQLiteLocationDAO.h +12 -0
- package/ios/common/BackgroundGeolocation/MAURSQLiteLocationDAO.m +125 -5
- package/package.json +36 -1
- package/plugin.xml +3 -2
- package/www/BackgroundGeolocation.d.ts +114 -3
- package/www/BackgroundGeolocation.js +11 -4
- package/CLAUDE.md +0 -56
- package/android/CDVBackgroundGeolocation/src/test/java/com/marianhello/ConfigMapperTest.java +0 -220
- package/android/common/src/androidTest/java/com/marianhello/bgloc/BackgroundGeolocationFacadeTest.java +0 -45
- package/android/common/src/androidTest/java/com/marianhello/bgloc/BatchManagerTest.java +0 -570
- package/android/common/src/androidTest/java/com/marianhello/bgloc/ConfigTest.java +0 -76
- package/android/common/src/androidTest/java/com/marianhello/bgloc/ContentProviderLocationDAOTest.java +0 -437
- package/android/common/src/androidTest/java/com/marianhello/bgloc/DBLogReaderTest.java +0 -95
- package/android/common/src/androidTest/java/com/marianhello/bgloc/LocationContentProviderTest.java +0 -159
- package/android/common/src/androidTest/java/com/marianhello/bgloc/LocationServiceProxyTest.java +0 -161
- package/android/common/src/androidTest/java/com/marianhello/bgloc/LocationServiceTest.java +0 -247
- package/android/common/src/androidTest/java/com/marianhello/bgloc/SQLiteConfigurationDAOTest.java +0 -200
- package/android/common/src/androidTest/java/com/marianhello/bgloc/SQLiteLocationDAOTest.java +0 -457
- package/android/common/src/androidTest/java/com/marianhello/bgloc/SQLiteLocationDAOThreadTest.java +0 -96
- package/android/common/src/androidTest/java/com/marianhello/bgloc/SQLiteOpenHelperTest.java +0 -225
- package/android/common/src/androidTest/java/com/marianhello/bgloc/TestPluginDelegate.java +0 -46
- package/android/common/src/androidTest/java/com/marianhello/bgloc/TestResourceResolver.java +0 -14
- package/android/common/src/androidTest/java/com/marianhello/bgloc/provider/MockLocationProvider.java +0 -50
- package/android/common/src/androidTest/java/com/marianhello/bgloc/provider/TestLocationProviderFactory.java +0 -17
- package/android/common/src/androidTest/java/com/marianhello/bgloc/sqlite/SQLiteOpenHelper10.java +0 -92
- package/android/common/src/androidTest/java/com/marianhello/bgloc/test/LocationProviderTestCase.java +0 -107
- package/android/common/src/androidTest/java/com/marianhello/bgloc/test/TestConstants.java +0 -5
- package/android/common/src/test/java/com/marianhello/backgroundgeolocation/ArrayListLocationTemplateTest.java +0 -82
- package/android/common/src/test/java/com/marianhello/backgroundgeolocation/BackgroundLocationTest.java +0 -128
- package/android/common/src/test/java/com/marianhello/backgroundgeolocation/ConfigTest.java +0 -191
- package/android/common/src/test/java/com/marianhello/backgroundgeolocation/DBLogReaderTest.java +0 -37
- package/android/common/src/test/java/com/marianhello/backgroundgeolocation/HashMapLocationTemplateTest.java +0 -216
- package/android/common/src/test/java/com/marianhello/backgroundgeolocation/HttpPostServiceTest.java +0 -223
- package/android/common/src/test/java/com/marianhello/backgroundgeolocation/LocationTemplateFactoryTest.java +0 -50
- package/android/common/src/test/java/com/marianhello/backgroundgeolocation/PostLocationTaskTest.java +0 -180
- package/android/common/src/test/java/com/marianhello/backgroundgeolocation/TestHelper.java +0 -16
- package/ios/common/BackgroundGeolocationTests/Info.plist +0 -24
- package/ios/common/BackgroundGeolocationTests/MAURBackgroundLocationTest.m +0 -185
- package/ios/common/BackgroundGeolocationTests/MAURConfigTest.m +0 -161
- package/ios/common/BackgroundGeolocationTests/MAURGeolocationOpenHelperTest.m +0 -102
- package/ios/common/BackgroundGeolocationTests/MAURLocationTest.m +0 -216
- package/ios/common/BackgroundGeolocationTests/MAURLocationUploaderTest.m +0 -55
- package/ios/common/BackgroundGeolocationTests/MAURLogReaderTest.m +0 -43
- package/ios/common/BackgroundGeolocationTests/MAURSQLiteConfigurationDAOTest.m +0 -102
- package/ios/common/BackgroundGeolocationTests/MAURSQLiteHelperTest.m +0 -41
- package/ios/common/BackgroundGeolocationTests/MAURSQLiteLocationDAOTests.m +0 -240
- package/ios/common/BackgroundGeolocationTests/MAURSQLiteLocationDAOThreadTest.m +0 -84
- package/ios/common/BackgroundGeolocationTests/MAURSQLiteOpenHelperTest.m +0 -144
- package/ios/common/scripts/xcode-refactor.js +0 -184
|
@@ -26,7 +26,11 @@
|
|
|
26
26
|
@{ @"name": @LC_COLUMN_NAME_PROVIDER, @"type": [SQLColumnType sqlColumnWithType: kText]},
|
|
27
27
|
@{ @"name": @LC_COLUMN_NAME_LOCATION_PROVIDER, @"type": [SQLColumnType sqlColumnWithType: kText]},
|
|
28
28
|
@{ @"name": @LC_COLUMN_NAME_STATUS, @"type": [SQLColumnType sqlColumnWithType: kInteger]},
|
|
29
|
-
@{ @"name": @LC_COLUMN_NAME_RECORDED_AT, @"type": [SQLColumnType sqlColumnWithType: kInteger]}
|
|
29
|
+
@{ @"name": @LC_COLUMN_NAME_RECORDED_AT, @"type": [SQLColumnType sqlColumnWithType: kInteger]},
|
|
30
|
+
// v4.5 — survive sync queue
|
|
31
|
+
@{ @"name": @LC_COLUMN_NAME_EVENTS_JSON, @"type": [SQLColumnType sqlColumnWithType: kText]},
|
|
32
|
+
@{ @"name": @LC_COLUMN_NAME_BATTERY_LEVEL, @"type": [SQLColumnType sqlColumnWithType: kInteger]},
|
|
33
|
+
@{ @"name": @LC_COLUMN_NAME_IS_CHARGING, @"type": [SQLColumnType sqlColumnWithType: kInteger]}
|
|
30
34
|
];
|
|
31
35
|
|
|
32
36
|
return [MAURSQLiteHelper createTableSqlStatement:@LC_TABLE_NAME columns:columns];
|
|
@@ -30,6 +30,15 @@
|
|
|
30
30
|
|
|
31
31
|
@property (nonatomic, weak) MAURConfig * _Nullable config;
|
|
32
32
|
@property (nonatomic, weak) id<MAURPostLocationTaskDelegate> _Nullable delegate;
|
|
33
|
+
/** v4.5.1 — pending driving events buffer owned by the facade; the task drains it onto the
|
|
34
|
+
* post-transform location so events fired without a simultaneous fix (provider change,
|
|
35
|
+
* sensor crash, phone usage) survive even if `locationTransform` returns a new instance.
|
|
36
|
+
* Weak ref: if the facade is gone, no flush — by design. */
|
|
37
|
+
@property (nonatomic, weak) NSMutableArray * _Nullable pendingDrivingEventsBuffer;
|
|
38
|
+
/** v4.5.1 — same idea for the battery snapshot block. The facade installs a block that the
|
|
39
|
+
* task invokes AFTER a successful transform, so even when `locationTransform` returns a
|
|
40
|
+
* fresh instance, battery/charging fields land on what actually gets POSTed. */
|
|
41
|
+
@property (nonatomic, copy) void (^ _Nullable attachBatterySnapshot)(MAURLocation * _Nonnull);
|
|
33
42
|
|
|
34
43
|
- (void) add:(MAURLocation * _Nonnull)location;
|
|
35
44
|
- (void) start;
|
|
@@ -83,11 +83,63 @@ static MAURLocationTransform s_locationTransform = nil;
|
|
|
83
83
|
MAURLocation *location = inLocation;
|
|
84
84
|
|
|
85
85
|
if (locationTransform != nil) {
|
|
86
|
+
// v4.5.1 — snapshot v4.3+ fields BEFORE transform so they survive a transform
|
|
87
|
+
// that returns a brand new MAURLocation instance (otherwise events/battery would
|
|
88
|
+
// be lost en route to SQLite / backend).
|
|
89
|
+
NSMutableArray *rawEvents = inLocation.drivingEvents;
|
|
90
|
+
NSNumber *rawBattery = inLocation.batteryLevel;
|
|
91
|
+
NSNumber *rawCharging = inLocation.isCharging;
|
|
92
|
+
|
|
86
93
|
location = locationTransform(location);
|
|
87
94
|
|
|
88
95
|
if (location == nil) {
|
|
89
96
|
return;
|
|
90
97
|
}
|
|
98
|
+
|
|
99
|
+
// v4.5.1 — re-attach fields the transform may have dropped. When the transform
|
|
100
|
+
// produced a NEW instance (`location != inLocation`), MERGE rawEvents into the new
|
|
101
|
+
// instance's array instead of overwriting — same semantics as Android
|
|
102
|
+
// `LocationServiceImpl.onLocation` re-attach. If the transform returned the same
|
|
103
|
+
// instance (mutated in place) the rawEvents are already there.
|
|
104
|
+
if (location != inLocation) {
|
|
105
|
+
if (rawEvents != nil && [rawEvents count] > 0) {
|
|
106
|
+
if (location.drivingEvents == nil) {
|
|
107
|
+
location.drivingEvents = [rawEvents mutableCopy];
|
|
108
|
+
} else {
|
|
109
|
+
[location.drivingEvents addObjectsFromArray:rawEvents];
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (location.batteryLevel == nil) location.batteryLevel = rawBattery;
|
|
113
|
+
if (location.isCharging == nil) location.isCharging = rawCharging;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// v4.5.1 — drain pending driving events ONTO the post-transform location. Previously
|
|
118
|
+
// the facade drained them BEFORE [postLocationTask add:], so a transform that returned
|
|
119
|
+
// nil silently lost every buffered event. Now: if transform succeeded we're guaranteed
|
|
120
|
+
// `location != nil` here and the buffer is drained safely.
|
|
121
|
+
NSMutableArray *pendingBuffer = self.pendingDrivingEventsBuffer;
|
|
122
|
+
if (pendingBuffer != nil) {
|
|
123
|
+
@synchronized (pendingBuffer) {
|
|
124
|
+
if ([pendingBuffer count] > 0) {
|
|
125
|
+
NSTimeInterval nowMs = [[NSDate date] timeIntervalSince1970] * 1000.0;
|
|
126
|
+
if (location.drivingEvents == nil) location.drivingEvents = [NSMutableArray array];
|
|
127
|
+
for (NSDictionary *ev in pendingBuffer) {
|
|
128
|
+
NSNumber *t = ev[@"time"];
|
|
129
|
+
NSTimeInterval evMs = t != nil ? [t doubleValue] : nowMs;
|
|
130
|
+
if (nowMs - evMs <= 60000.0) {
|
|
131
|
+
[location.drivingEvents addObject:ev];
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
[pendingBuffer removeAllObjects];
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// v4.5.1 — stamp battery snapshot AFTER transform so it lands on the POSTed instance
|
|
139
|
+
// even if the transform created a new one.
|
|
140
|
+
void (^attachBattery)(MAURLocation *) = self.attachBatterySnapshot;
|
|
141
|
+
if (attachBattery != nil) {
|
|
142
|
+
attachBattery(location);
|
|
91
143
|
}
|
|
92
144
|
|
|
93
145
|
// v3.5 Phase 4: mock location policy. Detection already exists in MAURLocation.simulated.
|
|
@@ -255,7 +307,8 @@ static MAURLocationTransform s_locationTransform = nil;
|
|
|
255
307
|
return YES;
|
|
256
308
|
}
|
|
257
309
|
|
|
258
|
-
|
|
310
|
+
// v4.4.1: guard against outError == NULL (defensive — current callers pass &error).
|
|
311
|
+
if (outError == NULL || *outError == nil) {
|
|
259
312
|
DDLogDebug(@"%@ Server error while posting locations responseCode: %ld", TAG, (long)statusCode);
|
|
260
313
|
} else {
|
|
261
314
|
DDLogError(@"%@ Error while posting locations %@", TAG, [*outError localizedDescription]);
|
|
@@ -269,6 +322,11 @@ static MAURLocationTransform s_locationTransform = nil;
|
|
|
269
322
|
if (![self.config syncEnabled] || ![self.config hasValidSyncUrl]) {
|
|
270
323
|
return;
|
|
271
324
|
}
|
|
325
|
+
// v4.5.1 — rescue rows stuck in SyncPending from a previous upload that never completed
|
|
326
|
+
// (app/process killed mid-flight). Anything older than 15 min is safe to revert to
|
|
327
|
+
// PostPending; rows younger than that may still be uploading on a background NSURLSession.
|
|
328
|
+
NSTimeInterval staleCutoff = [[NSDate date] timeIntervalSince1970] - (15 * 60);
|
|
329
|
+
[[MAURSQLiteLocationDAO sharedInstance] restoreStaleSyncLocationsOlderThan:staleCutoff error:nil];
|
|
272
330
|
// For sync (batch) only static queryParams placeholders apply; per-location templating
|
|
273
331
|
// belongs in real-time post (httpMode="single" + httpMethod=GET) instead.
|
|
274
332
|
NSString *resolvedSyncUrl = [MAURUrlTemplateResolver resolve:self.config.syncUrl location:nil queryParams:self.config.queryParams];
|
|
@@ -88,7 +88,8 @@
|
|
|
88
88
|
@COMMA_SEP @CC_COLUMN_NAME_PAUSE_LOCATION_UPDATES
|
|
89
89
|
@COMMA_SEP @CC_COLUMN_NAME_TEMPLATE
|
|
90
90
|
@COMMA_SEP @CC_COLUMN_NAME_LAST_UPDATED_AT
|
|
91
|
-
@
|
|
91
|
+
@COMMA_SEP @CC_COLUMN_NAME_CONFIG_JSON
|
|
92
|
+
@") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,DateTime('now'),?)";
|
|
92
93
|
|
|
93
94
|
[queue inDatabase:^(FMDatabase *database) {
|
|
94
95
|
success = [database executeUpdate:sql,
|
|
@@ -119,7 +120,9 @@
|
|
|
119
120
|
[config hasSaveBatteryOnBackground] ? config._saveBatteryOnBackground : @CC_COLUMN_NAME_NULLABLE,
|
|
120
121
|
[config hasMaxLocations] ? config.maxLocations : @CC_COLUMN_NAME_NULLABLE,
|
|
121
122
|
[config hasPauseLocationUpdates] ? config._pauseLocationUpdates : @CC_COLUMN_NAME_NULLABLE,
|
|
122
|
-
(templateString != nil) ? templateString : @CC_COLUMN_NAME_NULLABLE
|
|
123
|
+
(templateString != nil) ? templateString : @CC_COLUMN_NAME_NULLABLE,
|
|
124
|
+
// v4.5: full Config as JSON for paridad con Android
|
|
125
|
+
[self serializeConfigToJson:config]
|
|
123
126
|
];
|
|
124
127
|
|
|
125
128
|
if (success) {
|
|
@@ -165,6 +168,7 @@
|
|
|
165
168
|
@COMMA_SEP @CC_COLUMN_NAME_MAX_LOCATIONS
|
|
166
169
|
@COMMA_SEP @CC_COLUMN_NAME_PAUSE_LOCATION_UPDATES
|
|
167
170
|
@COMMA_SEP @CC_COLUMN_NAME_TEMPLATE
|
|
171
|
+
@COMMA_SEP @CC_COLUMN_NAME_CONFIG_JSON
|
|
168
172
|
@" FROM " @CC_TABLE_NAME @" WHERE " @CC_COLUMN_NAME_ID @" = 1";
|
|
169
173
|
|
|
170
174
|
[queue inDatabase:^(FMDatabase *database) {
|
|
@@ -231,14 +235,60 @@
|
|
|
231
235
|
config._template = [NSJSONSerialization JSONObjectWithData:jsonTemplate options:0 error:nil];
|
|
232
236
|
}
|
|
233
237
|
}
|
|
238
|
+
// v4.5: rehydrate post-3.2 keys from config_json blob (paridad Android).
|
|
239
|
+
// Index 28 is the new column. Strict NULL check (no NULLHACK sentinel for JSON column).
|
|
240
|
+
if (![rs columnIndexIsNull:28]) {
|
|
241
|
+
NSString *jsonString = [rs stringForColumnIndex:28];
|
|
242
|
+
if (jsonString != nil && jsonString.length > 0) {
|
|
243
|
+
[self applyConfigJson:jsonString to:config];
|
|
244
|
+
}
|
|
245
|
+
}
|
|
234
246
|
}
|
|
235
|
-
|
|
247
|
+
|
|
236
248
|
[rs close];
|
|
237
249
|
}];
|
|
238
|
-
|
|
250
|
+
|
|
239
251
|
return config;
|
|
240
252
|
}
|
|
241
253
|
|
|
254
|
+
// v4.5: serialize all post-3.2 keys to JSON for storage. Mirrors Android ConfigJsonMapper.
|
|
255
|
+
- (NSString*) serializeConfigToJson:(MAURConfig*)config
|
|
256
|
+
{
|
|
257
|
+
NSMutableDictionary *j = [NSMutableDictionary dictionary];
|
|
258
|
+
if (config.httpMethod != nil) j[@"httpMethod"] = config.httpMethod;
|
|
259
|
+
if (config.syncHttpMethod != nil) j[@"syncHttpMethod"] = config.syncHttpMethod;
|
|
260
|
+
if (config.httpMode != nil) j[@"httpMode"] = config.httpMode;
|
|
261
|
+
if (config.syncMode != nil) j[@"syncMode"] = config.syncMode;
|
|
262
|
+
if (config.queryParams != nil) j[@"queryParams"] = config.queryParams;
|
|
263
|
+
if (config.heartbeatInterval != nil) j[@"heartbeatInterval"] = config.heartbeatInterval;
|
|
264
|
+
if (config.mockLocationPolicy != nil) j[@"mockLocationPolicy"] = config.mockLocationPolicy;
|
|
265
|
+
if (config.drivingEvents != nil) j[@"drivingEvents"] = config.drivingEvents;
|
|
266
|
+
if (config.includeBattery != nil) j[@"includeBattery"] = config.includeBattery;
|
|
267
|
+
if (config._showsBackgroundLocationIndicator != nil) j[@"showsBackgroundLocationIndicator"] = config._showsBackgroundLocationIndicator;
|
|
268
|
+
NSError *err = nil;
|
|
269
|
+
NSData *data = [NSJSONSerialization dataWithJSONObject:j options:0 error:&err];
|
|
270
|
+
if (err != nil || data == nil) return @"";
|
|
271
|
+
return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
- (void) applyConfigJson:(NSString*)jsonString to:(MAURConfig*)config
|
|
275
|
+
{
|
|
276
|
+
NSData *data = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
|
|
277
|
+
NSError *err = nil;
|
|
278
|
+
NSDictionary *j = [NSJSONSerialization JSONObjectWithData:data options:0 error:&err];
|
|
279
|
+
if (err != nil || ![j isKindOfClass:[NSDictionary class]]) return;
|
|
280
|
+
if (j[@"httpMethod"]) config.httpMethod = j[@"httpMethod"];
|
|
281
|
+
if (j[@"syncHttpMethod"]) config.syncHttpMethod = j[@"syncHttpMethod"];
|
|
282
|
+
if (j[@"httpMode"]) config.httpMode = j[@"httpMode"];
|
|
283
|
+
if (j[@"syncMode"]) config.syncMode = j[@"syncMode"];
|
|
284
|
+
if ([j[@"queryParams"] isKindOfClass:[NSDictionary class]]) config.queryParams = [j[@"queryParams"] mutableCopy];
|
|
285
|
+
if (j[@"heartbeatInterval"]) config.heartbeatInterval = j[@"heartbeatInterval"];
|
|
286
|
+
if (j[@"mockLocationPolicy"]) config.mockLocationPolicy = j[@"mockLocationPolicy"];
|
|
287
|
+
if ([j[@"drivingEvents"] isKindOfClass:[NSDictionary class]]) config.drivingEvents = j[@"drivingEvents"];
|
|
288
|
+
if (j[@"includeBattery"] != nil) config.includeBattery = j[@"includeBattery"];
|
|
289
|
+
if (j[@"showsBackgroundLocationIndicator"] != nil) config._showsBackgroundLocationIndicator = j[@"showsBackgroundLocationIndicator"];
|
|
290
|
+
}
|
|
291
|
+
|
|
242
292
|
- (BOOL) clearDatabase
|
|
243
293
|
{
|
|
244
294
|
__block BOOL success;
|
|
@@ -28,6 +28,18 @@
|
|
|
28
28
|
- (BOOL) deleteAllLocations:(NSError * __autoreleasing *)outError;
|
|
29
29
|
/** Mark all locations pending sync (PostPending) as deleted. Clears the sync queue without sending. */
|
|
30
30
|
- (BOOL) deletePendingSyncLocations:(NSError * __autoreleasing *)outError;
|
|
31
|
+
/** v4.5.1 — soft-delete only sync-pending rows whose `recorded_at` is <= cutoff (UNIX seconds).
|
|
32
|
+
* Used after a successful background-sync POST so locations persisted DURING the upload (race
|
|
33
|
+
* window) are NOT incorrectly marked deleted. */
|
|
34
|
+
- (BOOL) deleteSyncedLocationsBefore:(NSTimeInterval)cutoff error:(NSError * __autoreleasing *)outError;
|
|
35
|
+
/** v4.5.1 — undo the in-flight SyncPending state when the upload failed. SyncPending → PostPending
|
|
36
|
+
* so the next sync window re-tries them. Without this, a network failure during background-sync
|
|
37
|
+
* would silently drop every pending location. */
|
|
38
|
+
- (BOOL) restoreFailedSyncLocations:(NSError * __autoreleasing *)outError;
|
|
39
|
+
/** v4.5.1 — recover SyncPending rows that got stuck (app/process killed between getLocationsForSync
|
|
40
|
+
* and the upload's success/failure callback). Rows whose `recorded_at` is older than `cutoff`
|
|
41
|
+
* (UNIX seconds) are restored to PostPending so they get retried. Call before each sync window. */
|
|
42
|
+
- (BOOL) restoreStaleSyncLocationsOlderThan:(NSTimeInterval)cutoff error:(NSError * __autoreleasing *)outError;
|
|
31
43
|
- (BOOL) clearDatabase;
|
|
32
44
|
- (NSString*) getDatabaseName;
|
|
33
45
|
- (NSString*) getDatabasePath;
|
|
@@ -94,9 +94,17 @@
|
|
|
94
94
|
}
|
|
95
95
|
[rs close];
|
|
96
96
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
97
|
+
// v4.5.1 FIX (CRITICAL): mark the rows we just selected as SyncPending — NOT Deleted.
|
|
98
|
+
// The previous code UPDATEd the WHOLE table to Deleted before the upload had even started,
|
|
99
|
+
// losing every fix on HTTP failure / network drop. Now:
|
|
100
|
+
// PostPending → SyncPending (in-flight, do not re-include)
|
|
101
|
+
// on success in the network task: SyncPending → Deleted (deleteSyncedLocationsBefore:)
|
|
102
|
+
// on failure in the network task: SyncPending → PostPending (restoreFailedSyncLocations)
|
|
103
|
+
NSString *upd = @"UPDATE " @LC_TABLE_NAME @" SET " @LC_COLUMN_NAME_STATUS @" = ? WHERE " @LC_COLUMN_NAME_STATUS @" = ?";
|
|
104
|
+
if (![database executeUpdate:upd,
|
|
105
|
+
[NSString stringWithFormat:@"%ld", MAURLocationSyncPending],
|
|
106
|
+
[NSString stringWithFormat:@"%ld", MAURLocationPostPending]]) {
|
|
107
|
+
NSLog(@"Marking PostPending → SyncPending failed code: %d: message: %@", [database lastErrorCode], [database lastErrorMessage]);
|
|
100
108
|
}
|
|
101
109
|
}];
|
|
102
110
|
|
|
@@ -139,7 +147,18 @@
|
|
|
139
147
|
@COMMA_SEP @LC_COLUMN_NAME_LOCATION_PROVIDER
|
|
140
148
|
@COMMA_SEP @LC_COLUMN_NAME_STATUS
|
|
141
149
|
@COMMA_SEP @LC_COLUMN_NAME_RECORDED_AT
|
|
142
|
-
@
|
|
150
|
+
@COMMA_SEP @LC_COLUMN_NAME_EVENTS_JSON
|
|
151
|
+
@COMMA_SEP @LC_COLUMN_NAME_BATTERY_LEVEL
|
|
152
|
+
@COMMA_SEP @LC_COLUMN_NAME_IS_CHARGING
|
|
153
|
+
@") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
|
|
154
|
+
|
|
155
|
+
// v4.5: serialize driving events array to JSON for SQLite storage.
|
|
156
|
+
NSString *eventsJson = nil;
|
|
157
|
+
if (location.drivingEvents != nil && [location.drivingEvents count] > 0) {
|
|
158
|
+
NSError *jerr = nil;
|
|
159
|
+
NSData *jd = [NSJSONSerialization dataWithJSONObject:location.drivingEvents options:0 error:&jerr];
|
|
160
|
+
if (jd != nil) eventsJson = [[NSString alloc] initWithData:jd encoding:NSUTF8StringEncoding];
|
|
161
|
+
}
|
|
143
162
|
|
|
144
163
|
BOOL success = [database executeUpdate:sql,
|
|
145
164
|
[NSNumber numberWithDouble:[location.time timeIntervalSince1970]],
|
|
@@ -152,7 +171,10 @@
|
|
|
152
171
|
location.provider ?: [NSNull null],
|
|
153
172
|
location.locationProvider ?: [NSNull null],
|
|
154
173
|
location.isValid == YES ? @(1) : @(0),
|
|
155
|
-
recordedAt
|
|
174
|
+
recordedAt,
|
|
175
|
+
eventsJson ?: [NSNull null],
|
|
176
|
+
location.batteryLevel ?: [NSNull null],
|
|
177
|
+
location.isCharging ?: [NSNull null]
|
|
156
178
|
];
|
|
157
179
|
|
|
158
180
|
if (success) {
|
|
@@ -223,8 +245,19 @@
|
|
|
223
245
|
@COMMA_SEP @LC_COLUMN_NAME_LOCATION_PROVIDER @EQ_BIND
|
|
224
246
|
@COMMA_SEP @LC_COLUMN_NAME_STATUS @EQ_BIND
|
|
225
247
|
@COMMA_SEP @LC_COLUMN_NAME_RECORDED_AT @EQ_BIND
|
|
248
|
+
@COMMA_SEP @LC_COLUMN_NAME_EVENTS_JSON @EQ_BIND
|
|
249
|
+
@COMMA_SEP @LC_COLUMN_NAME_BATTERY_LEVEL @EQ_BIND
|
|
250
|
+
@COMMA_SEP @LC_COLUMN_NAME_IS_CHARGING @EQ_BIND
|
|
226
251
|
@" WHERE " @LC_COLUMN_NAME_ID @EQ_BIND;
|
|
227
252
|
|
|
253
|
+
// v4.5.1: serialize events for UPDATE path so old values don't bleed onto new locations
|
|
254
|
+
NSString *eventsJsonForUpdate = nil;
|
|
255
|
+
if (location.drivingEvents != nil && [location.drivingEvents count] > 0) {
|
|
256
|
+
NSError *jerr = nil;
|
|
257
|
+
NSData *jd = [NSJSONSerialization dataWithJSONObject:location.drivingEvents options:0 error:&jerr];
|
|
258
|
+
if (jd != nil) eventsJsonForUpdate = [[NSString alloc] initWithData:jd encoding:NSUTF8StringEncoding];
|
|
259
|
+
}
|
|
260
|
+
|
|
228
261
|
BOOL success = [database executeUpdate:sql,
|
|
229
262
|
[NSNumber numberWithDouble:[location.time timeIntervalSince1970]],
|
|
230
263
|
location.accuracy,
|
|
@@ -237,6 +270,9 @@
|
|
|
237
270
|
location.locationProvider ?: [NSNull null],
|
|
238
271
|
location.isValid == YES ? @(1) : @(0),
|
|
239
272
|
recordedAt,
|
|
273
|
+
eventsJsonForUpdate ?: [NSNull null],
|
|
274
|
+
location.batteryLevel ?: [NSNull null],
|
|
275
|
+
location.isCharging ?: [NSNull null],
|
|
240
276
|
locationId
|
|
241
277
|
];
|
|
242
278
|
|
|
@@ -304,6 +340,77 @@
|
|
|
304
340
|
return success;
|
|
305
341
|
}
|
|
306
342
|
|
|
343
|
+
- (BOOL) deleteSyncedLocationsBefore:(NSTimeInterval)cutoff error:(NSError * __autoreleasing *)outError
|
|
344
|
+
{
|
|
345
|
+
__block BOOL success = YES;
|
|
346
|
+
// v4.5.1 — operate on SyncPending (the rows the network task is/was uploading), not on
|
|
347
|
+
// PostPending (those are still queued for real-time POST and must NOT be touched).
|
|
348
|
+
NSString *sql = @"UPDATE " @LC_TABLE_NAME
|
|
349
|
+
@" SET " @LC_COLUMN_NAME_STATUS @" = ? "
|
|
350
|
+
@" WHERE " @LC_COLUMN_NAME_STATUS @" = ? AND " @LC_COLUMN_NAME_RECORDED_AT @" <= ?";
|
|
351
|
+
[queue inDatabase:^(FMDatabase *database) {
|
|
352
|
+
if (![database executeUpdate:sql,
|
|
353
|
+
@(MAURLocationDeleted),
|
|
354
|
+
@(MAURLocationSyncPending),
|
|
355
|
+
@(cutoff)]) {
|
|
356
|
+
int errorCode = [database lastErrorCode];
|
|
357
|
+
NSString *errorMessage = [database lastErrorMessage];
|
|
358
|
+
NSLog(@"deleteSyncedLocationsBefore failed code: %d: message: %@", errorCode, errorMessage);
|
|
359
|
+
if (outError != NULL) {
|
|
360
|
+
*outError = [NSError errorWithDomain:Domain code:errorCode userInfo:@{ NSLocalizedDescriptionKey: errorMessage ?: @"" }];
|
|
361
|
+
}
|
|
362
|
+
success = NO;
|
|
363
|
+
}
|
|
364
|
+
}];
|
|
365
|
+
return success;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
- (BOOL) restoreStaleSyncLocationsOlderThan:(NSTimeInterval)cutoff error:(NSError * __autoreleasing *)outError
|
|
369
|
+
{
|
|
370
|
+
// v4.5.1 — rows left as SyncPending because the previous sync's task was killed
|
|
371
|
+
// (app suspended mid-upload, OS process death, manual kill) never reach their
|
|
372
|
+
// success/failure callback. Call at the start of each sync window to rescue them.
|
|
373
|
+
__block BOOL success = YES;
|
|
374
|
+
NSString *sql = @"UPDATE " @LC_TABLE_NAME
|
|
375
|
+
@" SET " @LC_COLUMN_NAME_STATUS @" = ? "
|
|
376
|
+
@" WHERE " @LC_COLUMN_NAME_STATUS @" = ? AND " @LC_COLUMN_NAME_RECORDED_AT @" < ?";
|
|
377
|
+
[queue inDatabase:^(FMDatabase *database) {
|
|
378
|
+
if (![database executeUpdate:sql,
|
|
379
|
+
@(MAURLocationPostPending),
|
|
380
|
+
@(MAURLocationSyncPending),
|
|
381
|
+
@(cutoff)]) {
|
|
382
|
+
int errorCode = [database lastErrorCode];
|
|
383
|
+
NSString *errorMessage = [database lastErrorMessage];
|
|
384
|
+
NSLog(@"restoreStaleSyncLocations failed code: %d: message: %@", errorCode, errorMessage);
|
|
385
|
+
if (outError != NULL) {
|
|
386
|
+
*outError = [NSError errorWithDomain:Domain code:errorCode userInfo:@{ NSLocalizedDescriptionKey: errorMessage ?: @"" }];
|
|
387
|
+
}
|
|
388
|
+
success = NO;
|
|
389
|
+
}
|
|
390
|
+
}];
|
|
391
|
+
return success;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
- (BOOL) restoreFailedSyncLocations:(NSError * __autoreleasing *)outError
|
|
395
|
+
{
|
|
396
|
+
// v4.5.1 — undo the in-flight transition: SyncPending → PostPending so the next sync window
|
|
397
|
+
// (or real-time post) re-tries them.
|
|
398
|
+
__block BOOL success = YES;
|
|
399
|
+
NSString *sql = @"UPDATE " @LC_TABLE_NAME @" SET " @LC_COLUMN_NAME_STATUS @" = ? WHERE " @LC_COLUMN_NAME_STATUS @" = ?";
|
|
400
|
+
[queue inDatabase:^(FMDatabase *database) {
|
|
401
|
+
if (![database executeUpdate:sql, @(MAURLocationPostPending), @(MAURLocationSyncPending)]) {
|
|
402
|
+
int errorCode = [database lastErrorCode];
|
|
403
|
+
NSString *errorMessage = [database lastErrorMessage];
|
|
404
|
+
NSLog(@"restoreFailedSyncLocations failed code: %d: message: %@", errorCode, errorMessage);
|
|
405
|
+
if (outError != NULL) {
|
|
406
|
+
*outError = [NSError errorWithDomain:Domain code:errorCode userInfo:@{ NSLocalizedDescriptionKey: errorMessage ?: @"" }];
|
|
407
|
+
}
|
|
408
|
+
success = NO;
|
|
409
|
+
}
|
|
410
|
+
}];
|
|
411
|
+
return success;
|
|
412
|
+
}
|
|
413
|
+
|
|
307
414
|
- (BOOL) deletePendingSyncLocations:(NSError * __autoreleasing *)outError
|
|
308
415
|
{
|
|
309
416
|
__block BOOL success = YES;
|
|
@@ -368,6 +475,9 @@
|
|
|
368
475
|
@COMMA_SEP @LC_COLUMN_NAME_LOCATION_PROVIDER
|
|
369
476
|
@COMMA_SEP @LC_COLUMN_NAME_STATUS
|
|
370
477
|
@COMMA_SEP @LC_COLUMN_NAME_RECORDED_AT
|
|
478
|
+
@COMMA_SEP @LC_COLUMN_NAME_EVENTS_JSON
|
|
479
|
+
@COMMA_SEP @LC_COLUMN_NAME_BATTERY_LEVEL
|
|
480
|
+
@COMMA_SEP @LC_COLUMN_NAME_IS_CHARGING
|
|
371
481
|
@" FROM " @LC_TABLE_NAME;
|
|
372
482
|
}
|
|
373
483
|
|
|
@@ -387,6 +497,16 @@
|
|
|
387
497
|
location.isValid = [rs intForColumnIndex:10] == 1 ? YES : NO;
|
|
388
498
|
NSTimeInterval recordedAt = [rs longForColumnIndex:11];
|
|
389
499
|
location.recordedAt = [NSDate dateWithTimeIntervalSince1970:recordedAt];
|
|
500
|
+
// v4.5: events / battery / charging
|
|
501
|
+
NSString *eventsJson = [rs stringForColumnIndex:12];
|
|
502
|
+
if (eventsJson != nil && eventsJson.length > 0) {
|
|
503
|
+
NSError *jerr = nil;
|
|
504
|
+
id parsed = [NSJSONSerialization JSONObjectWithData:[eventsJson dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:&jerr];
|
|
505
|
+
if ([parsed isKindOfClass:[NSMutableArray class]]) location.drivingEvents = parsed;
|
|
506
|
+
else if ([parsed isKindOfClass:[NSArray class]]) location.drivingEvents = [parsed mutableCopy];
|
|
507
|
+
}
|
|
508
|
+
if (![rs columnIndexIsNull:13]) location.batteryLevel = @([rs intForColumnIndex:13]);
|
|
509
|
+
if (![rs columnIndexIsNull:14]) location.isCharging = @([rs intForColumnIndex:14] == 1);
|
|
390
510
|
return location;
|
|
391
511
|
}
|
|
392
512
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@josuelmm/cordova-background-geolocation",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.5.1",
|
|
4
4
|
"description": "Cordova Background Geolocation (fork actualizado)",
|
|
5
5
|
"main": "./www/BackgroundGeolocation.js",
|
|
6
6
|
"types": "./www/BackgroundGeolocation.d.ts",
|
|
@@ -104,6 +104,41 @@
|
|
|
104
104
|
"cordova": ">=10.0.0",
|
|
105
105
|
"cordova-android": ">=12.0.0",
|
|
106
106
|
"cordova-ios": ">=6.2.0"
|
|
107
|
+
},
|
|
108
|
+
"4.2.3": {
|
|
109
|
+
"cordova": ">=10.0.0",
|
|
110
|
+
"cordova-android": ">=12.0.0",
|
|
111
|
+
"cordova-ios": ">=6.2.0"
|
|
112
|
+
},
|
|
113
|
+
"4.2.4": {
|
|
114
|
+
"cordova": ">=10.0.0",
|
|
115
|
+
"cordova-android": ">=12.0.0",
|
|
116
|
+
"cordova-ios": ">=6.2.0"
|
|
117
|
+
},
|
|
118
|
+
"4.3.0": {
|
|
119
|
+
"cordova": ">=10.0.0",
|
|
120
|
+
"cordova-android": ">=12.0.0",
|
|
121
|
+
"cordova-ios": ">=6.2.0"
|
|
122
|
+
},
|
|
123
|
+
"4.4.0": {
|
|
124
|
+
"cordova": ">=10.0.0",
|
|
125
|
+
"cordova-android": ">=12.0.0",
|
|
126
|
+
"cordova-ios": ">=6.2.0"
|
|
127
|
+
},
|
|
128
|
+
"4.4.1": {
|
|
129
|
+
"cordova": ">=10.0.0",
|
|
130
|
+
"cordova-android": ">=12.0.0",
|
|
131
|
+
"cordova-ios": ">=6.2.0"
|
|
132
|
+
},
|
|
133
|
+
"4.5.0": {
|
|
134
|
+
"cordova": ">=10.0.0",
|
|
135
|
+
"cordova-android": ">=12.0.0",
|
|
136
|
+
"cordova-ios": ">=6.2.0"
|
|
137
|
+
},
|
|
138
|
+
"4.5.1": {
|
|
139
|
+
"cordova": ">=10.0.0",
|
|
140
|
+
"cordova-android": ">=12.0.0",
|
|
141
|
+
"cordova-ios": ">=6.2.0"
|
|
107
142
|
}
|
|
108
143
|
}
|
|
109
144
|
},
|
package/plugin.xml
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0"
|
|
3
3
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
4
4
|
id="cordova-background-geolocation"
|
|
5
|
-
version="4.
|
|
5
|
+
version="4.5.1">
|
|
6
6
|
<name>cordova-background-geolocation</name>
|
|
7
7
|
<description>Cordova Background Geolocation Plugin</description>
|
|
8
8
|
<license>Apache-2.0</license>
|
|
@@ -59,6 +59,7 @@
|
|
|
59
59
|
<source-file src="android/common/src/main/java/com/marianhello/bgloc/data/BackgroundActivity.java" target-dir="src/com/marianhello/bgloc/data" />
|
|
60
60
|
<source-file src="android/common/src/main/java/com/marianhello/bgloc/data/BackgroundLocation.java" target-dir="src/com/marianhello/bgloc/data" />
|
|
61
61
|
<source-file src="android/common/src/main/java/com/marianhello/bgloc/data/ConfigurationDAO.java" target-dir="src/com/marianhello/bgloc/data" />
|
|
62
|
+
<source-file src="android/common/src/main/java/com/marianhello/bgloc/data/ConfigJsonMapper.java" target-dir="src/com/marianhello/bgloc/data" />
|
|
62
63
|
<source-file src="android/common/src/main/java/com/marianhello/bgloc/data/DAOFactory.java" target-dir="src/com/marianhello/bgloc/data" />
|
|
63
64
|
<source-file src="android/common/src/main/java/com/marianhello/bgloc/data/HashMapLocationTemplate.java" target-dir="src/com/marianhello/bgloc/data" />
|
|
64
65
|
<source-file src="android/common/src/main/java/com/marianhello/bgloc/data/LocationDAO.java" target-dir="src/com/marianhello/bgloc/data" />
|
|
@@ -196,7 +197,7 @@
|
|
|
196
197
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
|
197
198
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
|
198
199
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
|
|
199
|
-
<uses-
|
|
200
|
+
<uses-feature android:name="android.hardware.location" android:required="false" />
|
|
200
201
|
</config-file>
|
|
201
202
|
<config-file target="res/xml/config.xml" parent="/*">
|
|
202
203
|
<feature name="BackgroundGeolocation">
|
|
@@ -153,7 +153,7 @@ export interface ConfigureOptions {
|
|
|
153
153
|
* Platform: Android
|
|
154
154
|
* Provider: all
|
|
155
155
|
*
|
|
156
|
-
* @default
|
|
156
|
+
* @default 600000
|
|
157
157
|
* @see {@link https://bit.ly/1x00RUu|Android docs}
|
|
158
158
|
*/
|
|
159
159
|
interval?: number;
|
|
@@ -510,6 +510,52 @@ export interface ConfigureOptions {
|
|
|
510
510
|
*/
|
|
511
511
|
mockLocationPolicy?: 'allow' | 'flag' | 'drop';
|
|
512
512
|
|
|
513
|
+
/**
|
|
514
|
+
* v4.4 — Stamp device battery percentage (0-100) and charging state on every location
|
|
515
|
+
* sent to the backend. Default `true`. Set `false` to opt out.
|
|
516
|
+
*
|
|
517
|
+
* - With `bodyTemplate`/`postTemplate`, use placeholders `'@battery'` and `'@isCharging'`.
|
|
518
|
+
* - Default JSON includes `battery` and `isCharging` keys automatically.
|
|
519
|
+
*
|
|
520
|
+
* Android: read via `BatteryManager` sticky broadcast (no permission required).
|
|
521
|
+
* iOS: read via `UIDevice.batteryLevel` (free).
|
|
522
|
+
*
|
|
523
|
+
* Platform: Android, iOS
|
|
524
|
+
* @since 4.4.0
|
|
525
|
+
*/
|
|
526
|
+
includeBattery?: boolean;
|
|
527
|
+
|
|
528
|
+
/**
|
|
529
|
+
* v4.5.1 — WakeLock policy (Android only). Controls whether the service holds a
|
|
530
|
+
* `PARTIAL_WAKE_LOCK` while tracking. Default `'posting'`.
|
|
531
|
+
*
|
|
532
|
+
* - `'none'` — never acquire a wake lock. Best battery, but the device may
|
|
533
|
+
* sleep mid-POST. Recommended only with `httpMode: 'batch'`.
|
|
534
|
+
* - `'posting'` — acquire a 30 s wake lock on every fix while writing to SQLite
|
|
535
|
+
* and posting. Default. Good battery / reliability trade-off.
|
|
536
|
+
* - `'always'` — keep CPU awake the whole time the service is running. Most
|
|
537
|
+
* reliable, worst battery. Use only for fleet/emergency apps.
|
|
538
|
+
*
|
|
539
|
+
* @platform Android
|
|
540
|
+
* @since 4.5.1
|
|
541
|
+
*/
|
|
542
|
+
wakeLockMode?: 'none' | 'posting' | 'always';
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* v4.5.1 — Stationary detection knobs (Android `DISTANCE_FILTER_PROVIDER`).
|
|
546
|
+
* Override the previously hard-coded constants. All values in milliseconds.
|
|
547
|
+
*
|
|
548
|
+
* - `stationaryTimeout` (default 300_000) — time of no movement before declaring stationary.
|
|
549
|
+
* - `stationaryPollInterval` (default 180_000) — lazy poll while stationary.
|
|
550
|
+
* - `stationaryPollFast` (default 60_000) — aggressive poll near boundary.
|
|
551
|
+
*
|
|
552
|
+
* @platform Android
|
|
553
|
+
* @since 4.5.1
|
|
554
|
+
*/
|
|
555
|
+
stationaryTimeout?: number;
|
|
556
|
+
stationaryPollInterval?: number;
|
|
557
|
+
stationaryPollFast?: number;
|
|
558
|
+
|
|
513
559
|
/**
|
|
514
560
|
* v4.0 Phase 6 — Driver insights configuration. Enables a GPS-based state machine
|
|
515
561
|
* that emits `moving`, `stopped`, `tripStart`, `tripEnd`, `speeding` and
|
|
@@ -643,6 +689,31 @@ export interface Location {
|
|
|
643
689
|
* True if location was simulated by software (e.g. Simulator). (iOS 15+)
|
|
644
690
|
*/
|
|
645
691
|
simulated?: boolean;
|
|
692
|
+
|
|
693
|
+
/**
|
|
694
|
+
* v4.3 — Driving events anexados a este fix por el detector interno.
|
|
695
|
+
*
|
|
696
|
+
* Solo presente cuando un evento se disparó al mismo tiempo que esta location y
|
|
697
|
+
* `drivingEvents.enabled` está activo. Cada elemento es `{ type, time, ...payload }`,
|
|
698
|
+
* donde `payload` depende del tipo:
|
|
699
|
+
* - hardBrake / rapidAcceleration / sharpTurn → `value: number`
|
|
700
|
+
* - speeding → `speedKmh: number, limitKmh: number`
|
|
701
|
+
* - tripEnd → `distance: number, durationMs: number`
|
|
702
|
+
* - possibleCrash → `value: number, source: 'gps' | 'sensor'`
|
|
703
|
+
* - providerChange → `provider: string`
|
|
704
|
+
* - moving / stopped / tripStart / phoneUsageWhileDriving → solo type+time.
|
|
705
|
+
*
|
|
706
|
+
* Desde v4.5.0, `events` se persiste en la cola de sync y sobrevive a POST fallidos.
|
|
707
|
+
*
|
|
708
|
+
* @since 4.3.0
|
|
709
|
+
*/
|
|
710
|
+
events?: Array<{ type: string; time: number; [key: string]: any }>;
|
|
711
|
+
|
|
712
|
+
/** v4.4 — Device battery percentage (0-100) at the time of the fix. Disabled with
|
|
713
|
+
* `includeBattery: false` in ConfigureOptions. @since 4.4.0 */
|
|
714
|
+
battery?: number;
|
|
715
|
+
/** v4.4 — Whether the device is charging at the time of the fix. @since 4.4.0 */
|
|
716
|
+
isCharging?: boolean;
|
|
646
717
|
}
|
|
647
718
|
|
|
648
719
|
export interface StationaryLocation extends Location {
|
|
@@ -972,6 +1043,39 @@ export interface BackgroundGeolocationPlugin {
|
|
|
972
1043
|
fail?: (error: BackgroundGeolocationError) => void
|
|
973
1044
|
): Promise<void>;
|
|
974
1045
|
|
|
1046
|
+
/**
|
|
1047
|
+
* v4.5 — Request `ACCESS_BACKGROUND_LOCATION` runtime permission (Android 10+).
|
|
1048
|
+
* On Android < 10 resolves immediately as `{ granted: true, notRequired: true }`.
|
|
1049
|
+
* On iOS resolves as `{ granted: true, notRequired: true }` (Apple does not surface
|
|
1050
|
+
* a separate background permission — the standard "Always" authorization covers it).
|
|
1051
|
+
* @since 4.5.0
|
|
1052
|
+
*/
|
|
1053
|
+
requestBackgroundLocationPermission(
|
|
1054
|
+
success?: (result: { granted: boolean; denied?: string[]; notRequired?: boolean }) => void,
|
|
1055
|
+
fail?: (error: BackgroundGeolocationError) => void
|
|
1056
|
+
): Promise<{ granted: boolean; denied?: string[]; notRequired?: boolean }>;
|
|
1057
|
+
|
|
1058
|
+
/**
|
|
1059
|
+
* v4.5 — Request `ACTIVITY_RECOGNITION` runtime permission (Android 10+).
|
|
1060
|
+
* Required by `ActivityLocationProvider`. iOS / Android < 10 resolve `granted: true, notRequired`.
|
|
1061
|
+
* @since 4.5.0
|
|
1062
|
+
*/
|
|
1063
|
+
requestActivityRecognitionPermission(
|
|
1064
|
+
success?: (result: { granted: boolean; denied?: string[]; notRequired?: boolean }) => void,
|
|
1065
|
+
fail?: (error: BackgroundGeolocationError) => void
|
|
1066
|
+
): Promise<{ granted: boolean; denied?: string[]; notRequired?: boolean }>;
|
|
1067
|
+
|
|
1068
|
+
/**
|
|
1069
|
+
* v4.5 — Request `POST_NOTIFICATIONS` runtime permission (Android 13+).
|
|
1070
|
+
* Without it the foreground-service notification is invisible. iOS / Android < 13
|
|
1071
|
+
* resolve `granted: true, notRequired`.
|
|
1072
|
+
* @since 4.5.0
|
|
1073
|
+
*/
|
|
1074
|
+
requestNotificationPermission(
|
|
1075
|
+
success?: (result: { granted: boolean; denied?: string[]; notRequired?: boolean }) => void,
|
|
1076
|
+
fail?: (error: BackgroundGeolocationError) => void
|
|
1077
|
+
): Promise<{ granted: boolean; denied?: string[]; notRequired?: boolean }>;
|
|
1078
|
+
|
|
975
1079
|
/**
|
|
976
1080
|
* Show app settings to allow change of app location permissions.
|
|
977
1081
|
*
|
|
@@ -1245,13 +1349,20 @@ export interface BackgroundGeolocationPlugin {
|
|
|
1245
1349
|
): Promise<void>;
|
|
1246
1350
|
|
|
1247
1351
|
/**
|
|
1248
|
-
* A special task that gets executed when the app is terminated,
|
|
1249
|
-
* the plugin was configured to continue running in the background
|
|
1352
|
+
* **Android only.** A special task that gets executed when the app is terminated,
|
|
1353
|
+
* but the plugin was configured to continue running in the background
|
|
1250
1354
|
* (option <code>stopOnTerminate: false</code>).
|
|
1251
1355
|
*
|
|
1252
1356
|
* In this scenario the Activity was killed by the system and all registered
|
|
1253
1357
|
* event listeners will not be triggered until the app is relaunched.
|
|
1254
1358
|
*
|
|
1359
|
+
* **iOS:** Apple does not support running JS in a killed-app scenario the same
|
|
1360
|
+
* way; on iOS this method is a no-op. Use `significantLocationChanges` and the
|
|
1361
|
+
* normal `BackgroundGeolocation.on(...)` listeners with the standard background
|
|
1362
|
+
* location mode instead.
|
|
1363
|
+
*
|
|
1364
|
+
* Platform: Android
|
|
1365
|
+
*
|
|
1255
1366
|
* @example
|
|
1256
1367
|
* BackgroundGeolocation.headlessTask(function(event) {
|
|
1257
1368
|
*
|