react-native-nitro-geolocation 1.2.6 → 1.3.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/README.md +52 -295
- package/android/build.gradle +1 -0
- package/android/src/main/AndroidManifest.xml +39 -0
- package/android/src/main/java/com/margelo/nitro/nitrogeolocation/AndroidFusedLocationProvider.kt +310 -0
- package/android/src/main/java/com/margelo/nitro/nitrogeolocation/AndroidFusedRequestFactory.kt +31 -0
- package/android/src/main/java/com/margelo/nitro/nitrogeolocation/AndroidGeolocationConversions.kt +71 -0
- package/android/src/main/java/com/margelo/nitro/nitrogeolocation/AndroidGeolocationErrors.kt +85 -0
- package/android/src/main/java/com/margelo/nitro/nitrogeolocation/AndroidGeolocationOptions.kt +92 -0
- package/android/src/main/java/com/margelo/nitro/nitrogeolocation/AndroidLocationSettings.kt +3 -0
- package/android/src/main/java/com/margelo/nitro/nitrogeolocation/AndroidProviderRoute.kt +74 -0
- package/android/src/main/java/com/margelo/nitro/nitrogeolocation/NitroBackgroundLocation.kt +132 -0
- package/android/src/main/java/com/margelo/nitro/nitrogeolocation/NitroGeolocation.kt +219 -476
- package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/AndroidBackgroundHttpSync.kt +134 -0
- package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/AndroidBackgroundPermissions.kt +196 -0
- package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/AndroidBackgroundSerialization.kt +266 -0
- package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroActivityRecognitionReceiver.kt +13 -0
- package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroBackgroundEventHub.kt +65 -0
- package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroBackgroundHeadlessTaskService.kt +58 -0
- package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroBackgroundLocationController.kt +710 -0
- package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroBackgroundLocationService.kt +48 -0
- package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroBackgroundNotificationFactory.kt +37 -0
- package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroBackgroundStore.kt +655 -0
- package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroBootReceiver.kt +26 -0
- package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroGeofenceReceiver.kt +14 -0
- package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroLocationUpdateReceiver.kt +37 -0
- package/android/src/test/java/com/margelo/nitro/nitrogeolocation/AndroidFusedLocationProviderTest.kt +64 -0
- package/android/src/test/java/com/margelo/nitro/nitrogeolocation/AndroidProviderRouteTest.kt +116 -0
- package/ios/IOSBackgroundHttpSync.swift +126 -0
- package/ios/IOSBackgroundLocationDelegate.swift +36 -0
- package/ios/IOSBackgroundMotion.swift +55 -0
- package/ios/IOSBackgroundSerialization.swift +539 -0
- package/ios/IOSGeolocationConversions.swift +131 -0
- package/ios/IOSGeolocationDelegate.swift +31 -0
- package/ios/IOSGeolocationErrors.swift +39 -0
- package/ios/IOSGeolocationOptions.swift +135 -0
- package/ios/NitroBackgroundLocation.swift +849 -0
- package/ios/NitroGeolocation.swift +14 -347
- package/nitrogen/generated/android/c++/JActivityRecognitionOptions.hpp +69 -0
- package/nitrogen/generated/android/c++/JAndroidBackgroundLocationOptions.hpp +74 -0
- package/nitrogen/generated/android/c++/JAndroidBackgroundLocationStatus.hpp +67 -0
- package/nitrogen/generated/android/c++/JAndroidBackgroundProvider.hpp +61 -0
- package/nitrogen/generated/android/c++/JAndroidForegroundServiceOptions.hpp +90 -0
- package/nitrogen/generated/android/c++/JBackgroundEventEnvelope.hpp +129 -0
- package/nitrogen/generated/android/c++/JBackgroundEventType.hpp +70 -0
- package/nitrogen/generated/android/c++/JBackgroundHttpMethod.hpp +61 -0
- package/nitrogen/generated/android/c++/JBackgroundHttpSyncOptions.hpp +131 -0
- package/nitrogen/generated/android/c++/JBackgroundHttpSyncResult.hpp +111 -0
- package/nitrogen/generated/android/c++/JBackgroundLocation.hpp +110 -0
- package/nitrogen/generated/android/c++/JBackgroundLocationOptions.hpp +162 -0
- package/nitrogen/generated/android/c++/JBackgroundLocationSource.hpp +73 -0
- package/nitrogen/generated/android/c++/JBackgroundLocationState.hpp +70 -0
- package/nitrogen/generated/android/c++/JBackgroundLocationStatus.hpp +126 -0
- package/nitrogen/generated/android/c++/JBackgroundPermissionResult.hpp +79 -0
- package/nitrogen/generated/android/c++/JBackgroundPermissionStatus.hpp +64 -0
- package/nitrogen/generated/android/c++/JBackgroundTrackingMode.hpp +61 -0
- package/nitrogen/generated/android/c++/JBatterySnapshot.hpp +61 -0
- package/nitrogen/generated/android/c++/JDetectedActivity.hpp +66 -0
- package/nitrogen/generated/android/c++/JDetectedActivityType.hpp +76 -0
- package/nitrogen/generated/android/c++/JFunc_void_BackgroundEventEnvelope.hpp +114 -0
- package/nitrogen/generated/android/c++/JFunc_void_BackgroundLocation.hpp +95 -0
- package/nitrogen/generated/android/c++/JGeofenceEvent.hpp +94 -0
- package/nitrogen/generated/android/c++/JGeofenceRegion.hpp +112 -0
- package/nitrogen/generated/android/c++/JGeofenceTransition.hpp +61 -0
- package/nitrogen/generated/android/c++/JGeofencingOptions.hpp +82 -0
- package/nitrogen/generated/android/c++/JGetStoredBackgroundEventsOptions.hpp +90 -0
- package/nitrogen/generated/android/c++/JGetStoredBackgroundLocationsOptions.hpp +69 -0
- package/nitrogen/generated/android/c++/JHybridNitroBackgroundLocationSpec.cpp +662 -0
- package/nitrogen/generated/android/c++/JHybridNitroBackgroundLocationSpec.hpp +89 -0
- package/nitrogen/generated/android/c++/JIOSBackgroundActivityType.hpp +67 -0
- package/nitrogen/generated/android/c++/JIOSBackgroundLocationOptions.hpp +79 -0
- package/nitrogen/generated/android/c++/JIOSBackgroundLocationStatus.hpp +61 -0
- package/nitrogen/generated/android/c++/JLocationProviderStatus.hpp +5 -1
- package/nitrogen/generated/android/c++/JStoredBackgroundEventEnvelope.hpp +115 -0
- package/nitrogen/generated/android/c++/JStoredBackgroundLocation.hpp +122 -0
- package/nitrogen/generated/android/c++/JVariant_NullType_Boolean_String_Double.cpp +34 -0
- package/nitrogen/generated/android/c++/JVariant_NullType_Boolean_String_Double.hpp +100 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/ActivityRecognitionOptions.kt +66 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/AndroidBackgroundLocationOptions.kt +66 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/AndroidBackgroundLocationStatus.kt +61 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/AndroidBackgroundProvider.kt +24 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/AndroidForegroundServiceOptions.kt +91 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundEventEnvelope.kt +96 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundEventType.kt +27 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundHttpMethod.kt +24 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundHttpSyncOptions.kt +101 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundHttpSyncResult.kt +71 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundLocation.kt +96 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundLocationOptions.kt +136 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundLocationSource.kt +28 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundLocationState.kt +27 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundLocationStatus.kt +116 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundPermissionResult.kt +71 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundPermissionStatus.kt +25 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundTrackingMode.kt +24 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BatterySnapshot.kt +56 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/DetectedActivity.kt +61 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/DetectedActivityType.kt +29 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/Func_void_BackgroundEventEnvelope.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/Func_void_BackgroundLocation.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GeofenceEvent.kt +66 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GeofenceRegion.kt +96 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GeofenceTransition.kt +24 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GeofencingOptions.kt +56 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GetStoredBackgroundEventsOptions.kt +66 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GetStoredBackgroundLocationsOptions.kt +66 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/HybridNitroBackgroundLocationSpec.kt +174 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/IOSBackgroundActivityType.kt +26 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/IOSBackgroundLocationOptions.kt +76 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/IOSBackgroundLocationStatus.kt +56 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/LocationProviderStatus.kt +7 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/StoredBackgroundEventEnvelope.kt +76 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/StoredBackgroundLocation.kt +111 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/Variant_NullType_Boolean_String_Double.kt +88 -0
- package/nitrogen/generated/android/nitrogeolocation+autolinking.cmake +3 -0
- package/nitrogen/generated/android/nitrogeolocationOnLoad.cpp +20 -0
- package/nitrogen/generated/ios/NitroGeolocation-Swift-Cxx-Bridge.cpp +104 -15
- package/nitrogen/generated/ios/NitroGeolocation-Swift-Cxx-Bridge.hpp +1107 -50
- package/nitrogen/generated/ios/NitroGeolocation-Swift-Cxx-Umbrella.hpp +102 -0
- package/nitrogen/generated/ios/NitroGeolocationAutolinking.mm +8 -0
- package/nitrogen/generated/ios/NitroGeolocationAutolinking.swift +15 -3
- package/nitrogen/generated/ios/c++/HybridNitroBackgroundLocationSpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridNitroBackgroundLocationSpecSwift.hpp +416 -0
- package/nitrogen/generated/ios/swift/ActivityRecognitionOptions.swift +96 -0
- package/nitrogen/generated/ios/swift/AndroidBackgroundLocationOptions.swift +76 -0
- package/nitrogen/generated/ios/swift/AndroidBackgroundLocationStatus.swift +58 -0
- package/nitrogen/generated/ios/swift/AndroidBackgroundProvider.swift +44 -0
- package/nitrogen/generated/ios/swift/AndroidForegroundServiceOptions.swift +160 -0
- package/nitrogen/generated/ios/swift/BackgroundEventEnvelope.swift +110 -0
- package/nitrogen/generated/ios/swift/BackgroundEventType.swift +56 -0
- package/nitrogen/generated/ios/swift/BackgroundHttpMethod.swift +44 -0
- package/nitrogen/generated/ios/swift/BackgroundHttpSyncOptions.swift +259 -0
- package/nitrogen/generated/ios/swift/BackgroundHttpSyncResult.swift +87 -0
- package/nitrogen/generated/ios/swift/BackgroundLocation.swift +118 -0
- package/nitrogen/generated/ios/swift/BackgroundLocationOptions.swift +292 -0
- package/nitrogen/generated/ios/swift/BackgroundLocationSource.swift +60 -0
- package/nitrogen/generated/ios/swift/BackgroundLocationState.swift +56 -0
- package/nitrogen/generated/ios/swift/BackgroundLocationStatus.swift +124 -0
- package/nitrogen/generated/ios/swift/BackgroundPermissionResult.swift +81 -0
- package/nitrogen/generated/ios/swift/BackgroundPermissionStatus.swift +48 -0
- package/nitrogen/generated/ios/swift/BackgroundTrackingMode.swift +44 -0
- package/nitrogen/generated/ios/swift/BatterySnapshot.swift +60 -0
- package/nitrogen/generated/ios/swift/DetectedActivity.swift +39 -0
- package/nitrogen/generated/ios/swift/DetectedActivityType.swift +64 -0
- package/nitrogen/generated/ios/swift/Func_void_BackgroundEventEnvelope.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_BackgroundHttpSyncResult.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_BackgroundLocation.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_BackgroundLocationStatus.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_BackgroundPermissionResult.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_std__optional_BackgroundLocationOptions_.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_std__vector_GeofenceRegion_.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_std__vector_StoredBackgroundEventEnvelope_.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_std__vector_StoredBackgroundLocation_.swift +46 -0
- package/nitrogen/generated/ios/swift/GeofenceEvent.swift +50 -0
- package/nitrogen/generated/ios/swift/GeofenceRegion.swift +195 -0
- package/nitrogen/generated/ios/swift/GeofenceTransition.swift +44 -0
- package/nitrogen/generated/ios/swift/GeofencingOptions.swift +66 -0
- package/nitrogen/generated/ios/swift/GetStoredBackgroundEventsOptions.swift +102 -0
- package/nitrogen/generated/ios/swift/GetStoredBackgroundLocationsOptions.swift +96 -0
- package/nitrogen/generated/ios/swift/HybridNitroBackgroundLocationSpec.swift +81 -0
- package/nitrogen/generated/ios/swift/HybridNitroBackgroundLocationSpec_cxx.swift +654 -0
- package/nitrogen/generated/ios/swift/IOSBackgroundActivityType.swift +52 -0
- package/nitrogen/generated/ios/swift/IOSBackgroundLocationOptions.swift +125 -0
- package/nitrogen/generated/ios/swift/IOSBackgroundLocationStatus.swift +34 -0
- package/nitrogen/generated/ios/swift/LocationProviderStatus.swift +19 -1
- package/nitrogen/generated/ios/swift/StoredBackgroundEventEnvelope.swift +54 -0
- package/nitrogen/generated/ios/swift/StoredBackgroundLocation.swift +120 -0
- package/nitrogen/generated/ios/swift/Variant_NullType_Bool_String_Double.swift +34 -0
- package/nitrogen/generated/shared/c++/ActivityRecognitionOptions.hpp +95 -0
- package/nitrogen/generated/shared/c++/AndroidBackgroundLocationOptions.hpp +100 -0
- package/nitrogen/generated/shared/c++/AndroidBackgroundLocationStatus.hpp +93 -0
- package/nitrogen/generated/shared/c++/AndroidBackgroundProvider.hpp +80 -0
- package/nitrogen/generated/shared/c++/AndroidForegroundServiceOptions.hpp +116 -0
- package/nitrogen/generated/shared/c++/BackgroundEventEnvelope.hpp +140 -0
- package/nitrogen/generated/shared/c++/BackgroundEventType.hpp +92 -0
- package/nitrogen/generated/shared/c++/BackgroundHttpMethod.hpp +80 -0
- package/nitrogen/generated/shared/c++/BackgroundHttpSyncOptions.hpp +129 -0
- package/nitrogen/generated/shared/c++/BackgroundHttpSyncResult.hpp +101 -0
- package/nitrogen/generated/shared/c++/BackgroundLocation.hpp +134 -0
- package/nitrogen/generated/shared/c++/BackgroundLocationOptions.hpp +174 -0
- package/nitrogen/generated/shared/c++/BackgroundLocationSource.hpp +96 -0
- package/nitrogen/generated/shared/c++/BackgroundLocationState.hpp +92 -0
- package/nitrogen/generated/shared/c++/BackgroundLocationStatus.hpp +158 -0
- package/nitrogen/generated/shared/c++/BackgroundPermissionResult.hpp +107 -0
- package/nitrogen/generated/shared/c++/BackgroundPermissionStatus.hpp +84 -0
- package/nitrogen/generated/shared/c++/BackgroundTrackingMode.hpp +80 -0
- package/nitrogen/generated/shared/c++/BatterySnapshot.hpp +87 -0
- package/nitrogen/generated/shared/c++/DetectedActivity.hpp +92 -0
- package/nitrogen/generated/shared/c++/DetectedActivityType.hpp +100 -0
- package/nitrogen/generated/shared/c++/GeofenceEvent.hpp +103 -0
- package/nitrogen/generated/shared/c++/GeofenceRegion.hpp +123 -0
- package/nitrogen/generated/shared/c++/GeofenceTransition.hpp +80 -0
- package/nitrogen/generated/shared/c++/GeofencingOptions.hpp +90 -0
- package/nitrogen/generated/shared/c++/GetStoredBackgroundEventsOptions.hpp +98 -0
- package/nitrogen/generated/shared/c++/GetStoredBackgroundLocationsOptions.hpp +95 -0
- package/nitrogen/generated/shared/c++/HybridNitroBackgroundLocationSpec.cpp +47 -0
- package/nitrogen/generated/shared/c++/HybridNitroBackgroundLocationSpec.hpp +133 -0
- package/nitrogen/generated/shared/c++/IOSBackgroundActivityType.hpp +88 -0
- package/nitrogen/generated/shared/c++/IOSBackgroundLocationOptions.hpp +105 -0
- package/nitrogen/generated/shared/c++/IOSBackgroundLocationStatus.hpp +87 -0
- package/nitrogen/generated/shared/c++/LocationProviderStatus.hpp +5 -1
- package/nitrogen/generated/shared/c++/StoredBackgroundEventEnvelope.hpp +108 -0
- package/nitrogen/generated/shared/c++/StoredBackgroundLocation.hpp +146 -0
- package/package.json +17 -6
- package/src/NitroGeolocation.nitro.ts +4 -4
- package/src/api/getCurrentPosition.ts +1 -1
- package/src/api/requestLocationSettings.ts +3 -2
- package/src/background/NitroBackgroundLocation.nitro.ts +83 -0
- package/src/background/index.ts +200 -0
- package/src/background/index.web.ts +120 -0
- package/src/background/task.ts +13 -0
- package/src/background/types.ts +328 -0
- package/src/compat/index.web.ts +141 -0
- package/src/index.tsx +3 -0
- package/src/index.web.tsx +41 -0
- package/src/publicTypes.ts +6 -5
- package/src/types.ts +3 -0
- package/src/web/browser.ts +171 -0
- package/src/web/index.ts +167 -0
- package/src/web/useWatchPosition.ts +76 -0
- package/src/web/watch.ts +81 -0
- package/src/devtools/index.test.ts +0 -54
- package/src/utils/errors.test.ts +0 -65
- package/src/utils/provider.test.ts +0 -303
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
package com.margelo.nitro.nitrogeolocation.background
|
|
2
|
+
|
|
3
|
+
import com.margelo.nitro.nitrogeolocation.BackgroundHttpSyncOptions
|
|
4
|
+
import com.margelo.nitro.nitrogeolocation.BackgroundHttpSyncResult
|
|
5
|
+
import com.margelo.nitro.nitrogeolocation.StoredBackgroundLocation
|
|
6
|
+
import java.io.OutputStreamWriter
|
|
7
|
+
import java.net.HttpURLConnection
|
|
8
|
+
import java.net.URL
|
|
9
|
+
|
|
10
|
+
internal class AndroidBackgroundHttpSync {
|
|
11
|
+
fun uploadLocationsWithRetry(
|
|
12
|
+
sync: BackgroundHttpSyncOptions,
|
|
13
|
+
locations: Array<StoredBackgroundLocation>
|
|
14
|
+
): BackgroundHttpSyncResult {
|
|
15
|
+
val ids = locations.map { it.id }
|
|
16
|
+
val maxAttempts = if (sync.retry == true) {
|
|
17
|
+
(sync.maxRetries?.toInt()?.takeIf { it >= 0 } ?: 3) + 1
|
|
18
|
+
} else {
|
|
19
|
+
1
|
|
20
|
+
}
|
|
21
|
+
var lastStatus: Int? = null
|
|
22
|
+
var lastError: String? = null
|
|
23
|
+
|
|
24
|
+
if (sync.batch == false) {
|
|
25
|
+
return uploadSingleLocationsWithRetry(sync, locations, maxAttempts)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
repeat(maxAttempts) { attempt ->
|
|
29
|
+
try {
|
|
30
|
+
val response = uploadLocations(sync, locations)
|
|
31
|
+
lastStatus = response
|
|
32
|
+
if (response in 200..299) {
|
|
33
|
+
return BackgroundHttpSyncResult(
|
|
34
|
+
true,
|
|
35
|
+
response.toDouble(),
|
|
36
|
+
ids.toTypedArray(),
|
|
37
|
+
emptyArray(),
|
|
38
|
+
null
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
lastError = "HTTP sync failed with status $response"
|
|
42
|
+
} catch (error: Exception) {
|
|
43
|
+
lastError = error.message ?: "HTTP sync failed"
|
|
44
|
+
}
|
|
45
|
+
if (attempt < maxAttempts - 1) {
|
|
46
|
+
Thread.sleep(1_000L)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return BackgroundHttpSyncResult(
|
|
51
|
+
false,
|
|
52
|
+
lastStatus?.toDouble(),
|
|
53
|
+
emptyArray(),
|
|
54
|
+
ids.toTypedArray(),
|
|
55
|
+
lastError ?: "HTTP sync failed"
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
private fun uploadLocations(
|
|
60
|
+
sync: BackgroundHttpSyncOptions,
|
|
61
|
+
locations: Array<StoredBackgroundLocation>
|
|
62
|
+
): Int {
|
|
63
|
+
val connection = createConnection(sync)
|
|
64
|
+
OutputStreamWriter(connection.outputStream).use { writer ->
|
|
65
|
+
writer.write(sync.batchBody(locations).toString())
|
|
66
|
+
}
|
|
67
|
+
return connection.responseCode
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private fun uploadSingleLocationsWithRetry(
|
|
71
|
+
sync: BackgroundHttpSyncOptions,
|
|
72
|
+
locations: Array<StoredBackgroundLocation>,
|
|
73
|
+
maxAttempts: Int
|
|
74
|
+
): BackgroundHttpSyncResult {
|
|
75
|
+
val synced = mutableListOf<String>()
|
|
76
|
+
val failed = mutableListOf<String>()
|
|
77
|
+
var lastStatus: Int? = null
|
|
78
|
+
var lastError: String? = null
|
|
79
|
+
|
|
80
|
+
for (location in locations) {
|
|
81
|
+
var didSync = false
|
|
82
|
+
for (attempt in 0 until maxAttempts) {
|
|
83
|
+
try {
|
|
84
|
+
val response = uploadLocation(sync, location)
|
|
85
|
+
lastStatus = response
|
|
86
|
+
if (response in 200..299) {
|
|
87
|
+
synced += location.id
|
|
88
|
+
didSync = true
|
|
89
|
+
break
|
|
90
|
+
}
|
|
91
|
+
lastError = "HTTP sync failed with status $response"
|
|
92
|
+
} catch (error: Exception) {
|
|
93
|
+
lastError = error.message ?: "HTTP sync failed"
|
|
94
|
+
}
|
|
95
|
+
if (!didSync && attempt < maxAttempts - 1) {
|
|
96
|
+
Thread.sleep(1_000L)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (!didSync) {
|
|
100
|
+
failed += location.id
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return BackgroundHttpSyncResult(
|
|
105
|
+
failed.isEmpty(),
|
|
106
|
+
lastStatus?.toDouble(),
|
|
107
|
+
synced.toTypedArray(),
|
|
108
|
+
failed.toTypedArray(),
|
|
109
|
+
if (failed.isEmpty()) null else lastError ?: "HTTP sync failed"
|
|
110
|
+
)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
private fun uploadLocation(
|
|
114
|
+
sync: BackgroundHttpSyncOptions,
|
|
115
|
+
location: StoredBackgroundLocation
|
|
116
|
+
): Int {
|
|
117
|
+
val connection = createConnection(sync)
|
|
118
|
+
OutputStreamWriter(connection.outputStream).use { writer ->
|
|
119
|
+
writer.write(sync.singleBody(location).toString())
|
|
120
|
+
}
|
|
121
|
+
return connection.responseCode
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
private fun createConnection(sync: BackgroundHttpSyncOptions): HttpURLConnection {
|
|
125
|
+
return (URL(sync.url).openConnection() as HttpURLConnection).apply {
|
|
126
|
+
requestMethod = sync.method?.name ?: "POST"
|
|
127
|
+
connectTimeout = 15_000
|
|
128
|
+
readTimeout = 15_000
|
|
129
|
+
doOutput = true
|
|
130
|
+
setRequestProperty("Content-Type", "application/json")
|
|
131
|
+
sync.headers?.forEach { (key, value) -> setRequestProperty(key, value) }
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
package com.margelo.nitro.nitrogeolocation.background
|
|
2
|
+
|
|
3
|
+
import android.Manifest
|
|
4
|
+
import android.content.Context
|
|
5
|
+
import android.content.Intent
|
|
6
|
+
import android.content.pm.PackageManager
|
|
7
|
+
import android.net.Uri
|
|
8
|
+
import android.os.Build
|
|
9
|
+
import android.os.Handler
|
|
10
|
+
import android.os.Looper
|
|
11
|
+
import android.provider.Settings
|
|
12
|
+
import androidx.core.content.ContextCompat
|
|
13
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
14
|
+
import com.facebook.react.modules.core.PermissionAwareActivity
|
|
15
|
+
import com.facebook.react.modules.core.PermissionListener
|
|
16
|
+
import com.margelo.nitro.nitrogeolocation.*
|
|
17
|
+
import java.util.concurrent.CountDownLatch
|
|
18
|
+
import java.util.concurrent.TimeUnit
|
|
19
|
+
|
|
20
|
+
internal class AndroidBackgroundPermissions(
|
|
21
|
+
private val appContext: Context,
|
|
22
|
+
private val configProvider: () -> BackgroundLocationOptions?
|
|
23
|
+
) {
|
|
24
|
+
fun checkBackgroundPermission(): BackgroundPermissionResult {
|
|
25
|
+
val foreground = foregroundPermission()
|
|
26
|
+
val background = backgroundPermission()
|
|
27
|
+
return BackgroundPermissionResult(
|
|
28
|
+
foreground,
|
|
29
|
+
background,
|
|
30
|
+
accuracyAuthorization(),
|
|
31
|
+
Build.VERSION.SDK_INT < Build.VERSION_CODES.R,
|
|
32
|
+
background != BackgroundPermissionStatus.GRANTED
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
fun requestBackgroundPermission(reactContext: ReactApplicationContext): BackgroundPermissionResult {
|
|
37
|
+
val activity = reactContext.currentActivity
|
|
38
|
+
if (activity != null) {
|
|
39
|
+
val permissions = mutableListOf<String>()
|
|
40
|
+
if (foregroundPermission() != PermissionStatus.GRANTED) {
|
|
41
|
+
permissions += Manifest.permission.ACCESS_FINE_LOCATION
|
|
42
|
+
permissions += Manifest.permission.ACCESS_COARSE_LOCATION
|
|
43
|
+
}
|
|
44
|
+
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q &&
|
|
45
|
+
backgroundPermission() != BackgroundPermissionStatus.GRANTED) {
|
|
46
|
+
permissions += Manifest.permission.ACCESS_BACKGROUND_LOCATION
|
|
47
|
+
}
|
|
48
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
|
|
49
|
+
configProvider()?.android?.requestNotificationPermission != false &&
|
|
50
|
+
notificationPermission() != PermissionStatus.GRANTED) {
|
|
51
|
+
permissions += Manifest.permission.POST_NOTIFICATIONS
|
|
52
|
+
}
|
|
53
|
+
if (permissions.isNotEmpty()) {
|
|
54
|
+
requestPermissionsAndWait(activity, permissions.toTypedArray())
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R &&
|
|
58
|
+
backgroundPermission() != BackgroundPermissionStatus.GRANTED) {
|
|
59
|
+
openAppLocationSettings()
|
|
60
|
+
}
|
|
61
|
+
return checkBackgroundPermission()
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
fun openAppLocationSettings() {
|
|
65
|
+
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
|
|
66
|
+
.setData(Uri.fromParts("package", appContext.packageName, null))
|
|
67
|
+
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
|
68
|
+
appContext.startActivity(intent)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
fun foregroundPermission(): PermissionStatus {
|
|
72
|
+
val fine = ContextCompat.checkSelfPermission(
|
|
73
|
+
appContext,
|
|
74
|
+
Manifest.permission.ACCESS_FINE_LOCATION
|
|
75
|
+
) == PackageManager.PERMISSION_GRANTED
|
|
76
|
+
val coarse = ContextCompat.checkSelfPermission(
|
|
77
|
+
appContext,
|
|
78
|
+
Manifest.permission.ACCESS_COARSE_LOCATION
|
|
79
|
+
) == PackageManager.PERMISSION_GRANTED
|
|
80
|
+
return if (fine || coarse) PermissionStatus.GRANTED else PermissionStatus.DENIED
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
fun backgroundPermission(): BackgroundPermissionStatus {
|
|
84
|
+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
|
|
85
|
+
return BackgroundPermissionStatus.GRANTED
|
|
86
|
+
}
|
|
87
|
+
return if (
|
|
88
|
+
ContextCompat.checkSelfPermission(
|
|
89
|
+
appContext,
|
|
90
|
+
Manifest.permission.ACCESS_BACKGROUND_LOCATION
|
|
91
|
+
) == PackageManager.PERMISSION_GRANTED
|
|
92
|
+
) {
|
|
93
|
+
BackgroundPermissionStatus.GRANTED
|
|
94
|
+
} else {
|
|
95
|
+
BackgroundPermissionStatus.DENIED
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
fun notificationPermission(): PermissionStatus? {
|
|
100
|
+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) return null
|
|
101
|
+
return if (
|
|
102
|
+
ContextCompat.checkSelfPermission(
|
|
103
|
+
appContext,
|
|
104
|
+
Manifest.permission.POST_NOTIFICATIONS
|
|
105
|
+
) == PackageManager.PERMISSION_GRANTED
|
|
106
|
+
) {
|
|
107
|
+
PermissionStatus.GRANTED
|
|
108
|
+
} else {
|
|
109
|
+
PermissionStatus.DENIED
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
fun accuracyAuthorization(): AccuracyAuthorization {
|
|
114
|
+
val fine = ContextCompat.checkSelfPermission(
|
|
115
|
+
appContext,
|
|
116
|
+
Manifest.permission.ACCESS_FINE_LOCATION
|
|
117
|
+
) == PackageManager.PERMISSION_GRANTED
|
|
118
|
+
val coarse = ContextCompat.checkSelfPermission(
|
|
119
|
+
appContext,
|
|
120
|
+
Manifest.permission.ACCESS_COARSE_LOCATION
|
|
121
|
+
) == PackageManager.PERMISSION_GRANTED
|
|
122
|
+
return when {
|
|
123
|
+
fine -> AccuracyAuthorization.FULL
|
|
124
|
+
coarse -> AccuracyAuthorization.REDUCED
|
|
125
|
+
else -> AccuracyAuthorization.UNKNOWN
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
private fun requestPermissionsAndWait(
|
|
130
|
+
activity: android.app.Activity,
|
|
131
|
+
permissions: Array<String>
|
|
132
|
+
) {
|
|
133
|
+
val permissionAware = activity as? PermissionAwareActivity
|
|
134
|
+
val latch = CountDownLatch(1)
|
|
135
|
+
var lifecycleCallbacks: android.app.Application.ActivityLifecycleCallbacks? = null
|
|
136
|
+
fun finishNonPermissionAwareRequest() {
|
|
137
|
+
latch.countDown()
|
|
138
|
+
lifecycleCallbacks?.let {
|
|
139
|
+
runCatching {
|
|
140
|
+
activity.application.unregisterActivityLifecycleCallbacks(it)
|
|
141
|
+
}
|
|
142
|
+
lifecycleCallbacks = null
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
if (permissionAware == null) {
|
|
146
|
+
lifecycleCallbacks = object : android.app.Application.ActivityLifecycleCallbacks {
|
|
147
|
+
override fun onActivityCreated(
|
|
148
|
+
activity: android.app.Activity,
|
|
149
|
+
savedInstanceState: android.os.Bundle?
|
|
150
|
+
) = Unit
|
|
151
|
+
override fun onActivityStarted(activity: android.app.Activity) = Unit
|
|
152
|
+
override fun onActivityResumed(resumedActivity: android.app.Activity) {
|
|
153
|
+
if (resumedActivity === activity) {
|
|
154
|
+
finishNonPermissionAwareRequest()
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
override fun onActivityPaused(activity: android.app.Activity) = Unit
|
|
158
|
+
override fun onActivityStopped(activity: android.app.Activity) = Unit
|
|
159
|
+
override fun onActivitySaveInstanceState(
|
|
160
|
+
activity: android.app.Activity,
|
|
161
|
+
outState: android.os.Bundle
|
|
162
|
+
) = Unit
|
|
163
|
+
override fun onActivityDestroyed(activity: android.app.Activity) = Unit
|
|
164
|
+
}
|
|
165
|
+
activity.application.registerActivityLifecycleCallbacks(lifecycleCallbacks)
|
|
166
|
+
}
|
|
167
|
+
Handler(Looper.getMainLooper()).post {
|
|
168
|
+
if (permissionAware == null) {
|
|
169
|
+
androidx.core.app.ActivityCompat.requestPermissions(activity, permissions, 9473)
|
|
170
|
+
Handler(Looper.getMainLooper()).postDelayed(
|
|
171
|
+
{ finishNonPermissionAwareRequest() },
|
|
172
|
+
60_000
|
|
173
|
+
)
|
|
174
|
+
} else {
|
|
175
|
+
permissionAware.requestPermissions(
|
|
176
|
+
permissions,
|
|
177
|
+
9473,
|
|
178
|
+
PermissionListener { requestCode, _, _ ->
|
|
179
|
+
if (requestCode == 9473) {
|
|
180
|
+
latch.countDown()
|
|
181
|
+
true
|
|
182
|
+
} else {
|
|
183
|
+
false
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
)
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
if (Looper.myLooper() != Looper.getMainLooper()) {
|
|
190
|
+
latch.await(60, TimeUnit.SECONDS)
|
|
191
|
+
}
|
|
192
|
+
if (permissionAware == null && Looper.myLooper() != Looper.getMainLooper()) {
|
|
193
|
+
finishNonPermissionAwareRequest()
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
package com.margelo.nitro.nitrogeolocation.background
|
|
2
|
+
|
|
3
|
+
import android.location.LocationManager
|
|
4
|
+
import com.google.android.gms.location.Geofence
|
|
5
|
+
import com.google.android.gms.location.GeofencingRequest
|
|
6
|
+
import com.google.android.gms.location.DetectedActivity as GmsDetectedActivity
|
|
7
|
+
import com.margelo.nitro.core.NullType
|
|
8
|
+
import com.margelo.nitro.nitrogeolocation.*
|
|
9
|
+
import org.json.JSONArray
|
|
10
|
+
import org.json.JSONObject
|
|
11
|
+
|
|
12
|
+
internal fun backgroundProviderFrom(provider: String?): LocationProviderUsed {
|
|
13
|
+
return when (provider) {
|
|
14
|
+
LocationManager.GPS_PROVIDER -> LocationProviderUsed.GPS
|
|
15
|
+
LocationManager.NETWORK_PROVIDER -> LocationProviderUsed.NETWORK
|
|
16
|
+
LocationManager.PASSIVE_PROVIDER -> LocationProviderUsed.PASSIVE
|
|
17
|
+
"fused" -> LocationProviderUsed.FUSED
|
|
18
|
+
else -> LocationProviderUsed.UNKNOWN
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
internal fun BackgroundEventEnvelope.toJson(): JSONObject {
|
|
23
|
+
return JSONObject()
|
|
24
|
+
.put("id", id)
|
|
25
|
+
.put("type", type.jsValue())
|
|
26
|
+
.put("timestamp", timestamp)
|
|
27
|
+
.put("deliveredToJS", deliveredToJS)
|
|
28
|
+
.apply {
|
|
29
|
+
location?.let { put("location", it.toJson()) }
|
|
30
|
+
geofence?.let { put("geofence", it.toJson()) }
|
|
31
|
+
activity?.let { put("activity", it.toJson()) }
|
|
32
|
+
result?.let { put("result", it.toJson()) }
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
internal fun BackgroundHttpSyncResult.toJson(): JSONObject {
|
|
37
|
+
return JSONObject()
|
|
38
|
+
.put("success", success)
|
|
39
|
+
.put("statusCode", statusCode)
|
|
40
|
+
.put("syncedLocationIds", JSONArray(syncedLocationIds.toList()))
|
|
41
|
+
.put("failedLocationIds", JSONArray(failedLocationIds.toList()))
|
|
42
|
+
.put("error", error)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
internal fun DetectedActivity.toJson(): JSONObject {
|
|
46
|
+
return JSONObject()
|
|
47
|
+
.put("type", type.jsValue())
|
|
48
|
+
.put("confidence", confidence)
|
|
49
|
+
.put("timestamp", timestamp)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
internal fun StoredBackgroundLocation.toJson(): JSONObject {
|
|
53
|
+
return JSONObject()
|
|
54
|
+
.put("id", id)
|
|
55
|
+
.put("deliveredToJS", deliveredToJS)
|
|
56
|
+
.put("synced", synced)
|
|
57
|
+
.put("createdAt", createdAt)
|
|
58
|
+
.put("source", source.jsValue())
|
|
59
|
+
.put("isFromBackground", isFromBackground)
|
|
60
|
+
.put("provider", provider?.jsValue())
|
|
61
|
+
.put("mocked", mocked)
|
|
62
|
+
.put("recordedAt", recordedAt)
|
|
63
|
+
.put("coords", coords.toJson())
|
|
64
|
+
.put("timestamp", timestamp)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
internal fun BackgroundLocation.toJson(): JSONObject {
|
|
68
|
+
return JSONObject()
|
|
69
|
+
.put("id", id)
|
|
70
|
+
.put("source", source.jsValue())
|
|
71
|
+
.put("isFromBackground", isFromBackground)
|
|
72
|
+
.put("provider", provider?.jsValue())
|
|
73
|
+
.put("mocked", mocked)
|
|
74
|
+
.put("recordedAt", recordedAt)
|
|
75
|
+
.put("coords", coords.toJson())
|
|
76
|
+
.put("timestamp", timestamp)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
internal fun GeolocationCoordinates.toJson(): JSONObject {
|
|
80
|
+
return JSONObject()
|
|
81
|
+
.put("latitude", latitude)
|
|
82
|
+
.put("longitude", longitude)
|
|
83
|
+
.put("altitude", altitude?.asSecondOrNull())
|
|
84
|
+
.put("accuracy", accuracy)
|
|
85
|
+
.put("altitudeAccuracy", altitudeAccuracy?.asSecondOrNull())
|
|
86
|
+
.put("heading", heading?.asSecondOrNull())
|
|
87
|
+
.put("speed", speed?.asSecondOrNull())
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
internal fun GeofenceEvent.toJson(): JSONObject {
|
|
91
|
+
return JSONObject()
|
|
92
|
+
.put("region", region.toJson())
|
|
93
|
+
.put("transition", transition.jsValue())
|
|
94
|
+
.put("timestamp", timestamp)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
internal fun GeofenceRegion.toJson(): JSONObject {
|
|
98
|
+
return JSONObject()
|
|
99
|
+
.put("identifier", identifier)
|
|
100
|
+
.put("latitude", latitude)
|
|
101
|
+
.put("longitude", longitude)
|
|
102
|
+
.put("radius", radius)
|
|
103
|
+
.put("notifyOnEntry", notifyOnEntry)
|
|
104
|
+
.put("notifyOnExit", notifyOnExit)
|
|
105
|
+
.put("notifyOnDwell", notifyOnDwell)
|
|
106
|
+
.put("loiteringDelay", loiteringDelay)
|
|
107
|
+
.put("expirationDuration", expirationDuration)
|
|
108
|
+
.put("metadata", metadataToJsonObject(metadata))
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
internal fun metadataToJsonObject(
|
|
112
|
+
metadata: Map<String, Variant_NullType_Boolean_String_Double>?
|
|
113
|
+
): JSONObject? {
|
|
114
|
+
metadata ?: return null
|
|
115
|
+
val json = JSONObject()
|
|
116
|
+
metadata.forEach { (key, value) ->
|
|
117
|
+
when (value) {
|
|
118
|
+
is Variant_NullType_Boolean_String_Double.First -> json.put(key, JSONObject.NULL)
|
|
119
|
+
is Variant_NullType_Boolean_String_Double.Second -> json.put(key, value.value)
|
|
120
|
+
is Variant_NullType_Boolean_String_Double.Third -> json.put(key, value.value)
|
|
121
|
+
is Variant_NullType_Boolean_String_Double.Fourth -> json.put(key, value.value)
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return json
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
internal fun stringMapToJson(map: Map<String, String>): String {
|
|
128
|
+
val json = JSONObject()
|
|
129
|
+
map.forEach { (key, value) -> json.put(key, value) }
|
|
130
|
+
return json.toString()
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
internal fun jsonToStringMap(payload: String): Map<String, String> {
|
|
134
|
+
val json = JSONObject(payload)
|
|
135
|
+
val map = mutableMapOf<String, String>()
|
|
136
|
+
val keys = json.keys()
|
|
137
|
+
while (keys.hasNext()) {
|
|
138
|
+
val key = keys.next()
|
|
139
|
+
map[key] = json.getString(key)
|
|
140
|
+
}
|
|
141
|
+
return map
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
internal fun variantMapToJson(map: Map<String, Variant_NullType_Boolean_String_Double>): String {
|
|
145
|
+
return metadataToJsonObject(map)?.toString() ?: "{}"
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
internal fun jsonToVariantMap(payload: String): Map<String, Variant_NullType_Boolean_String_Double> {
|
|
149
|
+
val json = JSONObject(payload)
|
|
150
|
+
val map = mutableMapOf<String, Variant_NullType_Boolean_String_Double>()
|
|
151
|
+
val keys = json.keys()
|
|
152
|
+
while (keys.hasNext()) {
|
|
153
|
+
val key = keys.next()
|
|
154
|
+
map[key] = when (val value = json.get(key)) {
|
|
155
|
+
JSONObject.NULL -> Variant_NullType_Boolean_String_Double.create(NullType.NULL)
|
|
156
|
+
is Boolean -> Variant_NullType_Boolean_String_Double.create(value)
|
|
157
|
+
is String -> Variant_NullType_Boolean_String_Double.create(value)
|
|
158
|
+
is Number -> Variant_NullType_Boolean_String_Double.create(value.toDouble())
|
|
159
|
+
else -> Variant_NullType_Boolean_String_Double.create(value.toString())
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return map
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
internal fun BackgroundHttpSyncOptions.batchBody(locations: Array<StoredBackgroundLocation>): JSONObject {
|
|
166
|
+
val body = metadataToJsonObject(bodyTemplate) ?: JSONObject()
|
|
167
|
+
body.put("locations", JSONArray(locations.map { it.toJson() }))
|
|
168
|
+
return body
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
internal fun BackgroundHttpSyncOptions.singleBody(location: StoredBackgroundLocation): JSONObject {
|
|
172
|
+
val body = metadataToJsonObject(bodyTemplate)
|
|
173
|
+
if (body != null) {
|
|
174
|
+
body.put("location", location.toJson())
|
|
175
|
+
return body
|
|
176
|
+
}
|
|
177
|
+
return location.toJson()
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
internal fun BackgroundEventType.jsValue(): String {
|
|
181
|
+
return when (this) {
|
|
182
|
+
BackgroundEventType.LOCATION -> "location"
|
|
183
|
+
BackgroundEventType.GEOFENCE -> "geofence"
|
|
184
|
+
BackgroundEventType.ACTIVITY -> "activity"
|
|
185
|
+
BackgroundEventType.PROVIDERCHANGE -> "providerChange"
|
|
186
|
+
BackgroundEventType.HTTPSYNC -> "httpSync"
|
|
187
|
+
BackgroundEventType.ERROR -> "error"
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
internal fun BackgroundLocationSource.jsValue(): String {
|
|
192
|
+
return when (this) {
|
|
193
|
+
BackgroundLocationSource.FOREGROUNDSERVICE -> "foregroundService"
|
|
194
|
+
BackgroundLocationSource.BACKGROUND -> "background"
|
|
195
|
+
BackgroundLocationSource.SIGNIFICANTCHANGE -> "significantChange"
|
|
196
|
+
BackgroundLocationSource.GEOFENCE -> "geofence"
|
|
197
|
+
BackgroundLocationSource.DEFERRED -> "deferred"
|
|
198
|
+
BackgroundLocationSource.MANUAL -> "manual"
|
|
199
|
+
BackgroundLocationSource.UNKNOWN -> "unknown"
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
internal fun LocationProviderUsed.jsValue(): String {
|
|
204
|
+
return when (this) {
|
|
205
|
+
LocationProviderUsed.GPS -> "gps"
|
|
206
|
+
LocationProviderUsed.NETWORK -> "network"
|
|
207
|
+
LocationProviderUsed.PASSIVE -> "passive"
|
|
208
|
+
LocationProviderUsed.FUSED -> "fused"
|
|
209
|
+
LocationProviderUsed.UNKNOWN -> "unknown"
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
internal fun GeofenceTransition.jsValue(): String {
|
|
214
|
+
return when (this) {
|
|
215
|
+
GeofenceTransition.ENTER -> "enter"
|
|
216
|
+
GeofenceTransition.EXIT -> "exit"
|
|
217
|
+
GeofenceTransition.DWELL -> "dwell"
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
internal fun DetectedActivityType.jsValue(): String {
|
|
222
|
+
return when (this) {
|
|
223
|
+
DetectedActivityType.STILL -> "still"
|
|
224
|
+
DetectedActivityType.WALKING -> "walking"
|
|
225
|
+
DetectedActivityType.RUNNING -> "running"
|
|
226
|
+
DetectedActivityType.ONFOOT -> "onFoot"
|
|
227
|
+
DetectedActivityType.ONBICYCLE -> "onBicycle"
|
|
228
|
+
DetectedActivityType.INVEHICLE -> "inVehicle"
|
|
229
|
+
DetectedActivityType.TILTING -> "tilting"
|
|
230
|
+
DetectedActivityType.UNKNOWN -> "unknown"
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
internal fun GmsDetectedActivity.toNitroActivityType(): DetectedActivityType {
|
|
235
|
+
return when (type) {
|
|
236
|
+
GmsDetectedActivity.STILL -> DetectedActivityType.STILL
|
|
237
|
+
GmsDetectedActivity.WALKING -> DetectedActivityType.WALKING
|
|
238
|
+
GmsDetectedActivity.RUNNING -> DetectedActivityType.RUNNING
|
|
239
|
+
GmsDetectedActivity.ON_FOOT -> DetectedActivityType.ONFOOT
|
|
240
|
+
GmsDetectedActivity.ON_BICYCLE -> DetectedActivityType.ONBICYCLE
|
|
241
|
+
GmsDetectedActivity.IN_VEHICLE -> DetectedActivityType.INVEHICLE
|
|
242
|
+
GmsDetectedActivity.TILTING -> DetectedActivityType.TILTING
|
|
243
|
+
else -> DetectedActivityType.UNKNOWN
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
internal fun GeofenceRegion.toTransitionTypes(): Int {
|
|
248
|
+
var transitions = 0
|
|
249
|
+
if (notifyOnEntry != false) transitions = transitions or Geofence.GEOFENCE_TRANSITION_ENTER
|
|
250
|
+
if (notifyOnExit != false) transitions = transitions or Geofence.GEOFENCE_TRANSITION_EXIT
|
|
251
|
+
if (notifyOnDwell == true) transitions = transitions or Geofence.GEOFENCE_TRANSITION_DWELL
|
|
252
|
+
return transitions
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
internal fun GeofencingOptions?.toInitialTrigger(): Int {
|
|
256
|
+
val triggers = this?.initialTrigger ?: return 0
|
|
257
|
+
var value = 0
|
|
258
|
+
for (trigger in triggers) {
|
|
259
|
+
value = value or when (trigger) {
|
|
260
|
+
GeofenceTransition.ENTER -> GeofencingRequest.INITIAL_TRIGGER_ENTER
|
|
261
|
+
GeofenceTransition.EXIT -> GeofencingRequest.INITIAL_TRIGGER_EXIT
|
|
262
|
+
GeofenceTransition.DWELL -> GeofencingRequest.INITIAL_TRIGGER_DWELL
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
return value
|
|
266
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
package com.margelo.nitro.nitrogeolocation.background
|
|
2
|
+
|
|
3
|
+
import android.content.BroadcastReceiver
|
|
4
|
+
import android.content.Context
|
|
5
|
+
import android.content.Intent
|
|
6
|
+
|
|
7
|
+
class NitroActivityRecognitionReceiver : BroadcastReceiver() {
|
|
8
|
+
override fun onReceive(context: Context, intent: Intent) {
|
|
9
|
+
NitroBackgroundLocationController
|
|
10
|
+
.getInstance(context)
|
|
11
|
+
.handleActivityRecognition(intent)
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
package com.margelo.nitro.nitrogeolocation.background
|
|
2
|
+
|
|
3
|
+
import com.margelo.nitro.nitrogeolocation.BackgroundEventEnvelope
|
|
4
|
+
import com.margelo.nitro.nitrogeolocation.BackgroundEventType
|
|
5
|
+
import com.margelo.nitro.nitrogeolocation.BackgroundLocation
|
|
6
|
+
import com.margelo.nitro.nitrogeolocation.LocationError
|
|
7
|
+
import java.util.UUID
|
|
8
|
+
import java.util.concurrent.ConcurrentHashMap
|
|
9
|
+
|
|
10
|
+
class NitroBackgroundEventHub {
|
|
11
|
+
private val eventListeners =
|
|
12
|
+
ConcurrentHashMap<String, (BackgroundEventEnvelope) -> Unit>()
|
|
13
|
+
private val locationListeners =
|
|
14
|
+
ConcurrentHashMap<String, (BackgroundLocation) -> Unit>()
|
|
15
|
+
private val errorListeners =
|
|
16
|
+
ConcurrentHashMap<String, (LocationError) -> Unit>()
|
|
17
|
+
|
|
18
|
+
fun addEventListener(listener: (BackgroundEventEnvelope) -> Unit): String {
|
|
19
|
+
val token = UUID.randomUUID().toString()
|
|
20
|
+
eventListeners[token] = listener
|
|
21
|
+
return token
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
fun removeEventListener(token: String) {
|
|
25
|
+
eventListeners.remove(token)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
fun addLocationListener(listener: (BackgroundLocation) -> Unit): String {
|
|
29
|
+
val token = UUID.randomUUID().toString()
|
|
30
|
+
locationListeners[token] = listener
|
|
31
|
+
return token
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
fun removeLocationListener(token: String) {
|
|
35
|
+
locationListeners.remove(token)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
fun addErrorListener(listener: (LocationError) -> Unit): String {
|
|
39
|
+
val token = UUID.randomUUID().toString()
|
|
40
|
+
errorListeners[token] = listener
|
|
41
|
+
return token
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
fun removeErrorListener(token: String) {
|
|
45
|
+
errorListeners.remove(token)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
fun emit(event: BackgroundEventEnvelope) {
|
|
49
|
+
eventListeners.values.forEach { listener -> listener(event) }
|
|
50
|
+
|
|
51
|
+
when (event.type) {
|
|
52
|
+
BackgroundEventType.LOCATION -> {
|
|
53
|
+
event.location?.let { location ->
|
|
54
|
+
locationListeners.values.forEach { listener -> listener(location) }
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
BackgroundEventType.ERROR -> {
|
|
58
|
+
event.error?.let { error ->
|
|
59
|
+
errorListeners.values.forEach { listener -> listener(error) }
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else -> Unit
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|