@bricks-soft/capacitor-location-tracking 0.0.0-stage → 8.0.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.
Files changed (168) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +2759 -2
  3. package/android/build.gradle +107 -0
  4. package/android/consumer-rules.pro +42 -0
  5. package/android/src/main/AndroidManifest.xml +52 -0
  6. package/android/src/main/java/com/brickssoft/locationtracking/LocationTrackingPlugin.kt +431 -0
  7. package/android/src/main/java/com/brickssoft/locationtracking/api/LocationTrackingListener.kt +52 -0
  8. package/android/src/main/java/com/brickssoft/locationtracking/api/LocationTrackingNative.kt +267 -0
  9. package/android/src/main/java/com/brickssoft/locationtracking/api/NativeListeners.kt +270 -0
  10. package/android/src/main/java/com/brickssoft/locationtracking/api/NativeThread.kt +57 -0
  11. package/android/src/main/java/com/brickssoft/locationtracking/bridge/BridgeServices.kt +64 -0
  12. package/android/src/main/java/com/brickssoft/locationtracking/bridge/CallResponder.kt +41 -0
  13. package/android/src/main/java/com/brickssoft/locationtracking/bridge/OptionParsers.kt +281 -0
  14. package/android/src/main/java/com/brickssoft/locationtracking/bridge/PluginHandlers.kt +541 -0
  15. package/android/src/main/java/com/brickssoft/locationtracking/bridge/PluginPermissionHost.kt +76 -0
  16. package/android/src/main/java/com/brickssoft/locationtracking/bridge/WatchRegistry.kt +84 -0
  17. package/android/src/main/java/com/brickssoft/locationtracking/config/Config.kt +231 -0
  18. package/android/src/main/java/com/brickssoft/locationtracking/config/ConfigJson.kt +574 -0
  19. package/android/src/main/java/com/brickssoft/locationtracking/config/ConfigStore.kt +31 -0
  20. package/android/src/main/java/com/brickssoft/locationtracking/config/ConfigValidator.kt +170 -0
  21. package/android/src/main/java/com/brickssoft/locationtracking/config/RuntimeStateJson.kt +73 -0
  22. package/android/src/main/java/com/brickssoft/locationtracking/config/SharedPrefsConfigStore.kt +135 -0
  23. package/android/src/main/java/com/brickssoft/locationtracking/config/State.kt +45 -0
  24. package/android/src/main/java/com/brickssoft/locationtracking/core/AppDispatchers.kt +21 -0
  25. package/android/src/main/java/com/brickssoft/locationtracking/core/Clock.kt +41 -0
  26. package/android/src/main/java/com/brickssoft/locationtracking/core/Components.kt +217 -0
  27. package/android/src/main/java/com/brickssoft/locationtracking/core/Constants.kt +78 -0
  28. package/android/src/main/java/com/brickssoft/locationtracking/core/Errors.kt +27 -0
  29. package/android/src/main/java/com/brickssoft/locationtracking/core/EventBus.kt +39 -0
  30. package/android/src/main/java/com/brickssoft/locationtracking/core/ForceStopProbe.kt +63 -0
  31. package/android/src/main/java/com/brickssoft/locationtracking/core/Iso8601.kt +63 -0
  32. package/android/src/main/java/com/brickssoft/locationtracking/core/Logger.kt +68 -0
  33. package/android/src/main/java/com/brickssoft/locationtracking/core/RecordHooks.kt +47 -0
  34. package/android/src/main/java/com/brickssoft/locationtracking/core/TrackingEvent.kt +64 -0
  35. package/android/src/main/java/com/brickssoft/locationtracking/data/SqlSupport.kt +79 -0
  36. package/android/src/main/java/com/brickssoft/locationtracking/data/SqliteGeofenceStore.kt +144 -0
  37. package/android/src/main/java/com/brickssoft/locationtracking/data/SqliteLocationStore.kt +215 -0
  38. package/android/src/main/java/com/brickssoft/locationtracking/data/Stores.kt +45 -0
  39. package/android/src/main/java/com/brickssoft/locationtracking/data/TrackingDatabase.kt +111 -0
  40. package/android/src/main/java/com/brickssoft/locationtracking/device/DefaultDeviceInfoProvider.kt +104 -0
  41. package/android/src/main/java/com/brickssoft/locationtracking/device/DefaultDeviceMonitor.kt +335 -0
  42. package/android/src/main/java/com/brickssoft/locationtracking/device/DeviceMonitor.kt +36 -0
  43. package/android/src/main/java/com/brickssoft/locationtracking/device/DeviceStateMapping.kt +69 -0
  44. package/android/src/main/java/com/brickssoft/locationtracking/engine/DefaultTrackingEngine.kt +1281 -0
  45. package/android/src/main/java/com/brickssoft/locationtracking/engine/ElasticDistance.kt +68 -0
  46. package/android/src/main/java/com/brickssoft/locationtracking/engine/LocationRequests.kt +74 -0
  47. package/android/src/main/java/com/brickssoft/locationtracking/engine/MotionStateMachine.kt +291 -0
  48. package/android/src/main/java/com/brickssoft/locationtracking/engine/StationaryRegion.kt +41 -0
  49. package/android/src/main/java/com/brickssoft/locationtracking/engine/TrackingEngine.kt +60 -0
  50. package/android/src/main/java/com/brickssoft/locationtracking/engine/TrackingTimers.kt +90 -0
  51. package/android/src/main/java/com/brickssoft/locationtracking/geofence/DefaultGeofenceManager.kt +899 -0
  52. package/android/src/main/java/com/brickssoft/locationtracking/geofence/DwellTracker.kt +80 -0
  53. package/android/src/main/java/com/brickssoft/locationtracking/geofence/GeofenceManager.kt +33 -0
  54. package/android/src/main/java/com/brickssoft/locationtracking/geofence/PolygonMath.kt +194 -0
  55. package/android/src/main/java/com/brickssoft/locationtracking/heartbeat/DefaultHeartbeatScheduler.kt +713 -0
  56. package/android/src/main/java/com/brickssoft/locationtracking/heartbeat/HeartbeatAlarmReceiver.kt +69 -0
  57. package/android/src/main/java/com/brickssoft/locationtracking/heartbeat/HeartbeatAlarms.kt +100 -0
  58. package/android/src/main/java/com/brickssoft/locationtracking/heartbeat/HeartbeatScheduler.kt +25 -0
  59. package/android/src/main/java/com/brickssoft/locationtracking/heartbeat/HeartbeatWindow.kt +179 -0
  60. package/android/src/main/java/com/brickssoft/locationtracking/http/AuthorizationManager.kt +213 -0
  61. package/android/src/main/java/com/brickssoft/locationtracking/http/BodyBuilder.kt +73 -0
  62. package/android/src/main/java/com/brickssoft/locationtracking/http/HttpSupport.kt +118 -0
  63. package/android/src/main/java/com/brickssoft/locationtracking/http/HttpSyncer.kt +18 -0
  64. package/android/src/main/java/com/brickssoft/locationtracking/http/OkHttpSyncer.kt +551 -0
  65. package/android/src/main/java/com/brickssoft/locationtracking/http/StrictJson.kt +135 -0
  66. package/android/src/main/java/com/brickssoft/locationtracking/http/SyncPolicy.kt +109 -0
  67. package/android/src/main/java/com/brickssoft/locationtracking/http/TemplateRenderer.kt +143 -0
  68. package/android/src/main/java/com/brickssoft/locationtracking/logging/FileLogger.kt +461 -0
  69. package/android/src/main/java/com/brickssoft/locationtracking/logging/LogFileProvider.kt +9 -0
  70. package/android/src/main/java/com/brickssoft/locationtracking/logging/LogFormatter.kt +148 -0
  71. package/android/src/main/java/com/brickssoft/locationtracking/logging/LogStore.kt +30 -0
  72. package/android/src/main/java/com/brickssoft/locationtracking/model/DeviceModels.kt +176 -0
  73. package/android/src/main/java/com/brickssoft/locationtracking/model/GeofenceSpec.kt +25 -0
  74. package/android/src/main/java/com/brickssoft/locationtracking/model/ModelJson.kt +550 -0
  75. package/android/src/main/java/com/brickssoft/locationtracking/model/Record.kt +106 -0
  76. package/android/src/main/java/com/brickssoft/locationtracking/model/TrackedLocation.kt +53 -0
  77. package/android/src/main/java/com/brickssoft/locationtracking/permission/BackgroundRationaleDialog.kt +85 -0
  78. package/android/src/main/java/com/brickssoft/locationtracking/permission/CurrentActivityTracker.kt +72 -0
  79. package/android/src/main/java/com/brickssoft/locationtracking/permission/DefaultPermissionManager.kt +333 -0
  80. package/android/src/main/java/com/brickssoft/locationtracking/permission/PermissionManager.kt +54 -0
  81. package/android/src/main/java/com/brickssoft/locationtracking/position/DefaultPositionService.kt +277 -0
  82. package/android/src/main/java/com/brickssoft/locationtracking/position/PositionService.kt +39 -0
  83. package/android/src/main/java/com/brickssoft/locationtracking/position/PositionWatch.kt +115 -0
  84. package/android/src/main/java/com/brickssoft/locationtracking/processing/DefaultLocationProcessor.kt +93 -0
  85. package/android/src/main/java/com/brickssoft/locationtracking/processing/DefaultOdometer.kt +99 -0
  86. package/android/src/main/java/com/brickssoft/locationtracking/processing/DefaultRecordFactory.kt +166 -0
  87. package/android/src/main/java/com/brickssoft/locationtracking/processing/Geo.kt +56 -0
  88. package/android/src/main/java/com/brickssoft/locationtracking/processing/KalmanFilter.kt +72 -0
  89. package/android/src/main/java/com/brickssoft/locationtracking/processing/Processing.kt +48 -0
  90. package/android/src/main/java/com/brickssoft/locationtracking/provider/Backends.kt +187 -0
  91. package/android/src/main/java/com/brickssoft/locationtracking/provider/DefaultProviderFactory.kt +169 -0
  92. package/android/src/main/java/com/brickssoft/locationtracking/provider/ProviderPackaging.kt +135 -0
  93. package/android/src/main/java/com/brickssoft/locationtracking/provider/android/AndroidActivityBackend.kt +25 -0
  94. package/android/src/main/java/com/brickssoft/locationtracking/provider/android/AndroidGeofenceBackend.kt +181 -0
  95. package/android/src/main/java/com/brickssoft/locationtracking/provider/android/AndroidGeofenceReceiver.kt +115 -0
  96. package/android/src/main/java/com/brickssoft/locationtracking/provider/android/AndroidLocationBackend.kt +265 -0
  97. package/android/src/main/java/com/brickssoft/locationtracking/provider/android/AndroidProviderBundle.kt +31 -0
  98. package/android/src/main/java/com/brickssoft/locationtracking/provider/android/LocationProviders.kt +98 -0
  99. package/android/src/main/java/com/brickssoft/locationtracking/provider/gms/GmsActivityBackend.kt +80 -0
  100. package/android/src/main/java/com/brickssoft/locationtracking/provider/gms/GmsActivityReceiver.kt +62 -0
  101. package/android/src/main/java/com/brickssoft/locationtracking/provider/gms/GmsErrors.kt +72 -0
  102. package/android/src/main/java/com/brickssoft/locationtracking/provider/gms/GmsGeofenceBackend.kt +152 -0
  103. package/android/src/main/java/com/brickssoft/locationtracking/provider/gms/GmsGeofenceReceiver.kt +78 -0
  104. package/android/src/main/java/com/brickssoft/locationtracking/provider/gms/GmsLocationBackend.kt +176 -0
  105. package/android/src/main/java/com/brickssoft/locationtracking/provider/gms/GmsProviderBundle.kt +62 -0
  106. package/android/src/main/java/com/brickssoft/locationtracking/provider/gms/GmsReceiverSupport.kt +88 -0
  107. package/android/src/main/java/com/brickssoft/locationtracking/provider/gms/GmsTasks.kt +55 -0
  108. package/android/src/main/java/com/brickssoft/locationtracking/provider/hms/HmsActivityBackend.kt +71 -0
  109. package/android/src/main/java/com/brickssoft/locationtracking/provider/hms/HmsActivityReceiver.kt +57 -0
  110. package/android/src/main/java/com/brickssoft/locationtracking/provider/hms/HmsErrors.kt +76 -0
  111. package/android/src/main/java/com/brickssoft/locationtracking/provider/hms/HmsGeofenceBackend.kt +116 -0
  112. package/android/src/main/java/com/brickssoft/locationtracking/provider/hms/HmsGeofenceReceiver.kt +67 -0
  113. package/android/src/main/java/com/brickssoft/locationtracking/provider/hms/HmsIntents.kt +83 -0
  114. package/android/src/main/java/com/brickssoft/locationtracking/provider/hms/HmsLocationBackend.kt +197 -0
  115. package/android/src/main/java/com/brickssoft/locationtracking/provider/hms/HmsProviderBundle.kt +55 -0
  116. package/android/src/main/java/com/brickssoft/locationtracking/provider/hms/HmsTasks.kt +44 -0
  117. package/android/src/main/java/com/brickssoft/locationtracking/record/RecordSink.kt +95 -0
  118. package/android/src/main/java/com/brickssoft/locationtracking/service/BootCountStore.kt +44 -0
  119. package/android/src/main/java/com/brickssoft/locationtracking/service/BootReceiver.kt +175 -0
  120. package/android/src/main/java/com/brickssoft/locationtracking/service/DefaultServiceController.kt +196 -0
  121. package/android/src/main/java/com/brickssoft/locationtracking/service/LocationTrackingService.kt +319 -0
  122. package/android/src/main/java/com/brickssoft/locationtracking/service/NotificationActionReceiver.kt +42 -0
  123. package/android/src/main/java/com/brickssoft/locationtracking/service/NotificationFactory.kt +338 -0
  124. package/android/src/main/java/com/brickssoft/locationtracking/service/ServiceCommands.kt +204 -0
  125. package/android/src/main/java/com/brickssoft/locationtracking/service/ServiceController.kt +22 -0
  126. package/android/src/main/java/com/brickssoft/locationtracking/service/ServiceDeps.kt +61 -0
  127. package/android/src/main/java/com/brickssoft/locationtracking/service/WhileInUseStartCheck.kt +115 -0
  128. package/android/src/main/java/com/brickssoft/locationtracking/settings/DefaultDeviceSettings.kt +79 -0
  129. package/android/src/main/java/com/brickssoft/locationtracking/settings/DeviceSettings.kt +21 -0
  130. package/android/src/main/java/com/brickssoft/locationtracking/settings/OemPowerManagers.kt +198 -0
  131. package/android/src/main/res/drawable/lt_ic_notification.xml +11 -0
  132. package/android/src/main/res/values/lt_strings.xml +11 -0
  133. package/android/src/main/res/xml/lt_file_paths.xml +5 -0
  134. package/dist/esm/definitions.d.ts +719 -0
  135. package/dist/esm/definitions.js +2 -0
  136. package/dist/esm/definitions.js.map +1 -0
  137. package/dist/esm/events.d.ts +50 -0
  138. package/dist/esm/events.js +52 -0
  139. package/dist/esm/events.js.map +1 -0
  140. package/dist/esm/index.d.ts +3 -0
  141. package/dist/esm/index.js +5 -0
  142. package/dist/esm/index.js.map +1 -0
  143. package/dist/esm/plugin.d.ts +3 -0
  144. package/dist/esm/plugin.js +10 -0
  145. package/dist/esm/plugin.js.map +1 -0
  146. package/dist/esm/web/config.d.ts +19 -0
  147. package/dist/esm/web/config.js +243 -0
  148. package/dist/esm/web/config.js.map +1 -0
  149. package/dist/esm/web/device.d.ts +9 -0
  150. package/dist/esm/web/device.js +90 -0
  151. package/dist/esm/web/device.js.map +1 -0
  152. package/dist/esm/web/errors.d.ts +14 -0
  153. package/dist/esm/web/errors.js +19 -0
  154. package/dist/esm/web/errors.js.map +1 -0
  155. package/dist/esm/web/geolocation.d.ts +26 -0
  156. package/dist/esm/web/geolocation.js +117 -0
  157. package/dist/esm/web/geolocation.js.map +1 -0
  158. package/dist/esm/web/location.d.ts +7 -0
  159. package/dist/esm/web/location.js +70 -0
  160. package/dist/esm/web/location.js.map +1 -0
  161. package/dist/esm/web.d.ts +164 -0
  162. package/dist/esm/web.js +328 -0
  163. package/dist/esm/web.js.map +1 -0
  164. package/dist/plugin.cjs.js +945 -0
  165. package/dist/plugin.cjs.js.map +1 -0
  166. package/dist/plugin.js +948 -0
  167. package/dist/plugin.js.map +1 -0
  168. package/package.json +60 -4
