react-native-nitro-geolocation 1.2.5 → 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.
Files changed (223) hide show
  1. package/README.md +55 -278
  2. package/android/build.gradle +1 -0
  3. package/android/src/main/AndroidManifest.xml +39 -0
  4. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/AndroidFusedLocationProvider.kt +310 -0
  5. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/AndroidFusedRequestFactory.kt +31 -0
  6. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/AndroidGeolocationConversions.kt +71 -0
  7. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/AndroidGeolocationErrors.kt +85 -0
  8. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/AndroidGeolocationOptions.kt +92 -0
  9. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/AndroidLocationSettings.kt +3 -0
  10. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/AndroidProviderRoute.kt +74 -0
  11. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/NitroBackgroundLocation.kt +132 -0
  12. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/NitroGeolocation.kt +219 -476
  13. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/AndroidBackgroundHttpSync.kt +134 -0
  14. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/AndroidBackgroundPermissions.kt +196 -0
  15. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/AndroidBackgroundSerialization.kt +266 -0
  16. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroActivityRecognitionReceiver.kt +13 -0
  17. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroBackgroundEventHub.kt +65 -0
  18. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroBackgroundHeadlessTaskService.kt +58 -0
  19. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroBackgroundLocationController.kt +710 -0
  20. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroBackgroundLocationService.kt +48 -0
  21. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroBackgroundNotificationFactory.kt +37 -0
  22. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroBackgroundStore.kt +655 -0
  23. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroBootReceiver.kt +26 -0
  24. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroGeofenceReceiver.kt +14 -0
  25. package/android/src/main/java/com/margelo/nitro/nitrogeolocation/background/NitroLocationUpdateReceiver.kt +37 -0
  26. package/android/src/test/java/com/margelo/nitro/nitrogeolocation/AndroidFusedLocationProviderTest.kt +64 -0
  27. package/android/src/test/java/com/margelo/nitro/nitrogeolocation/AndroidProviderRouteTest.kt +116 -0
  28. package/ios/IOSBackgroundHttpSync.swift +126 -0
  29. package/ios/IOSBackgroundLocationDelegate.swift +36 -0
  30. package/ios/IOSBackgroundMotion.swift +55 -0
  31. package/ios/IOSBackgroundSerialization.swift +539 -0
  32. package/ios/IOSGeolocationConversions.swift +131 -0
  33. package/ios/IOSGeolocationDelegate.swift +31 -0
  34. package/ios/IOSGeolocationErrors.swift +39 -0
  35. package/ios/IOSGeolocationOptions.swift +135 -0
  36. package/ios/NitroBackgroundLocation.swift +849 -0
  37. package/ios/NitroGeolocation.swift +14 -347
  38. package/nitrogen/generated/android/c++/JActivityRecognitionOptions.hpp +69 -0
  39. package/nitrogen/generated/android/c++/JAndroidBackgroundLocationOptions.hpp +74 -0
  40. package/nitrogen/generated/android/c++/JAndroidBackgroundLocationStatus.hpp +67 -0
  41. package/nitrogen/generated/android/c++/JAndroidBackgroundProvider.hpp +61 -0
  42. package/nitrogen/generated/android/c++/JAndroidForegroundServiceOptions.hpp +90 -0
  43. package/nitrogen/generated/android/c++/JBackgroundEventEnvelope.hpp +129 -0
  44. package/nitrogen/generated/android/c++/JBackgroundEventType.hpp +70 -0
  45. package/nitrogen/generated/android/c++/JBackgroundHttpMethod.hpp +61 -0
  46. package/nitrogen/generated/android/c++/JBackgroundHttpSyncOptions.hpp +131 -0
  47. package/nitrogen/generated/android/c++/JBackgroundHttpSyncResult.hpp +111 -0
  48. package/nitrogen/generated/android/c++/JBackgroundLocation.hpp +110 -0
  49. package/nitrogen/generated/android/c++/JBackgroundLocationOptions.hpp +162 -0
  50. package/nitrogen/generated/android/c++/JBackgroundLocationSource.hpp +73 -0
  51. package/nitrogen/generated/android/c++/JBackgroundLocationState.hpp +70 -0
  52. package/nitrogen/generated/android/c++/JBackgroundLocationStatus.hpp +126 -0
  53. package/nitrogen/generated/android/c++/JBackgroundPermissionResult.hpp +79 -0
  54. package/nitrogen/generated/android/c++/JBackgroundPermissionStatus.hpp +64 -0
  55. package/nitrogen/generated/android/c++/JBackgroundTrackingMode.hpp +61 -0
  56. package/nitrogen/generated/android/c++/JBatterySnapshot.hpp +61 -0
  57. package/nitrogen/generated/android/c++/JDetectedActivity.hpp +66 -0
  58. package/nitrogen/generated/android/c++/JDetectedActivityType.hpp +76 -0
  59. package/nitrogen/generated/android/c++/JFunc_void_BackgroundEventEnvelope.hpp +114 -0
  60. package/nitrogen/generated/android/c++/JFunc_void_BackgroundLocation.hpp +95 -0
  61. package/nitrogen/generated/android/c++/JGeofenceEvent.hpp +94 -0
  62. package/nitrogen/generated/android/c++/JGeofenceRegion.hpp +112 -0
  63. package/nitrogen/generated/android/c++/JGeofenceTransition.hpp +61 -0
  64. package/nitrogen/generated/android/c++/JGeofencingOptions.hpp +82 -0
  65. package/nitrogen/generated/android/c++/JGetStoredBackgroundEventsOptions.hpp +90 -0
  66. package/nitrogen/generated/android/c++/JGetStoredBackgroundLocationsOptions.hpp +69 -0
  67. package/nitrogen/generated/android/c++/JHybridNitroBackgroundLocationSpec.cpp +662 -0
  68. package/nitrogen/generated/android/c++/JHybridNitroBackgroundLocationSpec.hpp +89 -0
  69. package/nitrogen/generated/android/c++/JIOSBackgroundActivityType.hpp +67 -0
  70. package/nitrogen/generated/android/c++/JIOSBackgroundLocationOptions.hpp +79 -0
  71. package/nitrogen/generated/android/c++/JIOSBackgroundLocationStatus.hpp +61 -0
  72. package/nitrogen/generated/android/c++/JLocationProviderStatus.hpp +5 -1
  73. package/nitrogen/generated/android/c++/JStoredBackgroundEventEnvelope.hpp +115 -0
  74. package/nitrogen/generated/android/c++/JStoredBackgroundLocation.hpp +122 -0
  75. package/nitrogen/generated/android/c++/JVariant_NullType_Boolean_String_Double.cpp +34 -0
  76. package/nitrogen/generated/android/c++/JVariant_NullType_Boolean_String_Double.hpp +100 -0
  77. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/ActivityRecognitionOptions.kt +66 -0
  78. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/AndroidBackgroundLocationOptions.kt +66 -0
  79. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/AndroidBackgroundLocationStatus.kt +61 -0
  80. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/AndroidBackgroundProvider.kt +24 -0
  81. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/AndroidForegroundServiceOptions.kt +91 -0
  82. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundEventEnvelope.kt +96 -0
  83. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundEventType.kt +27 -0
  84. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundHttpMethod.kt +24 -0
  85. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundHttpSyncOptions.kt +101 -0
  86. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundHttpSyncResult.kt +71 -0
  87. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundLocation.kt +96 -0
  88. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundLocationOptions.kt +136 -0
  89. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundLocationSource.kt +28 -0
  90. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundLocationState.kt +27 -0
  91. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundLocationStatus.kt +116 -0
  92. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundPermissionResult.kt +71 -0
  93. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundPermissionStatus.kt +25 -0
  94. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BackgroundTrackingMode.kt +24 -0
  95. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/BatterySnapshot.kt +56 -0
  96. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/DetectedActivity.kt +61 -0
  97. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/DetectedActivityType.kt +29 -0
  98. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/Func_void_BackgroundEventEnvelope.kt +80 -0
  99. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/Func_void_BackgroundLocation.kt +80 -0
  100. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GeofenceEvent.kt +66 -0
  101. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GeofenceRegion.kt +96 -0
  102. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GeofenceTransition.kt +24 -0
  103. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GeofencingOptions.kt +56 -0
  104. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GetStoredBackgroundEventsOptions.kt +66 -0
  105. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GetStoredBackgroundLocationsOptions.kt +66 -0
  106. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/HybridNitroBackgroundLocationSpec.kt +174 -0
  107. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/IOSBackgroundActivityType.kt +26 -0
  108. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/IOSBackgroundLocationOptions.kt +76 -0
  109. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/IOSBackgroundLocationStatus.kt +56 -0
  110. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/LocationProviderStatus.kt +7 -2
  111. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/StoredBackgroundEventEnvelope.kt +76 -0
  112. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/StoredBackgroundLocation.kt +111 -0
  113. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/Variant_NullType_Boolean_String_Double.kt +88 -0
  114. package/nitrogen/generated/android/nitrogeolocation+autolinking.cmake +3 -0
  115. package/nitrogen/generated/android/nitrogeolocationOnLoad.cpp +20 -0
  116. package/nitrogen/generated/ios/NitroGeolocation-Swift-Cxx-Bridge.cpp +104 -15
  117. package/nitrogen/generated/ios/NitroGeolocation-Swift-Cxx-Bridge.hpp +1107 -50
  118. package/nitrogen/generated/ios/NitroGeolocation-Swift-Cxx-Umbrella.hpp +102 -0
  119. package/nitrogen/generated/ios/NitroGeolocationAutolinking.mm +8 -0
  120. package/nitrogen/generated/ios/NitroGeolocationAutolinking.swift +15 -3
  121. package/nitrogen/generated/ios/c++/HybridNitroBackgroundLocationSpecSwift.cpp +11 -0
  122. package/nitrogen/generated/ios/c++/HybridNitroBackgroundLocationSpecSwift.hpp +416 -0
  123. package/nitrogen/generated/ios/swift/ActivityRecognitionOptions.swift +96 -0
  124. package/nitrogen/generated/ios/swift/AndroidBackgroundLocationOptions.swift +76 -0
  125. package/nitrogen/generated/ios/swift/AndroidBackgroundLocationStatus.swift +58 -0
  126. package/nitrogen/generated/ios/swift/AndroidBackgroundProvider.swift +44 -0
  127. package/nitrogen/generated/ios/swift/AndroidForegroundServiceOptions.swift +160 -0
  128. package/nitrogen/generated/ios/swift/BackgroundEventEnvelope.swift +110 -0
  129. package/nitrogen/generated/ios/swift/BackgroundEventType.swift +56 -0
  130. package/nitrogen/generated/ios/swift/BackgroundHttpMethod.swift +44 -0
  131. package/nitrogen/generated/ios/swift/BackgroundHttpSyncOptions.swift +259 -0
  132. package/nitrogen/generated/ios/swift/BackgroundHttpSyncResult.swift +87 -0
  133. package/nitrogen/generated/ios/swift/BackgroundLocation.swift +118 -0
  134. package/nitrogen/generated/ios/swift/BackgroundLocationOptions.swift +292 -0
  135. package/nitrogen/generated/ios/swift/BackgroundLocationSource.swift +60 -0
  136. package/nitrogen/generated/ios/swift/BackgroundLocationState.swift +56 -0
  137. package/nitrogen/generated/ios/swift/BackgroundLocationStatus.swift +124 -0
  138. package/nitrogen/generated/ios/swift/BackgroundPermissionResult.swift +81 -0
  139. package/nitrogen/generated/ios/swift/BackgroundPermissionStatus.swift +48 -0
  140. package/nitrogen/generated/ios/swift/BackgroundTrackingMode.swift +44 -0
  141. package/nitrogen/generated/ios/swift/BatterySnapshot.swift +60 -0
  142. package/nitrogen/generated/ios/swift/DetectedActivity.swift +39 -0
  143. package/nitrogen/generated/ios/swift/DetectedActivityType.swift +64 -0
  144. package/nitrogen/generated/ios/swift/Func_void_BackgroundEventEnvelope.swift +46 -0
  145. package/nitrogen/generated/ios/swift/Func_void_BackgroundHttpSyncResult.swift +46 -0
  146. package/nitrogen/generated/ios/swift/Func_void_BackgroundLocation.swift +46 -0
  147. package/nitrogen/generated/ios/swift/Func_void_BackgroundLocationStatus.swift +46 -0
  148. package/nitrogen/generated/ios/swift/Func_void_BackgroundPermissionResult.swift +46 -0
  149. package/nitrogen/generated/ios/swift/Func_void_std__optional_BackgroundLocationOptions_.swift +46 -0
  150. package/nitrogen/generated/ios/swift/Func_void_std__vector_GeofenceRegion_.swift +46 -0
  151. package/nitrogen/generated/ios/swift/Func_void_std__vector_StoredBackgroundEventEnvelope_.swift +46 -0
  152. package/nitrogen/generated/ios/swift/Func_void_std__vector_StoredBackgroundLocation_.swift +46 -0
  153. package/nitrogen/generated/ios/swift/GeofenceEvent.swift +50 -0
  154. package/nitrogen/generated/ios/swift/GeofenceRegion.swift +195 -0
  155. package/nitrogen/generated/ios/swift/GeofenceTransition.swift +44 -0
  156. package/nitrogen/generated/ios/swift/GeofencingOptions.swift +66 -0
  157. package/nitrogen/generated/ios/swift/GetStoredBackgroundEventsOptions.swift +102 -0
  158. package/nitrogen/generated/ios/swift/GetStoredBackgroundLocationsOptions.swift +96 -0
  159. package/nitrogen/generated/ios/swift/HybridNitroBackgroundLocationSpec.swift +81 -0
  160. package/nitrogen/generated/ios/swift/HybridNitroBackgroundLocationSpec_cxx.swift +654 -0
  161. package/nitrogen/generated/ios/swift/IOSBackgroundActivityType.swift +52 -0
  162. package/nitrogen/generated/ios/swift/IOSBackgroundLocationOptions.swift +125 -0
  163. package/nitrogen/generated/ios/swift/IOSBackgroundLocationStatus.swift +34 -0
  164. package/nitrogen/generated/ios/swift/LocationProviderStatus.swift +19 -1
  165. package/nitrogen/generated/ios/swift/StoredBackgroundEventEnvelope.swift +54 -0
  166. package/nitrogen/generated/ios/swift/StoredBackgroundLocation.swift +120 -0
  167. package/nitrogen/generated/ios/swift/Variant_NullType_Bool_String_Double.swift +34 -0
  168. package/nitrogen/generated/shared/c++/ActivityRecognitionOptions.hpp +95 -0
  169. package/nitrogen/generated/shared/c++/AndroidBackgroundLocationOptions.hpp +100 -0
  170. package/nitrogen/generated/shared/c++/AndroidBackgroundLocationStatus.hpp +93 -0
  171. package/nitrogen/generated/shared/c++/AndroidBackgroundProvider.hpp +80 -0
  172. package/nitrogen/generated/shared/c++/AndroidForegroundServiceOptions.hpp +116 -0
  173. package/nitrogen/generated/shared/c++/BackgroundEventEnvelope.hpp +140 -0
  174. package/nitrogen/generated/shared/c++/BackgroundEventType.hpp +92 -0
  175. package/nitrogen/generated/shared/c++/BackgroundHttpMethod.hpp +80 -0
  176. package/nitrogen/generated/shared/c++/BackgroundHttpSyncOptions.hpp +129 -0
  177. package/nitrogen/generated/shared/c++/BackgroundHttpSyncResult.hpp +101 -0
  178. package/nitrogen/generated/shared/c++/BackgroundLocation.hpp +134 -0
  179. package/nitrogen/generated/shared/c++/BackgroundLocationOptions.hpp +174 -0
  180. package/nitrogen/generated/shared/c++/BackgroundLocationSource.hpp +96 -0
  181. package/nitrogen/generated/shared/c++/BackgroundLocationState.hpp +92 -0
  182. package/nitrogen/generated/shared/c++/BackgroundLocationStatus.hpp +158 -0
  183. package/nitrogen/generated/shared/c++/BackgroundPermissionResult.hpp +107 -0
  184. package/nitrogen/generated/shared/c++/BackgroundPermissionStatus.hpp +84 -0
  185. package/nitrogen/generated/shared/c++/BackgroundTrackingMode.hpp +80 -0
  186. package/nitrogen/generated/shared/c++/BatterySnapshot.hpp +87 -0
  187. package/nitrogen/generated/shared/c++/DetectedActivity.hpp +92 -0
  188. package/nitrogen/generated/shared/c++/DetectedActivityType.hpp +100 -0
  189. package/nitrogen/generated/shared/c++/GeofenceEvent.hpp +103 -0
  190. package/nitrogen/generated/shared/c++/GeofenceRegion.hpp +123 -0
  191. package/nitrogen/generated/shared/c++/GeofenceTransition.hpp +80 -0
  192. package/nitrogen/generated/shared/c++/GeofencingOptions.hpp +90 -0
  193. package/nitrogen/generated/shared/c++/GetStoredBackgroundEventsOptions.hpp +98 -0
  194. package/nitrogen/generated/shared/c++/GetStoredBackgroundLocationsOptions.hpp +95 -0
  195. package/nitrogen/generated/shared/c++/HybridNitroBackgroundLocationSpec.cpp +47 -0
  196. package/nitrogen/generated/shared/c++/HybridNitroBackgroundLocationSpec.hpp +133 -0
  197. package/nitrogen/generated/shared/c++/IOSBackgroundActivityType.hpp +88 -0
  198. package/nitrogen/generated/shared/c++/IOSBackgroundLocationOptions.hpp +105 -0
  199. package/nitrogen/generated/shared/c++/IOSBackgroundLocationStatus.hpp +87 -0
  200. package/nitrogen/generated/shared/c++/LocationProviderStatus.hpp +5 -1
  201. package/nitrogen/generated/shared/c++/StoredBackgroundEventEnvelope.hpp +108 -0
  202. package/nitrogen/generated/shared/c++/StoredBackgroundLocation.hpp +146 -0
  203. package/package.json +17 -6
  204. package/src/NitroGeolocation.nitro.ts +4 -4
  205. package/src/api/getCurrentPosition.ts +1 -1
  206. package/src/api/requestLocationSettings.ts +3 -2
  207. package/src/background/NitroBackgroundLocation.nitro.ts +83 -0
  208. package/src/background/index.ts +200 -0
  209. package/src/background/index.web.ts +120 -0
  210. package/src/background/task.ts +13 -0
  211. package/src/background/types.ts +328 -0
  212. package/src/compat/index.web.ts +141 -0
  213. package/src/index.tsx +3 -0
  214. package/src/index.web.tsx +41 -0
  215. package/src/publicTypes.ts +6 -5
  216. package/src/types.ts +3 -0
  217. package/src/web/browser.ts +171 -0
  218. package/src/web/index.ts +167 -0
  219. package/src/web/useWatchPosition.ts +76 -0
  220. package/src/web/watch.ts +81 -0
  221. package/src/devtools/index.test.ts +0 -54
  222. package/src/utils/errors.test.ts +0 -65
  223. 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
+ }