@josuelmm/capacitor-background-geolocation 1.0.0
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/JosuelmmCapacitorBackgroundGeolocation.podspec +34 -0
- package/LICENSE +17 -0
- package/NOTICE.md +32 -0
- package/Package.swift +45 -0
- package/README.md +402 -0
- package/android/build.gradle +79 -0
- package/android/proguard-rules.pro +1 -0
- package/android/src/main/AndroidManifest.xml +83 -0
- package/android/src/main/java/com/evgenii/jsevaluator/HandlerWrapper.java +18 -0
- package/android/src/main/java/com/evgenii/jsevaluator/JavaScriptInterface.java +22 -0
- package/android/src/main/java/com/evgenii/jsevaluator/JsEvaluator.java +133 -0
- package/android/src/main/java/com/evgenii/jsevaluator/JsFunctionCallFormatter.java +37 -0
- package/android/src/main/java/com/evgenii/jsevaluator/WebViewWrapper.java +71 -0
- package/android/src/main/java/com/evgenii/jsevaluator/interfaces/CallJavaResultInterface.java +8 -0
- package/android/src/main/java/com/evgenii/jsevaluator/interfaces/HandlerWrapperInterface.java +5 -0
- package/android/src/main/java/com/evgenii/jsevaluator/interfaces/JsCallback.java +10 -0
- package/android/src/main/java/com/evgenii/jsevaluator/interfaces/JsEvaluatorInterface.java +18 -0
- package/android/src/main/java/com/evgenii/jsevaluator/interfaces/WebViewWrapperInterface.java +14 -0
- package/android/src/main/java/com/josuelmm/capacitor/backgroundgeolocation/BackgroundGeolocationPlugin.java +898 -0
- package/android/src/main/java/com/josuelmm/capacitor/backgroundgeolocation/ConfigMapper.java +303 -0
- package/android/src/main/java/com/josuelmm/capacitor/backgroundgeolocation/HeadlessTaskRegistry.java +34 -0
- package/android/src/main/java/com/josuelmm/capacitor/backgroundgeolocation/JsEvaluatorTaskRunner.java +63 -0
- package/android/src/main/java/com/marianhello/bgloc/BackgroundGeolocationFacade.java +699 -0
- package/android/src/main/java/com/marianhello/bgloc/BootCompletedReceiver.java +103 -0
- package/android/src/main/java/com/marianhello/bgloc/Config.java +1155 -0
- package/android/src/main/java/com/marianhello/bgloc/ConnectivityListener.java +5 -0
- package/android/src/main/java/com/marianhello/bgloc/HttpPostService.java +362 -0
- package/android/src/main/java/com/marianhello/bgloc/LocationManager.java +138 -0
- package/android/src/main/java/com/marianhello/bgloc/PluginDelegate.java +45 -0
- package/android/src/main/java/com/marianhello/bgloc/PluginException.java +38 -0
- package/android/src/main/java/com/marianhello/bgloc/PostLocationTask.java +238 -0
- package/android/src/main/java/com/marianhello/bgloc/ResourceResolver.java +55 -0
- package/android/src/main/java/com/marianhello/bgloc/data/AbstractLocationTemplate.java +69 -0
- package/android/src/main/java/com/marianhello/bgloc/data/ArrayListLocationTemplate.java +88 -0
- package/android/src/main/java/com/marianhello/bgloc/data/BackgroundActivity.java +108 -0
- package/android/src/main/java/com/marianhello/bgloc/data/BackgroundLocation.java +1088 -0
- package/android/src/main/java/com/marianhello/bgloc/data/ConfigJsonMapper.java +211 -0
- package/android/src/main/java/com/marianhello/bgloc/data/ConfigurationDAO.java +13 -0
- package/android/src/main/java/com/marianhello/bgloc/data/DAOFactory.java +17 -0
- package/android/src/main/java/com/marianhello/bgloc/data/HashMapLocationTemplate.java +82 -0
- package/android/src/main/java/com/marianhello/bgloc/data/LocationDAO.java +27 -0
- package/android/src/main/java/com/marianhello/bgloc/data/LocationTemplate.java +12 -0
- package/android/src/main/java/com/marianhello/bgloc/data/LocationTemplateFactory.java +71 -0
- package/android/src/main/java/com/marianhello/bgloc/data/LocationTransform.java +19 -0
- package/android/src/main/java/com/marianhello/bgloc/data/SessionLocationDAO.java +18 -0
- package/android/src/main/java/com/marianhello/bgloc/data/provider/ContentProviderLocationDAO.java +406 -0
- package/android/src/main/java/com/marianhello/bgloc/data/provider/LocationContentProvider.java +321 -0
- package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteConfigurationContract.java +94 -0
- package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteConfigurationDAO.java +227 -0
- package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteLocationContract.java +122 -0
- package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteLocationDAO.java +550 -0
- package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteOpenHelper.java +189 -0
- package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteSessionContract.java +74 -0
- package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteSessionLocationDAO.java +169 -0
- package/android/src/main/java/com/marianhello/bgloc/driving/DrivingEventsDetector.java +265 -0
- package/android/src/main/java/com/marianhello/bgloc/headless/AbstractTaskRunner.java +15 -0
- package/android/src/main/java/com/marianhello/bgloc/headless/ActivityTask.java +48 -0
- package/android/src/main/java/com/marianhello/bgloc/headless/JsCallback.java +10 -0
- package/android/src/main/java/com/marianhello/bgloc/headless/LocationTask.java +60 -0
- package/android/src/main/java/com/marianhello/bgloc/headless/StationaryTask.java +25 -0
- package/android/src/main/java/com/marianhello/bgloc/headless/Task.java +8 -0
- package/android/src/main/java/com/marianhello/bgloc/headless/TaskRunner.java +5 -0
- package/android/src/main/java/com/marianhello/bgloc/headless/TaskRunnerFactory.java +8 -0
- package/android/src/main/java/com/marianhello/bgloc/http/UrlTemplateResolver.java +115 -0
- package/android/src/main/java/com/marianhello/bgloc/oem/BatteryOemHelper.java +214 -0
- package/android/src/main/java/com/marianhello/bgloc/provider/AbstractLocationProvider.java +218 -0
- package/android/src/main/java/com/marianhello/bgloc/provider/ActivityRecognitionLocationProvider.java +385 -0
- package/android/src/main/java/com/marianhello/bgloc/provider/DistanceFilterLocationProvider.java +685 -0
- package/android/src/main/java/com/marianhello/bgloc/provider/LocationProvider.java +32 -0
- package/android/src/main/java/com/marianhello/bgloc/provider/LocationProviderFactory.java +47 -0
- package/android/src/main/java/com/marianhello/bgloc/provider/ProviderDelegate.java +12 -0
- package/android/src/main/java/com/marianhello/bgloc/provider/RawLocationProvider.java +175 -0
- package/android/src/main/java/com/marianhello/bgloc/sensor/SensorFusionDetector.java +199 -0
- package/android/src/main/java/com/marianhello/bgloc/service/LocationService.java +16 -0
- package/android/src/main/java/com/marianhello/bgloc/service/LocationServiceImpl.java +1531 -0
- package/android/src/main/java/com/marianhello/bgloc/service/LocationServiceInfo.java +6 -0
- package/android/src/main/java/com/marianhello/bgloc/service/LocationServiceInfoImpl.java +41 -0
- package/android/src/main/java/com/marianhello/bgloc/service/LocationServiceIntentBuilder.java +203 -0
- package/android/src/main/java/com/marianhello/bgloc/service/LocationServiceProxy.java +156 -0
- package/android/src/main/java/com/marianhello/bgloc/sync/AccountHelper.java +39 -0
- package/android/src/main/java/com/marianhello/bgloc/sync/Authenticator.java +68 -0
- package/android/src/main/java/com/marianhello/bgloc/sync/AuthenticatorService.java +28 -0
- package/android/src/main/java/com/marianhello/bgloc/sync/BatchManager.java +311 -0
- package/android/src/main/java/com/marianhello/bgloc/sync/NotificationHelper.java +148 -0
- package/android/src/main/java/com/marianhello/bgloc/sync/SyncAdapter.java +301 -0
- package/android/src/main/java/com/marianhello/bgloc/sync/SyncService.java +68 -0
- package/android/src/main/java/com/marianhello/logging/DBLogReader.java +208 -0
- package/android/src/main/java/com/marianhello/logging/LogEntry.java +99 -0
- package/android/src/main/java/com/marianhello/logging/LoggerManager.java +70 -0
- package/android/src/main/java/com/marianhello/logging/UncaughtExceptionLogger.java +36 -0
- package/android/src/main/java/com/marianhello/utils/CloneHelper.java +22 -0
- package/android/src/main/java/com/marianhello/utils/Convert.java +56 -0
- package/android/src/main/java/com/marianhello/utils/TextUtils.java +72 -0
- package/android/src/main/java/com/marianhello/utils/ToneGenerator.java +68 -0
- package/android/src/main/java/org/apache/commons/io/Charsets.java +153 -0
- package/android/src/main/java/org/apache/commons/io/input/ReversedLinesFileReader.java +344 -0
- package/android/src/main/java/org/chromium/content/browser/ThreadUtils.java +134 -0
- package/android/src/main/java/ru/andremoniy/sqlbuilder/SqlExpression.java +398 -0
- package/android/src/main/java/ru/andremoniy/sqlbuilder/SqlSelectStatement.java +671 -0
- package/android/src/main/java/ru/andremoniy/sqlbuilder/SqlStatement.java +29 -0
- package/android/src/main/java/ru/andremoniy/utils/TextUtils.java +61 -0
- package/android/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
- package/android/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
- package/android/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
- package/android/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/android/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/android/src/main/res/values/strings.xml +15 -0
- package/android/src/main/res/xml/authenticator.xml +7 -0
- package/android/src/main/res/xml/syncadapter.xml +9 -0
- package/dist/esm/definitions.d.ts +1052 -0
- package/dist/esm/definitions.js +142 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +8 -0
- package/dist/esm/index.js +23 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +92 -0
- package/dist/esm/web.js +242 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +415 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +418 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Sources/BackgroundGeolocationPlugin/BackgroundGeolocationPlugin-Bridging-Header.h +18 -0
- package/ios/Sources/BackgroundGeolocationPlugin/BackgroundGeolocationPlugin.m +52 -0
- package/ios/Sources/BackgroundGeolocationPlugin/BackgroundGeolocationPlugin.swift +750 -0
- package/ios/Tests/BackgroundGeolocationPluginTests/BackgroundGeolocationPluginTests.swift +12 -0
- package/ios/common/BackgroundGeolocation/CocoaLumberjack.h +1945 -0
- package/ios/common/BackgroundGeolocation/CocoaLumberjack.m +5255 -0
- package/ios/common/BackgroundGeolocation/FMDB.h +2357 -0
- package/ios/common/BackgroundGeolocation/FMDB.m +2672 -0
- package/ios/common/BackgroundGeolocation/FMDBLogger.h +42 -0
- package/ios/common/BackgroundGeolocation/FMDBLogger.m +264 -0
- package/ios/common/BackgroundGeolocation/INTULocationManager/INTUHeadingRequest.h +41 -0
- package/ios/common/BackgroundGeolocation/INTULocationManager/INTUHeadingRequest.m +68 -0
- package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationManager+Internal.h +33 -0
- package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationManager.h +178 -0
- package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationManager.m +1025 -0
- package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationRequest.h +103 -0
- package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationRequest.m +238 -0
- package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationRequestDefines.h +163 -0
- package/ios/common/BackgroundGeolocation/INTULocationManager/INTURequestIDGenerator.h +39 -0
- package/ios/common/BackgroundGeolocation/INTULocationManager/INTURequestIDGenerator.m +37 -0
- package/ios/common/BackgroundGeolocation/MAURAbstractLocationProvider.h +51 -0
- package/ios/common/BackgroundGeolocation/MAURAbstractLocationProvider.m +53 -0
- package/ios/common/BackgroundGeolocation/MAURActivity.h +23 -0
- package/ios/common/BackgroundGeolocation/MAURActivity.m +52 -0
- package/ios/common/BackgroundGeolocation/MAURActivityLocationProvider.h +18 -0
- package/ios/common/BackgroundGeolocation/MAURActivityLocationProvider.m +340 -0
- package/ios/common/BackgroundGeolocation/MAURBackgroundGeolocationFacade.h +88 -0
- package/ios/common/BackgroundGeolocation/MAURBackgroundGeolocationFacade.m +1193 -0
- package/ios/common/BackgroundGeolocation/MAURBackgroundSync.h +46 -0
- package/ios/common/BackgroundGeolocation/MAURBackgroundSync.m +283 -0
- package/ios/common/BackgroundGeolocation/MAURBackgroundTaskManager.h +25 -0
- package/ios/common/BackgroundGeolocation/MAURBackgroundTaskManager.m +105 -0
- package/ios/common/BackgroundGeolocation/MAURConfig.h +99 -0
- package/ios/common/BackgroundGeolocation/MAURConfig.m +636 -0
- package/ios/common/BackgroundGeolocation/MAURConfigurationContract.h +53 -0
- package/ios/common/BackgroundGeolocation/MAURConfigurationContract.m +54 -0
- package/ios/common/BackgroundGeolocation/MAURDistanceFilterLocationProvider.h +20 -0
- package/ios/common/BackgroundGeolocation/MAURDistanceFilterLocationProvider.m +550 -0
- package/ios/common/BackgroundGeolocation/MAURGeolocationOpenHelper.h +17 -0
- package/ios/common/BackgroundGeolocation/MAURGeolocationOpenHelper.m +124 -0
- package/ios/common/BackgroundGeolocation/MAURLocation.h +73 -0
- package/ios/common/BackgroundGeolocation/MAURLocation.m +392 -0
- package/ios/common/BackgroundGeolocation/MAURLocationContract.h +38 -0
- package/ios/common/BackgroundGeolocation/MAURLocationContract.m +39 -0
- package/ios/common/BackgroundGeolocation/MAURLocationManager.h +53 -0
- package/ios/common/BackgroundGeolocation/MAURLocationManager.m +305 -0
- package/ios/common/BackgroundGeolocation/MAURLogReader.h +26 -0
- package/ios/common/BackgroundGeolocation/MAURLogReader.m +122 -0
- package/ios/common/BackgroundGeolocation/MAURLogging.h +19 -0
- package/ios/common/BackgroundGeolocation/MAURPostLocationTask.h +53 -0
- package/ios/common/BackgroundGeolocation/MAURPostLocationTask.m +367 -0
- package/ios/common/BackgroundGeolocation/MAURProviderDelegate.h +52 -0
- package/ios/common/BackgroundGeolocation/MAURRawLocationProvider.h +18 -0
- package/ios/common/BackgroundGeolocation/MAURRawLocationProvider.m +138 -0
- package/ios/common/BackgroundGeolocation/MAURSQLiteConfigurationDAO.h +26 -0
- package/ios/common/BackgroundGeolocation/MAURSQLiteConfigurationDAO.m +335 -0
- package/ios/common/BackgroundGeolocation/MAURSQLiteHelper.h +57 -0
- package/ios/common/BackgroundGeolocation/MAURSQLiteHelper.m +93 -0
- package/ios/common/BackgroundGeolocation/MAURSQLiteLocationDAO.h +52 -0
- package/ios/common/BackgroundGeolocation/MAURSQLiteLocationDAO.m +520 -0
- package/ios/common/BackgroundGeolocation/MAURSQLiteOpenHelper.h +32 -0
- package/ios/common/BackgroundGeolocation/MAURSQLiteOpenHelper.m +276 -0
- package/ios/common/BackgroundGeolocation/MAURSensorFusionDetector.h +41 -0
- package/ios/common/BackgroundGeolocation/MAURSensorFusionDetector.m +137 -0
- package/ios/common/BackgroundGeolocation/MAURSessionLocationContract.h +29 -0
- package/ios/common/BackgroundGeolocation/MAURSessionLocationContract.m +31 -0
- package/ios/common/BackgroundGeolocation/MAURSessionLocationDAO.h +25 -0
- package/ios/common/BackgroundGeolocation/MAURSessionLocationDAO.m +153 -0
- package/ios/common/BackgroundGeolocation/MAURUncaughtExceptionLogger.h +20 -0
- package/ios/common/BackgroundGeolocation/MAURUncaughtExceptionLogger.m +62 -0
- package/ios/common/BackgroundGeolocation/MAURUrlTemplateResolver.h +31 -0
- package/ios/common/BackgroundGeolocation/MAURUrlTemplateResolver.m +107 -0
- package/ios/common/BackgroundGeolocation/Reachability.h +102 -0
- package/ios/common/BackgroundGeolocation/Reachability.m +475 -0
- package/ios/common/BackgroundGeolocation/SQLQueryBuilder/README.md +170 -0
- package/ios/common/BackgroundGeolocation/SQLQueryBuilder/ext/NSString+ZIMString.h +55 -0
- package/ios/common/BackgroundGeolocation/SQLQueryBuilder/ext/NSString+ZIMString.m +47 -0
- package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlDataManipulationCommand.h +27 -0
- package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlExpression.h +250 -0
- package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlExpression.m +259 -0
- package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlSelectStatement.h +360 -0
- package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlSelectStatement.m +427 -0
- package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlStatement.h +37 -0
- package/ios/common/BackgroundGeolocation/module.modulemap +16 -0
- package/package.json +82 -0
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
//
|
|
2
|
+
// MAURSQLiteOpenHelper.m
|
|
3
|
+
//
|
|
4
|
+
// Created by Marian Hello on 22/06/16.
|
|
5
|
+
//
|
|
6
|
+
|
|
7
|
+
#import <Foundation/Foundation.h>
|
|
8
|
+
#import <sqlite3.h>
|
|
9
|
+
#import "MAURSQLiteHelper.h"
|
|
10
|
+
#import "MAURSQLiteOpenHelper.h"
|
|
11
|
+
|
|
12
|
+
@implementation MAURSQLiteOpenHelper {
|
|
13
|
+
FMDatabaseQueue *mQueue;
|
|
14
|
+
BOOL mIsInitializing;
|
|
15
|
+
BOOL mIsReadOnly;
|
|
16
|
+
NSInteger mNewVersion; // REMARK: never use mNewVersion < 1 in your subclasses
|
|
17
|
+
NSString* mName;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
static NSString *const metaTableName = @"__META";
|
|
21
|
+
static int const OPEN_READONLY = SQLITE_OPEN_READONLY|SQLITE_OPEN_FULLMUTEX;
|
|
22
|
+
static int const OPEN_READWRITE = SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE|SQLITE_OPEN_FULLMUTEX;
|
|
23
|
+
|
|
24
|
+
- (instancetype)init:(NSString*)name version:(NSInteger)version
|
|
25
|
+
{
|
|
26
|
+
self = [super init];
|
|
27
|
+
if (self) {
|
|
28
|
+
self->mName = name;
|
|
29
|
+
self->mNewVersion = version;
|
|
30
|
+
}
|
|
31
|
+
return self;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
- (FMDatabaseQueue*) getReadableDatabase
|
|
35
|
+
{
|
|
36
|
+
|
|
37
|
+
@synchronized(self) {
|
|
38
|
+
return [self getDatabaseLocked: NO];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
- (FMDatabaseQueue*) getWritableDatabase
|
|
43
|
+
{
|
|
44
|
+
@synchronized(self) {
|
|
45
|
+
return [self getDatabaseLocked: YES];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
- (FMDatabaseQueue*) getDatabaseLocked:(BOOL)writable
|
|
50
|
+
{
|
|
51
|
+
if (mQueue != nil) {
|
|
52
|
+
// TODO: add check if db was closed by user
|
|
53
|
+
return mQueue;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (mIsInitializing) {
|
|
57
|
+
@throw [NSException exceptionWithName:NSInternalInconsistencyException
|
|
58
|
+
reason:[NSString stringWithFormat:@"getDatabaseLocked called recursively"]
|
|
59
|
+
userInfo:nil];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
FMDatabaseQueue* queue = mQueue;
|
|
63
|
+
mIsInitializing = true;
|
|
64
|
+
|
|
65
|
+
if (queue != nil) {
|
|
66
|
+
if (writable && mIsReadOnly) {
|
|
67
|
+
// TODO reopen as writable
|
|
68
|
+
}
|
|
69
|
+
} else if (mName == nil) {
|
|
70
|
+
@throw [NSException exceptionWithName:NSInternalInconsistencyException
|
|
71
|
+
reason:[NSString stringWithFormat:@"in memory database is not supported"]
|
|
72
|
+
userInfo:nil];
|
|
73
|
+
} else {
|
|
74
|
+
if (writable) {
|
|
75
|
+
queue = [self openOrCreateDatabase:mName];
|
|
76
|
+
} else {
|
|
77
|
+
queue = [self openDatabase:[self getDatabasePath] flags: OPEN_READONLY];
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
[self onConfigure:queue];
|
|
82
|
+
|
|
83
|
+
NSInteger version = [self getVersion:queue];
|
|
84
|
+
NSLog(@"Current db version: %ld", (long)version);
|
|
85
|
+
|
|
86
|
+
if (version != mNewVersion) {
|
|
87
|
+
if (version == 0) {
|
|
88
|
+
[self onCreate:queue];
|
|
89
|
+
} else {
|
|
90
|
+
if (version < mNewVersion) {
|
|
91
|
+
[self onUpgrade:queue fromVersion:version toVersion:mNewVersion];
|
|
92
|
+
} else if (version > mNewVersion) {
|
|
93
|
+
[self onDowngrade:queue fromVersion:version toVersion:mNewVersion];
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
[self setVersion:queue version:mNewVersion];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
[self onOpen:queue];
|
|
100
|
+
|
|
101
|
+
mQueue = queue;
|
|
102
|
+
mIsInitializing = false;
|
|
103
|
+
mIsReadOnly = !writable;
|
|
104
|
+
return queue;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
- (FMDatabaseQueue*) openDatabase:(NSString*)path flags:(int)flags
|
|
108
|
+
{
|
|
109
|
+
return [FMDatabaseQueue databaseQueueWithPath:path flags:flags];
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
- (FMDatabaseQueue*) openOrCreateDatabase:(NSString*)name
|
|
113
|
+
{
|
|
114
|
+
__block BOOL isOpen;
|
|
115
|
+
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:[self getDatabasePath:name]];
|
|
116
|
+
|
|
117
|
+
[queue inDatabase:^(FMDatabase *database) {
|
|
118
|
+
isOpen = [database open];
|
|
119
|
+
}];
|
|
120
|
+
|
|
121
|
+
if (!isOpen) {
|
|
122
|
+
return nil;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if ([self getVersion:queue] == -1) {
|
|
126
|
+
NSArray *columns = @[
|
|
127
|
+
@{ @"name": @"id", @"type": [SQLPrimaryKeyColumnType sqlColumnWithType: kInteger]},
|
|
128
|
+
@{ @"name": @"db_version", @"type": [SQLColumnType sqlColumnWithType: kInteger]},
|
|
129
|
+
@{ @"name": @"created", @"type": [SQLColumnType sqlColumnWithType: kInteger]},
|
|
130
|
+
@{ @"name": @"last_updated", @"type": [SQLColumnType sqlColumnWithType: kInteger]}
|
|
131
|
+
];
|
|
132
|
+
|
|
133
|
+
[queue inDatabase:^(FMDatabase *database) {
|
|
134
|
+
if ([database executeStatements:[MAURSQLiteHelper createTableSqlStatement:metaTableName columns:columns]]) {
|
|
135
|
+
NSString *sql = [NSString stringWithFormat: @"INSERT INTO %@ (id,db_version,created,last_updated) VALUES (1,%d,datetime(),null)", metaTableName, 0];
|
|
136
|
+
if (![database executeUpdate:sql]) {
|
|
137
|
+
NSLog(@"%@ failed code: %d: message: %@", sql, [database lastErrorCode], [database lastErrorMessage]);
|
|
138
|
+
}
|
|
139
|
+
} else {
|
|
140
|
+
NSLog(@"Creating meta table %@ failed code: %d: message: %@", metaTableName, [database lastErrorCode], [database lastErrorMessage]);
|
|
141
|
+
}
|
|
142
|
+
}];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return queue;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
- (void) close
|
|
149
|
+
{
|
|
150
|
+
@synchronized(self) {
|
|
151
|
+
if (mQueue != nil) {
|
|
152
|
+
[mQueue close];
|
|
153
|
+
mQueue = nil;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
- (NSDictionary*) getDatabaseMetadata
|
|
159
|
+
{
|
|
160
|
+
FMDatabaseQueue *queue = [self getReadableDatabase];
|
|
161
|
+
NSMutableDictionary *metadata = [[NSMutableDictionary alloc] init];
|
|
162
|
+
[metadata setObject:[NSNumber numberWithInt:-1] forKey:@"dbVersion"];
|
|
163
|
+
|
|
164
|
+
NSString *sql =[NSString stringWithFormat: @"SELECT db_version, created, last_updated FROM %@ LIMIT 1", metaTableName];
|
|
165
|
+
[queue inDatabase:^(FMDatabase *database) {
|
|
166
|
+
FMResultSet *rs = [database executeQuery:sql];
|
|
167
|
+
while ([rs next]) {
|
|
168
|
+
NSNumber *dbVersion = [NSNumber numberWithInt:[rs intForColumnIndex:0]];
|
|
169
|
+
NSString *created = [rs stringForColumnIndex:1] ?: @"";
|
|
170
|
+
NSString *lastUpdated = [rs stringForColumnIndex:2] ?: @"";
|
|
171
|
+
|
|
172
|
+
[metadata setObject:dbVersion forKey:@"dbVersion"];
|
|
173
|
+
[metadata setObject:created forKey:@"created"];
|
|
174
|
+
[metadata setObject:lastUpdated forKey:@"last_updated"];
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// TODO error handling
|
|
178
|
+
// NSLog(@"Retrieving meta data failed code: %d: message: %s", sqlite3_errcode(database), sqlite3_errmsg(database));
|
|
179
|
+
[rs close];
|
|
180
|
+
|
|
181
|
+
}];
|
|
182
|
+
|
|
183
|
+
[queue close];
|
|
184
|
+
|
|
185
|
+
return metadata;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
- (NSString*) getDatabaseName
|
|
189
|
+
{
|
|
190
|
+
return mName;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
- (NSString*) getDatabasePath:(NSString*)name
|
|
194
|
+
{
|
|
195
|
+
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
|
|
196
|
+
NSString *libraryDirectory = [paths objectAtIndex:0];
|
|
197
|
+
NSString *databasePath = [[NSString alloc]initWithString:[libraryDirectory stringByAppendingPathComponent:name]];
|
|
198
|
+
|
|
199
|
+
return databasePath;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
- (NSString*) getDatabasePath
|
|
203
|
+
{
|
|
204
|
+
return [self getDatabasePath:mName];
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
- (FMDatabaseQueue*) getDatabaseQueue
|
|
208
|
+
{
|
|
209
|
+
@synchronized(self) {
|
|
210
|
+
if (mQueue == nil) {
|
|
211
|
+
mQueue = [FMDatabaseQueue databaseQueueWithPath:[self getDatabasePath]];
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return mQueue;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
- (NSInteger) getVersion:(FMDatabaseQueue*)queue
|
|
219
|
+
{
|
|
220
|
+
__block NSInteger dbVersion = -1;
|
|
221
|
+
NSString *sql =[NSString stringWithFormat: @"SELECT db_version FROM %@", metaTableName];
|
|
222
|
+
[queue inDatabase:^(FMDatabase *database) {
|
|
223
|
+
database.logsErrors = NO;
|
|
224
|
+
NSError *lastError;
|
|
225
|
+
FMResultSet *rs = [database executeQuery:sql values:nil error:&lastError];
|
|
226
|
+
if (rs != nil) {
|
|
227
|
+
while ([rs next]) {
|
|
228
|
+
dbVersion = [rs intForColumnIndex:0];
|
|
229
|
+
}
|
|
230
|
+
[rs close];
|
|
231
|
+
} else {
|
|
232
|
+
NSLog(@"Determining db version returned error (ok for first run): %@", [lastError localizedDescription]);
|
|
233
|
+
}
|
|
234
|
+
database.logsErrors = YES;
|
|
235
|
+
}];
|
|
236
|
+
|
|
237
|
+
return dbVersion;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
- (void) setVersion:(FMDatabaseQueue*)queue version:(NSInteger)version
|
|
241
|
+
{
|
|
242
|
+
NSString *sql = [NSString stringWithFormat: @"UPDATE %@ SET db_version = %ld, last_updated = datetime()", metaTableName, (long)version];
|
|
243
|
+
[queue inDatabase:^(FMDatabase *database) {
|
|
244
|
+
if (![database executeUpdate:sql]) {
|
|
245
|
+
NSLog(@"%@ failed code: %d: message: %@", sql, [database lastErrorCode], [database lastErrorMessage]);
|
|
246
|
+
}
|
|
247
|
+
}];
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
- (void) onOpen:(FMDatabaseQueue*)database
|
|
251
|
+
{
|
|
252
|
+
// ment to be implemented in subclass
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
- (void) onConfigure:(FMDatabaseQueue*)database;
|
|
256
|
+
{
|
|
257
|
+
// ment to be implemented in subclass
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
- (void) onCreate:(FMDatabaseQueue*)database
|
|
261
|
+
{
|
|
262
|
+
// has to be implemented in subclass
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
- (void) onUpgrade:(FMDatabaseQueue*)database fromVersion:(NSInteger)oldVersion toVersion:(NSInteger)newVersion
|
|
266
|
+
{
|
|
267
|
+
// upgrade policy has to be implemented in subclass
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
- (void) onDowngrade:(FMDatabaseQueue*)database fromVersion:(NSInteger)oldVersion toVersion:(NSInteger)newVersion
|
|
271
|
+
{
|
|
272
|
+
// upgrade policy has to be implemented in subclass
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
@end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
//
|
|
2
|
+
// MAURSensorFusionDetector.h
|
|
3
|
+
// BackgroundGeolocation
|
|
4
|
+
//
|
|
5
|
+
// v4.2 Phase 8 — Real sensor fusion detector for iOS.
|
|
6
|
+
// Uses CMMotionManager to sample userAcceleration (gravity removed) and rotationRate.
|
|
7
|
+
// Refines possibleCrash via accelerometer impact and detects phoneUsageWhileDriving.
|
|
8
|
+
//
|
|
9
|
+
|
|
10
|
+
#ifndef MAURSensorFusionDetector_h
|
|
11
|
+
#define MAURSensorFusionDetector_h
|
|
12
|
+
|
|
13
|
+
#import <Foundation/Foundation.h>
|
|
14
|
+
|
|
15
|
+
@class MAURLocation;
|
|
16
|
+
|
|
17
|
+
@protocol MAURSensorFusionListener <NSObject>
|
|
18
|
+
- (void)onSensorCrashWithImpactG:(double)impactG location:(MAURLocation *)location;
|
|
19
|
+
- (void)onPhoneUsageWhileDriving:(MAURLocation *)location;
|
|
20
|
+
@end
|
|
21
|
+
|
|
22
|
+
@interface MAURSensorFusionDetector : NSObject
|
|
23
|
+
|
|
24
|
+
@property (nonatomic, weak) id<MAURSensorFusionListener> listener;
|
|
25
|
+
@property (nonatomic, assign) BOOL enabled;
|
|
26
|
+
@property (nonatomic, assign) double crashImpactG; // default 3.0
|
|
27
|
+
@property (nonatomic, assign) NSTimeInterval crashCooldownMs; // default 10000
|
|
28
|
+
@property (nonatomic, assign) NSTimeInterval phoneUsageWindowMs; // default 4000
|
|
29
|
+
@property (nonatomic, assign) NSTimeInterval phoneUsageCooldownMs; // default 60000
|
|
30
|
+
|
|
31
|
+
@property (nonatomic, assign) BOOL tripActive;
|
|
32
|
+
@property (nonatomic, strong) MAURLocation *lastLocation;
|
|
33
|
+
|
|
34
|
+
- (instancetype)init;
|
|
35
|
+
- (BOOL)isAvailable;
|
|
36
|
+
- (void)start;
|
|
37
|
+
- (void)stop;
|
|
38
|
+
|
|
39
|
+
@end
|
|
40
|
+
|
|
41
|
+
#endif /* MAURSensorFusionDetector_h */
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
//
|
|
2
|
+
// MAURSensorFusionDetector.m
|
|
3
|
+
// BackgroundGeolocation
|
|
4
|
+
//
|
|
5
|
+
// v4.2 Phase 8 — sensor fusion detector implementation.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
#import "MAURSensorFusionDetector.h"
|
|
9
|
+
#import <CoreMotion/CoreMotion.h>
|
|
10
|
+
#import <UIKit/UIKit.h>
|
|
11
|
+
|
|
12
|
+
static const double kJitterGyroRadS = 0.7; // ~40 deg/s
|
|
13
|
+
static const double kJitterAccelMps2 = 0.5;
|
|
14
|
+
|
|
15
|
+
@interface MAURSensorFusionDetector ()
|
|
16
|
+
@property (nonatomic, strong) CMMotionManager *motion;
|
|
17
|
+
@property (nonatomic, strong) NSOperationQueue *queue;
|
|
18
|
+
@property (nonatomic, assign) BOOL started;
|
|
19
|
+
@property (nonatomic, assign) NSTimeInterval lastCrashAt;
|
|
20
|
+
@property (nonatomic, assign) NSTimeInterval lastPhoneUsageAt;
|
|
21
|
+
@property (nonatomic, assign) NSTimeInterval jitterAboveSince;
|
|
22
|
+
@end
|
|
23
|
+
|
|
24
|
+
@implementation MAURSensorFusionDetector
|
|
25
|
+
|
|
26
|
+
- (instancetype)init {
|
|
27
|
+
if ((self = [super init])) {
|
|
28
|
+
_motion = [[CMMotionManager alloc] init];
|
|
29
|
+
_motion.deviceMotionUpdateInterval = 1.0 / 50.0; // 50 Hz
|
|
30
|
+
_queue = [[NSOperationQueue alloc] init];
|
|
31
|
+
_queue.name = @"MAURSensorFusionQueue";
|
|
32
|
+
_queue.maxConcurrentOperationCount = 1;
|
|
33
|
+
_enabled = NO;
|
|
34
|
+
_crashImpactG = 3.0;
|
|
35
|
+
_crashCooldownMs = 10000;
|
|
36
|
+
_phoneUsageWindowMs = 4000;
|
|
37
|
+
_phoneUsageCooldownMs = 60000;
|
|
38
|
+
_started = NO;
|
|
39
|
+
_lastCrashAt = 0;
|
|
40
|
+
_lastPhoneUsageAt = 0;
|
|
41
|
+
_jitterAboveSince = 0;
|
|
42
|
+
}
|
|
43
|
+
return self;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
- (BOOL)isAvailable {
|
|
47
|
+
return self.motion.isDeviceMotionAvailable;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
- (void)start {
|
|
51
|
+
@synchronized (self) {
|
|
52
|
+
if (self.started || !self.enabled) return;
|
|
53
|
+
if (![self.motion isDeviceMotionAvailable]) return;
|
|
54
|
+
__weak typeof(self) weakSelf = self;
|
|
55
|
+
[self.motion startDeviceMotionUpdatesToQueue:self.queue
|
|
56
|
+
withHandler:^(CMDeviceMotion * _Nullable motion, NSError * _Nullable error) {
|
|
57
|
+
if (!motion || error) return;
|
|
58
|
+
[weakSelf processMotion:motion];
|
|
59
|
+
}];
|
|
60
|
+
self.started = YES;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
- (void)stop {
|
|
65
|
+
@synchronized (self) {
|
|
66
|
+
if (!self.started) return;
|
|
67
|
+
[self.motion stopDeviceMotionUpdates];
|
|
68
|
+
self.started = NO;
|
|
69
|
+
self.jitterAboveSince = 0;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
- (void)processMotion:(CMDeviceMotion *)motion {
|
|
74
|
+
if (!self.enabled) return;
|
|
75
|
+
NSTimeInterval nowMs = [[NSDate date] timeIntervalSince1970] * 1000.0;
|
|
76
|
+
|
|
77
|
+
// userAcceleration is in g (gravity removed); convert magnitude to g and to m/s².
|
|
78
|
+
double ax = motion.userAcceleration.x;
|
|
79
|
+
double ay = motion.userAcceleration.y;
|
|
80
|
+
double az = motion.userAcceleration.z;
|
|
81
|
+
double accelMagG = sqrt(ax*ax + ay*ay + az*az); // g
|
|
82
|
+
double accelMagMs = accelMagG * 9.80665; // m/s²
|
|
83
|
+
|
|
84
|
+
double gx = motion.rotationRate.x;
|
|
85
|
+
double gy = motion.rotationRate.y;
|
|
86
|
+
double gz = motion.rotationRate.z;
|
|
87
|
+
double gyroMag = sqrt(gx*gx + gy*gy + gz*gz); // rad/s
|
|
88
|
+
|
|
89
|
+
BOOL tripActiveNow = self.tripActive;
|
|
90
|
+
MAURLocation *loc = self.lastLocation;
|
|
91
|
+
id<MAURSensorFusionListener> l = self.listener;
|
|
92
|
+
|
|
93
|
+
// Crash detection
|
|
94
|
+
if (tripActiveNow && self.crashImpactG > 0 && accelMagG >= self.crashImpactG
|
|
95
|
+
&& (nowMs - self.lastCrashAt) >= self.crashCooldownMs) {
|
|
96
|
+
self.lastCrashAt = nowMs;
|
|
97
|
+
if ([l respondsToSelector:@selector(onSensorCrashWithImpactG:location:)]) {
|
|
98
|
+
[l onSensorCrashWithImpactG:accelMagG location:loc];
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// phoneUsageWhileDriving
|
|
103
|
+
if (!tripActiveNow) { self.jitterAboveSince = 0; return; }
|
|
104
|
+
BOOL screenOn = [self isScreenOnApprox];
|
|
105
|
+
if (!screenOn) { self.jitterAboveSince = 0; return; }
|
|
106
|
+
|
|
107
|
+
BOOL above = (accelMagMs >= kJitterAccelMps2) || (gyroMag >= kJitterGyroRadS);
|
|
108
|
+
if (above) {
|
|
109
|
+
if (self.jitterAboveSince == 0) self.jitterAboveSince = nowMs;
|
|
110
|
+
if ((nowMs - self.jitterAboveSince) >= self.phoneUsageWindowMs
|
|
111
|
+
&& (nowMs - self.lastPhoneUsageAt) >= self.phoneUsageCooldownMs) {
|
|
112
|
+
self.lastPhoneUsageAt = nowMs;
|
|
113
|
+
self.jitterAboveSince = 0;
|
|
114
|
+
if ([l respondsToSelector:@selector(onPhoneUsageWhileDriving:)]) {
|
|
115
|
+
[l onPhoneUsageWhileDriving:loc];
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
} else {
|
|
119
|
+
self.jitterAboveSince = 0;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
- (BOOL)isScreenOnApprox {
|
|
124
|
+
// Heuristic: app is foreground active => screen is on. Background sampling does
|
|
125
|
+
// not constitute phone usage while driving (passenger may have screen off too).
|
|
126
|
+
__block UIApplicationState state = UIApplicationStateBackground;
|
|
127
|
+
if ([NSThread isMainThread]) {
|
|
128
|
+
state = [UIApplication sharedApplication].applicationState;
|
|
129
|
+
} else {
|
|
130
|
+
dispatch_sync(dispatch_get_main_queue(), ^{
|
|
131
|
+
state = [UIApplication sharedApplication].applicationState;
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
return state == UIApplicationStateActive;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
@end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//
|
|
2
|
+
// MAURSessionLocationContract.h
|
|
3
|
+
// BackgroundGeolocation
|
|
4
|
+
//
|
|
5
|
+
// Session table for current recording route. Independent of sync; cleared on startSession/clearSession.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
#ifndef MAURSessionLocationContract_h
|
|
9
|
+
#define MAURSessionLocationContract_h
|
|
10
|
+
|
|
11
|
+
#define LSC_TABLE_NAME "location_session"
|
|
12
|
+
#define LSC_COLUMN_NAME_ID "id"
|
|
13
|
+
#define LSC_COLUMN_NAME_TIME "time"
|
|
14
|
+
#define LSC_COLUMN_NAME_ACCURACY "accuracy"
|
|
15
|
+
#define LSC_COLUMN_NAME_SPEED "speed"
|
|
16
|
+
#define LSC_COLUMN_NAME_BEARING "bearing"
|
|
17
|
+
#define LSC_COLUMN_NAME_ALTITUDE "altitude"
|
|
18
|
+
#define LSC_COLUMN_NAME_LATITUDE "latitude"
|
|
19
|
+
#define LSC_COLUMN_NAME_LONGITUDE "longitude"
|
|
20
|
+
#define LSC_COLUMN_NAME_PROVIDER "provider"
|
|
21
|
+
#define LSC_COLUMN_NAME_LOCATION_PROVIDER "service_provider"
|
|
22
|
+
#define LSC_COLUMN_NAME_STATUS "valid"
|
|
23
|
+
#define LSC_COLUMN_NAME_RECORDED_AT "recorded_at"
|
|
24
|
+
|
|
25
|
+
@interface MAURSessionLocationContract : NSObject
|
|
26
|
+
+ (NSString*) createTableSQL;
|
|
27
|
+
@end
|
|
28
|
+
|
|
29
|
+
#endif /* MAURSessionLocationContract_h */
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
//
|
|
2
|
+
// MAURSessionLocationContract.m
|
|
3
|
+
// BackgroundGeolocation
|
|
4
|
+
//
|
|
5
|
+
|
|
6
|
+
#import <Foundation/Foundation.h>
|
|
7
|
+
#import "MAURSQLiteHelper.h"
|
|
8
|
+
#import "MAURSessionLocationContract.h"
|
|
9
|
+
|
|
10
|
+
@implementation MAURSessionLocationContract
|
|
11
|
+
|
|
12
|
+
+ (NSString*) createTableSQL
|
|
13
|
+
{
|
|
14
|
+
NSArray *columns = @[
|
|
15
|
+
@{ @"name": @LSC_COLUMN_NAME_ID, @"type": [SQLPrimaryKeyAutoIncColumnType sqlColumnWithType: kInteger]},
|
|
16
|
+
@{ @"name": @LSC_COLUMN_NAME_TIME, @"type": [SQLColumnType sqlColumnWithType: kReal]},
|
|
17
|
+
@{ @"name": @LSC_COLUMN_NAME_ACCURACY, @"type": [SQLColumnType sqlColumnWithType: kReal]},
|
|
18
|
+
@{ @"name": @LSC_COLUMN_NAME_SPEED, @"type": [SQLColumnType sqlColumnWithType: kReal]},
|
|
19
|
+
@{ @"name": @LSC_COLUMN_NAME_BEARING, @"type": [SQLColumnType sqlColumnWithType: kReal]},
|
|
20
|
+
@{ @"name": @LSC_COLUMN_NAME_ALTITUDE, @"type": [SQLColumnType sqlColumnWithType: kReal]},
|
|
21
|
+
@{ @"name": @LSC_COLUMN_NAME_LATITUDE, @"type": [SQLColumnType sqlColumnWithType: kReal]},
|
|
22
|
+
@{ @"name": @LSC_COLUMN_NAME_LONGITUDE, @"type": [SQLColumnType sqlColumnWithType: kReal]},
|
|
23
|
+
@{ @"name": @LSC_COLUMN_NAME_PROVIDER, @"type": [SQLColumnType sqlColumnWithType: kText]},
|
|
24
|
+
@{ @"name": @LSC_COLUMN_NAME_LOCATION_PROVIDER, @"type": [SQLColumnType sqlColumnWithType: kText]},
|
|
25
|
+
@{ @"name": @LSC_COLUMN_NAME_STATUS, @"type": [SQLColumnType sqlColumnWithType: kInteger]},
|
|
26
|
+
@{ @"name": @LSC_COLUMN_NAME_RECORDED_AT, @"type": [SQLColumnType sqlColumnWithType: kInteger]}
|
|
27
|
+
];
|
|
28
|
+
return [MAURSQLiteHelper createTableSqlStatement:@LSC_TABLE_NAME columns:columns];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//
|
|
2
|
+
// MAURSessionLocationDAO.h
|
|
3
|
+
// BackgroundGeolocation
|
|
4
|
+
//
|
|
5
|
+
// Session storage for current route. Cleared on startSession/clearSession; not cleared by sync.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
#ifndef MAURSessionLocationDAO_h
|
|
9
|
+
#define MAURSessionLocationDAO_h
|
|
10
|
+
|
|
11
|
+
#import <Foundation/Foundation.h>
|
|
12
|
+
#import "MAURLocation.h"
|
|
13
|
+
|
|
14
|
+
@interface MAURSessionLocationDAO : NSObject
|
|
15
|
+
+ (instancetype) sharedInstance;
|
|
16
|
+
- (id) init NS_UNAVAILABLE;
|
|
17
|
+
- (void) startSession;
|
|
18
|
+
- (void) clearSession;
|
|
19
|
+
- (BOOL) isSessionActive;
|
|
20
|
+
- (void) persistSessionLocation:(MAURLocation*)location;
|
|
21
|
+
- (NSArray<MAURLocation*>*) getSessionLocations;
|
|
22
|
+
- (NSInteger) getSessionLocationsCount;
|
|
23
|
+
@end
|
|
24
|
+
|
|
25
|
+
#endif /* MAURSessionLocationDAO_h */
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
//
|
|
2
|
+
// MAURSessionLocationDAO.m
|
|
3
|
+
// BackgroundGeolocation
|
|
4
|
+
//
|
|
5
|
+
|
|
6
|
+
#import <Foundation/Foundation.h>
|
|
7
|
+
#import "MAURGeolocationOpenHelper.h"
|
|
8
|
+
#import "MAURSessionLocationContract.h"
|
|
9
|
+
#import "MAURSessionLocationDAO.h"
|
|
10
|
+
#import "MAURLocation.h"
|
|
11
|
+
#import "FMDB.h"
|
|
12
|
+
|
|
13
|
+
static NSString *const kSessionActiveKey = @"bgloc_session_active";
|
|
14
|
+
|
|
15
|
+
@interface MAURSessionLocationDAO ()
|
|
16
|
+
- (instancetype)initPrivate;
|
|
17
|
+
@end
|
|
18
|
+
|
|
19
|
+
@implementation MAURSessionLocationDAO {
|
|
20
|
+
FMDatabaseQueue* queue;
|
|
21
|
+
MAURGeolocationOpenHelper *helper;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
+ (instancetype) sharedInstance
|
|
25
|
+
{
|
|
26
|
+
static MAURSessionLocationDAO *instance = nil;
|
|
27
|
+
static dispatch_once_t onceToken;
|
|
28
|
+
dispatch_once(&onceToken, ^{
|
|
29
|
+
instance = [[self alloc] initPrivate];
|
|
30
|
+
});
|
|
31
|
+
return instance;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
- (instancetype) initPrivate
|
|
35
|
+
{
|
|
36
|
+
if (self = [super init]) {
|
|
37
|
+
helper = [[MAURGeolocationOpenHelper alloc] init];
|
|
38
|
+
queue = [helper getWritableDatabase];
|
|
39
|
+
}
|
|
40
|
+
return self;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
- (void) startSession
|
|
44
|
+
{
|
|
45
|
+
[queue inDatabase:^(FMDatabase *database) {
|
|
46
|
+
NSString *sql = [NSString stringWithFormat:@"DELETE FROM %@", @LSC_TABLE_NAME];
|
|
47
|
+
[database executeUpdate:sql];
|
|
48
|
+
}];
|
|
49
|
+
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:kSessionActiveKey];
|
|
50
|
+
[[NSUserDefaults standardUserDefaults] synchronize];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
- (void) clearSession
|
|
54
|
+
{
|
|
55
|
+
[queue inDatabase:^(FMDatabase *database) {
|
|
56
|
+
NSString *sql = [NSString stringWithFormat:@"DELETE FROM %@", @LSC_TABLE_NAME];
|
|
57
|
+
[database executeUpdate:sql];
|
|
58
|
+
}];
|
|
59
|
+
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:kSessionActiveKey];
|
|
60
|
+
[[NSUserDefaults standardUserDefaults] synchronize];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
- (BOOL) isSessionActive
|
|
64
|
+
{
|
|
65
|
+
return [[NSUserDefaults standardUserDefaults] boolForKey:kSessionActiveKey];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
- (void) persistSessionLocation:(MAURLocation*)location
|
|
69
|
+
{
|
|
70
|
+
if (![self isSessionActive]) return;
|
|
71
|
+
if (!location || !location.time) return;
|
|
72
|
+
NSTimeInterval timestamp = [[NSDate date] timeIntervalSince1970];
|
|
73
|
+
NSNumber *recordedAt = [NSNumber numberWithDouble:timestamp];
|
|
74
|
+
|
|
75
|
+
NSString *sql = @"INSERT INTO " @LSC_TABLE_NAME @" ("
|
|
76
|
+
@LSC_COLUMN_NAME_TIME @"," @LSC_COLUMN_NAME_ACCURACY @"," @LSC_COLUMN_NAME_SPEED @","
|
|
77
|
+
@LSC_COLUMN_NAME_BEARING @"," @LSC_COLUMN_NAME_ALTITUDE @"," @LSC_COLUMN_NAME_LATITUDE @","
|
|
78
|
+
@LSC_COLUMN_NAME_LONGITUDE @"," @LSC_COLUMN_NAME_PROVIDER @"," @LSC_COLUMN_NAME_LOCATION_PROVIDER @","
|
|
79
|
+
@LSC_COLUMN_NAME_STATUS @"," @LSC_COLUMN_NAME_RECORDED_AT
|
|
80
|
+
@") VALUES (?,?,?,?,?,?,?,?,?,?,?)";
|
|
81
|
+
|
|
82
|
+
[queue inDatabase:^(FMDatabase *database) {
|
|
83
|
+
[database executeUpdate:sql,
|
|
84
|
+
[NSNumber numberWithDouble:[location.time timeIntervalSince1970]],
|
|
85
|
+
location.accuracy ?: @0,
|
|
86
|
+
location.speed ?: @0,
|
|
87
|
+
location.heading ?: @0,
|
|
88
|
+
location.altitude ?: @0,
|
|
89
|
+
location.latitude ?: @0,
|
|
90
|
+
location.longitude ?: @0,
|
|
91
|
+
location.provider ?: [NSNull null],
|
|
92
|
+
location.locationProvider ? [NSString stringWithFormat:@"%@", location.locationProvider] : [NSNull null],
|
|
93
|
+
@(1),
|
|
94
|
+
recordedAt
|
|
95
|
+
];
|
|
96
|
+
}];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
- (NSArray<MAURLocation*>*) getSessionLocations
|
|
100
|
+
{
|
|
101
|
+
__block NSMutableArray* locations = [[NSMutableArray alloc] init];
|
|
102
|
+
NSString *sql = @"SELECT " @LSC_COLUMN_NAME_ID @"," @LSC_COLUMN_NAME_TIME @"," @LSC_COLUMN_NAME_ACCURACY @","
|
|
103
|
+
@LSC_COLUMN_NAME_SPEED @"," @LSC_COLUMN_NAME_BEARING @"," @LSC_COLUMN_NAME_ALTITUDE @","
|
|
104
|
+
@LSC_COLUMN_NAME_LATITUDE @"," @LSC_COLUMN_NAME_LONGITUDE @"," @LSC_COLUMN_NAME_PROVIDER @","
|
|
105
|
+
@LSC_COLUMN_NAME_LOCATION_PROVIDER @"," @LSC_COLUMN_NAME_STATUS @"," @LSC_COLUMN_NAME_RECORDED_AT
|
|
106
|
+
@" FROM " @LSC_TABLE_NAME @" ORDER BY " @LSC_COLUMN_NAME_RECORDED_AT;
|
|
107
|
+
|
|
108
|
+
[queue inDatabase:^(FMDatabase *database) {
|
|
109
|
+
FMResultSet *rs = [database executeQuery:sql];
|
|
110
|
+
while ([rs next]) {
|
|
111
|
+
MAURLocation *loc = [self convertToLocation:rs];
|
|
112
|
+
[locations addObject:loc];
|
|
113
|
+
}
|
|
114
|
+
[rs close];
|
|
115
|
+
}];
|
|
116
|
+
return locations;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
- (NSInteger) getSessionLocationsCount
|
|
120
|
+
{
|
|
121
|
+
__block NSInteger count = 0;
|
|
122
|
+
NSString *sql = [NSString stringWithFormat:@"SELECT COUNT(*) FROM %@", @LSC_TABLE_NAME];
|
|
123
|
+
[queue inDatabase:^(FMDatabase *database) {
|
|
124
|
+
FMResultSet *rs = [database executeQuery:sql];
|
|
125
|
+
if ([rs next]) {
|
|
126
|
+
count = [rs intForColumnIndex:0];
|
|
127
|
+
}
|
|
128
|
+
[rs close];
|
|
129
|
+
}];
|
|
130
|
+
return count;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
- (MAURLocation*) convertToLocation:(FMResultSet*)rs
|
|
134
|
+
{
|
|
135
|
+
MAURLocation *location = [[MAURLocation alloc] init];
|
|
136
|
+
location.locationId = [NSNumber numberWithLongLong:[rs longLongIntForColumnIndex:0]];
|
|
137
|
+
NSTimeInterval timestamp = [rs doubleForColumnIndex:1];
|
|
138
|
+
location.time = [NSDate dateWithTimeIntervalSince1970:timestamp];
|
|
139
|
+
location.accuracy = [NSNumber numberWithDouble:[rs doubleForColumnIndex:2]];
|
|
140
|
+
location.speed = [NSNumber numberWithDouble:[rs doubleForColumnIndex:3]];
|
|
141
|
+
location.heading = [NSNumber numberWithDouble:[rs doubleForColumnIndex:4]];
|
|
142
|
+
location.altitude = [NSNumber numberWithDouble:[rs doubleForColumnIndex:5]];
|
|
143
|
+
location.latitude = [NSNumber numberWithDouble:[rs doubleForColumnIndex:6]];
|
|
144
|
+
location.longitude = [NSNumber numberWithDouble:[rs doubleForColumnIndex:7]];
|
|
145
|
+
location.provider = [rs stringForColumnIndex:8];
|
|
146
|
+
location.locationProvider = [NSNumber numberWithInt:[rs intForColumnIndex:9]];
|
|
147
|
+
location.isValid = [rs intForColumnIndex:10] == 1 ? YES : NO;
|
|
148
|
+
NSTimeInterval recordedAt = [rs longForColumnIndex:11];
|
|
149
|
+
location.recordedAt = [NSDate dateWithTimeIntervalSince1970:recordedAt];
|
|
150
|
+
return location;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
@end
|