@@ -0,0 +1,719 @@
1
+ import type { PermissionState, PluginListenerHandle } from '@capacitor/core';
2
+ export type CallbackID = string;
3
+ export type DesiredAccuracy = 'high' | 'balanced' | 'low' | 'passive';
4
+ export type LocationProviderSetting = 'auto' | 'gms' | 'hms' | 'android';
5
+ export type LocationBackend = 'gms' | 'hms' | 'android' | 'web';
6
+ export type TrackingMode = 'location' | 'geofences';
7
+ export type LogLevel = 'off' | 'error' | 'warn' | 'info' | 'debug' | 'verbose';
8
+ export type ActivityType = 'still' | 'on_foot' | 'walking' | 'running' | 'on_bicycle' | 'in_vehicle' | 'unknown';
9
+ export type RecordEvent = 'location' | 'motionchange' | 'current_position' | 'watch_position' | 'heartbeat' | 'geofence' | 'tracking_start' | 'tracking_stop' | 'providerchange';
10
+ export type GeofenceAction = 'ENTER' | 'EXIT' | 'DWELL';
11
+ export type HttpMethod = 'POST' | 'PUT' | 'PATCH';
12
+ export type NotificationPriority = 'min' | 'low' | 'default' | 'high' | 'max';
13
+ export type PermissionType = 'location' | 'backgroundLocation' | 'activityRecognition' | 'notifications';
14
+ export type ConnectivityType = 'wifi' | 'cellular' | 'ethernet' | 'other' | 'none';
15
+ export type HeartbeatStrategy = 'exact' | 'listener_with_backup' | 'idle_paced' | 'disabled';
16
+ /** Rejection `code` of every failed promise. */
17
+ export type ErrorCode = 'NOT_READY' | 'PERMISSION_DENIED' | 'LOCATION_DISABLED' | 'TIMEOUT' | 'UNAVAILABLE' | 'INVALID_ARGUMENT' | 'NOT_FOUND' | 'NO_URL' | 'HTTP_ERROR' | 'NETWORK_ERROR' | 'TOO_MANY_GEOFENCES' | 'NO_ACTIVITY' | 'IO_ERROR' | 'UNIMPLEMENTED' | 'INTERNAL';
18
+ export interface LocationFilterConfig {
19
+ /** @default false */
20
+ useKalman?: boolean;
21
+ /**
22
+ * Reject fixes with accuracy worse than this (m).
23
+ * @default 100
24
+ */
25
+ trackingAccuracyThreshold?: number;
26
+ /**
27
+ * Reject fixes implying speed above this (m/s); 0 = off.
28
+ * @default 80
29
+ */
30
+ maxImpliedSpeed?: number;
31
+ /**
32
+ * Odometer ignores fixes worse than this (m).
33
+ * @default 20
34
+ */
35
+ odometerAccuracyThreshold?: number;
36
+ /** @default false */
37
+ allowIdenticalLocations?: boolean;
38
+ /**
39
+ * Drop mock fixes entirely (otherwise they are kept with mock:true).
40
+ * @default false
41
+ */
42
+ rejectMockLocations?: boolean;
43
+ }
44
+ export interface GeolocationConfig {
45
+ /** @default 'high' */
46
+ desiredAccuracy?: DesiredAccuracy;
47
+ /**
48
+ * meters
49
+ * @default 10
50
+ */
51
+ distanceFilter?: number;
52
+ /**
53
+ * ms
54
+ * @default 1000
55
+ */
56
+ locationUpdateInterval?: number;
57
+ /**
58
+ * ms
59
+ * @default 500
60
+ */
61
+ fastestLocationUpdateInterval?: number;
62
+ /** @default false */
63
+ disableElasticity?: boolean;
64
+ /** @default 1 */
65
+ elasticityMultiplier?: number;
66
+ /**
67
+ * meters
68
+ * @default 25
69
+ */
70
+ stationaryRadius?: number;
71
+ /**
72
+ * minutes
73
+ * @default 5
74
+ */
75
+ stopTimeout?: number;
76
+ /**
77
+ * minutes, 0 = off
78
+ * @default 0
79
+ */
80
+ stopAfterElapsedMinutes?: number;
81
+ /** @default false */
82
+ stopOnStationary?: boolean;
83
+ /**
84
+ * default getCurrentPosition timeout, ms
85
+ * @default 30000
86
+ */
87
+ locationTimeout?: number;
88
+ filter?: LocationFilterConfig;
89
+ }
90
+ export interface ActivityConfig {
91
+ /** @default false */
92
+ disableMotionActivityUpdates?: boolean;
93
+ /**
94
+ * ms
95
+ * @default 10000
96
+ */
97
+ activityRecognitionInterval?: number;
98
+ /**
99
+ * 0-100
100
+ * @default 75
101
+ */
102
+ minimumActivityRecognitionConfidence?: number;
103
+ /**
104
+ * ms
105
+ * @default 0
106
+ */
107
+ motionTriggerDelay?: number;
108
+ /** @default false */
109
+ disableStopDetection?: boolean;
110
+ }
111
+ export interface HeartbeatConfig {
112
+ /** @default true */
113
+ enabled?: boolean;
114
+ /**
115
+ * seconds, min 60
116
+ * @default 180
117
+ */
118
+ minInterval?: number;
119
+ /**
120
+ * seconds, >= minInterval
121
+ * @default 300
122
+ */
123
+ maxInterval?: number;
124
+ }
125
+ export interface AuthorizationConfig {
126
+ /** @default 'JWT' */
127
+ strategy?: 'JWT';
128
+ accessToken?: string;
129
+ refreshToken?: string;
130
+ refreshUrl?: string;
131
+ /**
132
+ * String values may contain `{refreshToken}`.
133
+ * @default {}
134
+ */
135
+ refreshPayload?: Record<string, string>;
136
+ refreshHeaders?: Record<string, string>;
137
+ /** @default 'json' */
138
+ refreshPayloadEncoding?: 'json' | 'form';
139
+ /**
140
+ * access-token expiry, epoch ms; -1 = unknown
141
+ * @default -1
142
+ */
143
+ expires?: number;
144
+ }
145
+ export interface HttpConfig {
146
+ /** No url => nothing is uploaded (records stay queued). */
147
+ url?: string | null;
148
+ /** @default 'POST' */
149
+ method?: HttpMethod;
150
+ /** @default {} */
151
+ headers?: Record<string, string>;
152
+ /**
153
+ * merged into the ROOT of every request body
154
+ * @default {}
155
+ */
156
+ params?: Record<string, unknown>;
157
+ /** @default true */
158
+ autoSync?: boolean;
159
+ /**
160
+ * upload when queue >= threshold; 0 = every record
161
+ * @default 0
162
+ */
163
+ autoSyncThreshold?: number;
164
+ /**
165
+ * s; upload normal records once the oldest queued one is this old; 0 = off
166
+ * @default 0
167
+ */
168
+ syncInterval?: number;
169
+ /** @default false */
170
+ batchSync?: boolean;
171
+ /** @default 100 */
172
+ maxBatchSize?: number;
173
+ /** @default false */
174
+ disableAutoSyncOnCellular?: boolean;
175
+ /**
176
+ * '.' = no wrapping
177
+ * @default 'location'
178
+ */
179
+ rootProperty?: string;
180
+ /** JSON text with `<%= name %>` placeholders */
181
+ locationTemplate?: string | null;
182
+ /** used for event 'geofence'; falls back to locationTemplate */
183
+ geofenceTemplate?: string | null;
184
+ /**
185
+ * ms
186
+ * @default 60000
187
+ */
188
+ timeout?: number;
189
+ authorization?: AuthorizationConfig | null;
190
+ }
191
+ export interface PersistenceConfig {
192
+ /** @default 7 */
193
+ maxDaysToPersist?: number;
194
+ /**
195
+ * -1 = unlimited
196
+ * @default -1
197
+ */
198
+ maxRecordsToPersist?: number;
199
+ /**
200
+ * merged into `extras` of every record at creation time
201
+ * @default {}
202
+ */
203
+ extras?: Record<string, unknown>;
204
+ }
205
+ export interface AppConfig {
206
+ /** @default true */
207
+ stopOnTerminate?: boolean;
208
+ /** @default false */
209
+ startOnBoot?: boolean;
210
+ }
211
+ export interface NotificationActionButton {
212
+ id: string;
213
+ label: string;
214
+ }
215
+ export interface NotificationConfig {
216
+ /** @default app label */
217
+ title?: string;
218
+ /** @default 'Location tracking is active' */
219
+ text?: string;
220
+ /**
221
+ * 'drawable/name' | 'mipmap/name'
222
+ * @default plugin icon 'drawable/lt_ic_notification'
223
+ */
224
+ smallIcon?: string;
225
+ largeIcon?: string;
226
+ /** '#RRGGBB' */
227
+ color?: string;
228
+ /** @default 'default' */
229
+ priority?: NotificationPriority;
230
+ /** @default 'location_tracking' */
231
+ channelId?: string;
232
+ /** @default 'Location tracking' */
233
+ channelName?: string;
234
+ /** max 3; tap => 'notificationaction' event */
235
+ actions?: NotificationActionButton[];
236
+ /** notification that resumes tracking when Android refuses to restore it from the background (Android 14+) */
237
+ resume?: ResumeNotificationConfig;
238
+ }
239
+ /**
240
+ * Posted when Android refuses to restore tracking from the background (after a reboot, an app update or a process
241
+ * restart), typically on Android 14+ without "Allow all the time". A tap resumes the session
242
+ * (`tracking_start` reason `resume_notification`). Uses the tracking notification's small icon and color.
243
+ */
244
+ export interface ResumeNotificationConfig {
245
+ /** @default false */
246
+ enabled?: boolean;
247
+ /** @default app label */
248
+ title?: string;
249
+ /** @default 'Location tracking is paused. Tap to resume.' */
250
+ text?: string;
251
+ /** @default 'Paused location tracking' */
252
+ channelName?: string;
253
+ }
254
+ export interface GeofenceConfig {
255
+ /** @default true */
256
+ initialTriggerEntry?: boolean;
257
+ }
258
+ export interface LoggerConfig {
259
+ /** @default 'info' */
260
+ logLevel?: LogLevel;
261
+ /** @default 3 */
262
+ logMaxDays?: number;
263
+ }
264
+ export interface BackgroundPermissionRationale {
265
+ /** defaults from plugin string resources */
266
+ title?: string;
267
+ message?: string;
268
+ positiveAction?: string;
269
+ negativeAction?: string;
270
+ }
271
+ export interface Config {
272
+ geolocation?: GeolocationConfig;
273
+ activity?: ActivityConfig;
274
+ heartbeat?: HeartbeatConfig;
275
+ http?: HttpConfig;
276
+ persistence?: PersistenceConfig;
277
+ app?: AppConfig;
278
+ notification?: NotificationConfig;
279
+ geofence?: GeofenceConfig;
280
+ logger?: LoggerConfig;
281
+ backgroundPermissionRationale?: BackgroundPermissionRationale;
282
+ /**
283
+ * Android only
284
+ * @default 'auto'
285
+ */
286
+ locationProvider?: LocationProviderSetting;
287
+ }
288
+ export interface ReadyOptions {
289
+ config?: Config;
290
+ /**
291
+ * true: config = defaults + given config (every launch). false: given config applied only on the very first
292
+ * ready(); afterwards persisted config wins.
293
+ * @default true
294
+ */
295
+ reset?: boolean;
296
+ }
297
+ export interface State {
298
+ enabled: boolean;
299
+ trackingMode: TrackingMode;
300
+ isMoving: boolean;
301
+ odometer: number;
302
+ backend: LocationBackend;
303
+ lastRecordAt: string | null;
304
+ /** fully populated with defaults */
305
+ config: Config;
306
+ }
307
+ export interface Coords {
308
+ latitude: number;
309
+ longitude: number;
310
+ accuracy: number;
311
+ altitude: number | null;
312
+ altitude_accuracy: number | null;
313
+ speed: number | null;
314
+ speed_accuracy: number | null;
315
+ heading: number | null;
316
+ heading_accuracy: number | null;
317
+ }
318
+ export interface ProviderState {
319
+ enabled: boolean;
320
+ gps: boolean;
321
+ network: boolean;
322
+ permission: 'always' | 'when_in_use' | 'denied';
323
+ accuracy: 'precise' | 'approximate' | 'none';
324
+ backend: LocationBackend;
325
+ }
326
+ export interface Location {
327
+ uuid: string;
328
+ event: RecordEvent;
329
+ /** fix time (ISO-8601 UTC ms); null if no location ever known */
330
+ timestamp: string | null;
331
+ /** record creation time */
332
+ recorded_at: string;
333
+ /** only present in HTTP bodies */
334
+ sent_at?: string;
335
+ elapsed_realtime_ms: number;
336
+ /** -1 if unavailable */
337
+ boot_count: number;
338
+ is_moving: boolean;
339
+ odometer: number;
340
+ mock: boolean;
341
+ coords: Coords | null;
342
+ activity: {
343
+ type: ActivityType;
344
+ confidence: number;
345
+ };
346
+ /** level 0..1, -1 unknown */
347
+ battery: {
348
+ level: number;
349
+ is_charging: boolean;
350
+ };
351
+ backend: LocationBackend | null;
352
+ extras?: Record<string, unknown>;
353
+ /** event 'geofence' only */
354
+ geofence?: {
355
+ identifier: string;
356
+ action: GeofenceAction;
357
+ extras?: Record<string, unknown>;
358
+ };
359
+ /** provider state when the record was created; the new state for event 'providerchange' */
360
+ provider?: ProviderState;
361
+ /**
362
+ * tracking_start: start|start_geofences|boot|restore|package_replaced|resume_notification;
363
+ * tracking_stop: stop|stop_on_stationary|stop_after_elapsed|terminate|permission_denied|service_start_failed|reboot|package_replaced
364
+ */
365
+ reason?: string;
366
+ /** event 'heartbeat' only, optional: how the heartbeat is scheduled */
367
+ heartbeat?: HeartbeatMeta;
368
+ }
369
+ /** Scheduling metadata of a `heartbeat` record (snake_case = wire format). */
370
+ export interface HeartbeatMeta {
371
+ strategy: 'exact' | 'listener_with_backup' | 'idle_paced';
372
+ /** heartbeat.minInterval (s) when the heartbeat was created */
373
+ min_interval: number;
374
+ /** heartbeat.maxInterval (s) when the heartbeat was created */
375
+ max_interval: number;
376
+ /** when the next heartbeat is expected (ISO-8601 UTC ms); null if unknown */
377
+ next_at: string | null;
378
+ /** the app is exempt from battery optimization */
379
+ battery_exempt: boolean;
380
+ /** the device was in deep Doze */
381
+ device_idle: boolean;
382
+ }
383
+ export type LocationRecord = Location;
384
+ export interface InsertLocationInput {
385
+ coords: Pick<Coords, 'latitude' | 'longitude'> & Partial<Coords>;
386
+ timestamp?: string;
387
+ event?: RecordEvent;
388
+ is_moving?: boolean;
389
+ extras?: Record<string, unknown>;
390
+ }
391
+ /**
392
+ * Either (latitude, longitude, radius) = circle, or vertices = polygon. For polygons, getGeofences() also returns
393
+ * the computed enclosing circle.
394
+ */
395
+ export interface Geofence {
396
+ identifier: string;
397
+ latitude?: number;
398
+ longitude?: number;
399
+ /** m */
400
+ radius?: number;
401
+ /** [[lat,lng], ...] >= 3 points */
402
+ vertices?: [number, number][];
403
+ /** @default true */
404
+ notifyOnEntry?: boolean;
405
+ /** @default true */
406
+ notifyOnExit?: boolean;
407
+ /** @default false */
408
+ notifyOnDwell?: boolean;
409
+ /**
410
+ * ms
411
+ * @default 30000
412
+ */
413
+ loiteringDelay?: number;
414
+ extras?: Record<string, unknown>;
415
+ }
416
+ export interface MotionChangeEvent {
417
+ isMoving: boolean;
418
+ location: Location;
419
+ }
420
+ export interface ActivityChangeEvent {
421
+ activity: ActivityType;
422
+ confidence: number;
423
+ }
424
+ export interface HeartbeatEvent {
425
+ location: Location;
426
+ }
427
+ export interface GeofenceEvent {
428
+ identifier: string;
429
+ action: GeofenceAction;
430
+ location: Location;
431
+ extras?: Record<string, unknown>;
432
+ }
433
+ export interface GeofencesChangeEvent {
434
+ on: Geofence[];
435
+ off: string[];
436
+ }
437
+ export interface HttpEvent {
438
+ success: boolean;
439
+ status: number;
440
+ responseText: string;
441
+ uuids: string[];
442
+ }
443
+ export interface ConnectivityChangeEvent {
444
+ connected: boolean;
445
+ type: ConnectivityType;
446
+ }
447
+ export interface PowerSaveChangeEvent {
448
+ isPowerSaveMode: boolean;
449
+ }
450
+ export interface EnabledChangeEvent {
451
+ enabled: boolean;
452
+ }
453
+ export interface NotificationActionEvent {
454
+ id: string;
455
+ }
456
+ export interface AuthorizationEvent {
457
+ success: boolean;
458
+ status: number;
459
+ error?: string;
460
+ response?: Record<string, unknown>;
461
+ }
462
+ export interface LocationTrackingEventMap {
463
+ location: Location;
464
+ motionchange: MotionChangeEvent;
465
+ activitychange: ActivityChangeEvent;
466
+ providerchange: ProviderState;
467
+ heartbeat: HeartbeatEvent;
468
+ geofence: GeofenceEvent;
469
+ geofenceschange: GeofencesChangeEvent;
470
+ http: HttpEvent;
471
+ connectivitychange: ConnectivityChangeEvent;
472
+ powersavechange: PowerSaveChangeEvent;
473
+ enabledchange: EnabledChangeEvent;
474
+ notificationaction: NotificationActionEvent;
475
+ authorization: AuthorizationEvent;
476
+ }
477
+ export type LocationTrackingEventName = keyof LocationTrackingEventMap;
478
+ export interface CurrentPositionOptions {
479
+ /** @default 3 */
480
+ samples?: number;
481
+ /**
482
+ * ms
483
+ * @default geolocation.locationTimeout
484
+ */
485
+ timeout?: number;
486
+ /**
487
+ * ms
488
+ * @default 0
489
+ */
490
+ maximumAge?: number;
491
+ /** @default 'high' */
492
+ desiredAccuracy?: DesiredAccuracy;
493
+ /** @default true */
494
+ persist?: boolean;
495
+ extras?: Record<string, unknown>;
496
+ }
497
+ export interface WatchPositionOptions {
498
+ /**
499
+ * ms
500
+ * @default 1000
501
+ */
502
+ interval?: number;
503
+ /** @default 'high' */
504
+ desiredAccuracy?: DesiredAccuracy;
505
+ /** @default false */
506
+ persist?: boolean;
507
+ extras?: Record<string, unknown>;
508
+ }
509
+ export type WatchPositionCallback = (location: Location | null, error?: {
510
+ code: ErrorCode;
511
+ message: string;
512
+ }) => void;
513
+ export interface HeartbeatStatus {
514
+ enabled: boolean;
515
+ minInterval: number;
516
+ maxInterval: number;
517
+ lastRecordAt: string | null;
518
+ lastHeartbeatAt: string | null;
519
+ nextHeartbeatAt: string | null;
520
+ strategy: HeartbeatStrategy;
521
+ canScheduleExactAlarms: boolean;
522
+ isIgnoringBatteryOptimizations: boolean;
523
+ isDeviceIdleMode: boolean;
524
+ isPowerSaveMode: boolean;
525
+ pendingHeartbeats: number;
526
+ }
527
+ export interface BatteryOptimizationStatus {
528
+ isIgnoringBatteryOptimizations: boolean;
529
+ canScheduleExactAlarms: boolean;
530
+ isDeviceIdleMode: boolean;
531
+ }
532
+ export interface PowerManagerInfo {
533
+ manufacturer: string;
534
+ available: boolean;
535
+ }
536
+ export interface DeviceInfo {
537
+ platform: 'android' | 'web';
538
+ manufacturer: string;
539
+ model: string;
540
+ brand: string;
541
+ osVersion: string;
542
+ sdkInt: number;
543
+ pluginVersion: string;
544
+ gmsAvailable: boolean;
545
+ hmsAvailable: boolean;
546
+ backend: LocationBackend;
547
+ packagedProviders: string[];
548
+ }
549
+ export interface Sensors {
550
+ accelerometer: boolean;
551
+ gyroscope: boolean;
552
+ magnetometer: boolean;
553
+ significantMotion: boolean;
554
+ stepCounter: boolean;
555
+ stepDetector: boolean;
556
+ barometer: boolean;
557
+ }
558
+ export interface PermissionStatus {
559
+ location: PermissionState;
560
+ backgroundLocation: PermissionState;
561
+ activityRecognition: PermissionState;
562
+ notifications: PermissionState;
563
+ }
564
+ export interface LogQuery {
565
+ start?: number;
566
+ end?: number;
567
+ level?: LogLevel;
568
+ limit?: number;
569
+ order?: 'asc' | 'desc';
570
+ }
571
+ export interface LocationTrackingPlugin {
572
+ /** Loads persisted config and state. Must resolve before most other methods (see NOT_READY rule). */
573
+ ready(options?: ReadyOptions): Promise<State>;
574
+ /** deep merge; arrays replaced; null resets key to default */
575
+ setConfig(options: {
576
+ config: Config;
577
+ }): Promise<State>;
578
+ /** Resets the config to defaults, then applies the given config. */
579
+ reset(options?: {
580
+ config?: Config;
581
+ }): Promise<State>;
582
+ getState(): Promise<State>;
583
+ /** Starts location tracking (mode 'location'). */
584
+ start(): Promise<State>;
585
+ /** Starts geofence-only tracking (mode 'geofences'). */
586
+ startGeofences(): Promise<State>;
587
+ stop(): Promise<State>;
588
+ /** Forces the motion state to moving or stationary. */
589
+ changePace(options: {
590
+ isMoving: boolean;
591
+ }): Promise<void>;
592
+ getCurrentPosition(options?: CurrentPositionOptions): Promise<Location>;
593
+ watchPosition(options: WatchPositionOptions, callback: WatchPositionCallback): Promise<CallbackID>;
594
+ clearWatch(options: {
595
+ id: CallbackID;
596
+ }): Promise<void>;
597
+ getOdometer(): Promise<{
598
+ odometer: number;
599
+ }>;
600
+ setOdometer(options: {
601
+ odometer: number;
602
+ }): Promise<{
603
+ odometer: number;
604
+ }>;
605
+ resetOdometer(): Promise<{
606
+ odometer: number;
607
+ }>;
608
+ getLocations(options?: {
609
+ limit?: number;
610
+ }): Promise<{
611
+ locations: Location[];
612
+ }>;
613
+ getCount(): Promise<{
614
+ count: number;
615
+ }>;
616
+ insertLocation(options: {
617
+ location: InsertLocationInput;
618
+ }): Promise<{
619
+ uuid: string;
620
+ }>;
621
+ destroyLocations(): Promise<{
622
+ count: number;
623
+ }>;
624
+ destroyLocation(options: {
625
+ uuid: string;
626
+ }): Promise<{
627
+ deleted: boolean;
628
+ }>;
629
+ /** uploads whole queue now; resolves with uploaded records */
630
+ sync(): Promise<{
631
+ locations: Location[];
632
+ }>;
633
+ addGeofence(options: {
634
+ geofence: Geofence;
635
+ }): Promise<void>;
636
+ addGeofences(options: {
637
+ geofences: Geofence[];
638
+ }): Promise<void>;
639
+ removeGeofence(options: {
640
+ identifier: string;
641
+ }): Promise<void>;
642
+ /** identifiers omitted (or null) = remove all; an empty array removes nothing */
643
+ removeGeofences(options?: {
644
+ identifiers?: string[];
645
+ }): Promise<void>;
646
+ getGeofences(): Promise<{
647
+ geofences: Geofence[];
648
+ }>;
649
+ getGeofence(options: {
650
+ identifier: string;
651
+ }): Promise<{
652
+ geofence: Geofence | null;
653
+ }>;
654
+ geofenceExists(options: {
655
+ identifier: string;
656
+ }): Promise<{
657
+ exists: boolean;
658
+ }>;
659
+ getHeartbeatStatus(): Promise<HeartbeatStatus>;
660
+ getProviderState(): Promise<ProviderState>;
661
+ isPowerSaveMode(): Promise<{
662
+ isPowerSaveMode: boolean;
663
+ }>;
664
+ getBatteryOptimizationStatus(): Promise<BatteryOptimizationStatus>;
665
+ openBatteryOptimizationSettings(): Promise<{
666
+ opened: boolean;
667
+ }>;
668
+ getPowerManagerInfo(): Promise<PowerManagerInfo>;
669
+ openPowerManagerSettings(): Promise<{
670
+ opened: boolean;
671
+ }>;
672
+ openLocationSettings(): Promise<{
673
+ opened: boolean;
674
+ }>;
675
+ openAppSettings(): Promise<{
676
+ opened: boolean;
677
+ }>;
678
+ getDeviceInfo(): Promise<DeviceInfo>;
679
+ getSensors(): Promise<Sensors>;
680
+ checkPermissions(): Promise<PermissionStatus>;
681
+ /** default all four, order: location, notifications, activityRecognition, backgroundLocation */
682
+ requestPermissions(options?: {
683
+ permissions?: PermissionType[];
684
+ }): Promise<PermissionStatus>;
685
+ log(options: {
686
+ level: Exclude<LogLevel, 'off'>;
687
+ message: string;
688
+ }): Promise<void>;
689
+ getLog(options?: LogQuery): Promise<{
690
+ log: string;
691
+ }>;
692
+ destroyLog(): Promise<void>;
693
+ uploadLog(options: {
694
+ url: string;
695
+ headers?: Record<string, string>;
696
+ params?: Record<string, unknown>;
697
+ }): Promise<{
698
+ success: boolean;
699
+ status: number;
700
+ }>;
701
+ emailLog(options: {
702
+ email: string;
703
+ subject?: string;
704
+ }): Promise<void>;
705
+ addListener(eventName: 'location', listenerFunc: (e: Location) => void): Promise<PluginListenerHandle>;
706
+ addListener(eventName: 'motionchange', listenerFunc: (e: MotionChangeEvent) => void): Promise<PluginListenerHandle>;
707
+ addListener(eventName: 'activitychange', listenerFunc: (e: ActivityChangeEvent) => void): Promise<PluginListenerHandle>;
708
+ addListener(eventName: 'providerchange', listenerFunc: (e: ProviderState) => void): Promise<PluginListenerHandle>;
709
+ addListener(eventName: 'heartbeat', listenerFunc: (e: HeartbeatEvent) => void): Promise<PluginListenerHandle>;
710
+ addListener(eventName: 'geofence', listenerFunc: (e: GeofenceEvent) => void): Promise<PluginListenerHandle>;
711
+ addListener(eventName: 'geofenceschange', listenerFunc: (e: GeofencesChangeEvent) => void): Promise<PluginListenerHandle>;
712
+ addListener(eventName: 'http', listenerFunc: (e: HttpEvent) => void): Promise<PluginListenerHandle>;
713
+ addListener(eventName: 'connectivitychange', listenerFunc: (e: ConnectivityChangeEvent) => void): Promise<PluginListenerHandle>;
714
+ addListener(eventName: 'powersavechange', listenerFunc: (e: PowerSaveChangeEvent) => void): Promise<PluginListenerHandle>;
715
+ addListener(eventName: 'enabledchange', listenerFunc: (e: EnabledChangeEvent) => void): Promise<PluginListenerHandle>;
716
+ addListener(eventName: 'notificationaction', listenerFunc: (e: NotificationActionEvent) => void): Promise<PluginListenerHandle>;
717
+ addListener(eventName: 'authorization', listenerFunc: (e: AuthorizationEvent) => void): Promise<PluginListenerHandle>;
718
+ removeAllListeners(): Promise<void>;
719
+ }