react-native-bg-geolocation 0.2.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/BgGeolocation.podspec +39 -0
- package/LICENSE +20 -0
- package/README.md +366 -0
- package/android/build.gradle +69 -0
- package/android/src/main/AndroidManifest.xml +53 -0
- package/android/src/main/java/com/bggeolocation/BgGeolocationActivityRecognitionReceiver.kt +116 -0
- package/android/src/main/java/com/bggeolocation/BgGeolocationBootReceiver.kt +44 -0
- package/android/src/main/java/com/bggeolocation/BgGeolocationForegroundService.kt +373 -0
- package/android/src/main/java/com/bggeolocation/BgGeolocationGeofenceReceiver.kt +55 -0
- package/android/src/main/java/com/bggeolocation/BgGeolocationHeadlessTask.kt +138 -0
- package/android/src/main/java/com/bggeolocation/BgGeolocationModule.kt +1030 -0
- package/android/src/main/java/com/bggeolocation/BgGeolocationMotionStateMachine.kt +159 -0
- package/android/src/main/java/com/bggeolocation/BgGeolocationPackage.kt +31 -0
- package/android/src/main/res/drawable/bg_geo_notification.xml +9 -0
- package/ios/BgGeolocation.h +14 -0
- package/ios/BgGeolocation.mm +709 -0
- package/ios/engine/AtomicBoolean.swift +48 -0
- package/ios/engine/BGActivityChangeEvent.swift +20 -0
- package/ios/engine/BGActivityConfig.swift +71 -0
- package/ios/engine/BGAppConfig.swift +92 -0
- package/ios/engine/BGAppState.swift +147 -0
- package/ios/engine/BGAuthorization.swift +85 -0
- package/ios/engine/BGAuthorizationAlertPresenter.swift +39 -0
- package/ios/engine/BGAuthorizationConfig.swift +50 -0
- package/ios/engine/BGAuthorizationEvent.swift +40 -0
- package/ios/engine/BGBackgroundTaskManager.swift +143 -0
- package/ios/engine/BGCLRouter.swift +101 -0
- package/ios/engine/BGCallback.swift +19 -0
- package/ios/engine/BGConfig.swift +440 -0
- package/ios/engine/BGConfigModuleBase.swift +180 -0
- package/ios/engine/BGConfigOLD.swift +582 -0
- package/ios/engine/BGConnectivityChangeEvent.swift +15 -0
- package/ios/engine/BGCrashDetector.swift +122 -0
- package/ios/engine/BGCurrentPositionRequest.swift +87 -0
- package/ios/engine/BGDataStore.swift +75 -0
- package/ios/engine/BGDatabase.swift +677 -0
- package/ios/engine/BGDatabasePool.swift +220 -0
- package/ios/engine/BGDatabaseQueue.swift +215 -0
- package/ios/engine/BGDateUtils.swift +26 -0
- package/ios/engine/BGDeviceInfo.swift +54 -0
- package/ios/engine/BGDeviceManager.swift +65 -0
- package/ios/engine/BGEnabledChangeEvent.swift +11 -0
- package/ios/engine/BGEnv.swift +17 -0
- package/ios/engine/BGEventBus.swift +83 -0
- package/ios/engine/BGEventManager.swift +169 -0
- package/ios/engine/BGEventNames.swift +51 -0
- package/ios/engine/BGGeofence.swift +233 -0
- package/ios/engine/BGGeofenceDAO.swift +152 -0
- package/ios/engine/BGGeofenceEvent.swift +42 -0
- package/ios/engine/BGGeofenceLocationRequest.swift +94 -0
- package/ios/engine/BGGeofenceManager.swift +315 -0
- package/ios/engine/BGGeofenceTransition.swift +97 -0
- package/ios/engine/BGGeofencesChangeEvent.swift +26 -0
- package/ios/engine/BGGeolocationConfig.swift +136 -0
- package/ios/engine/BGHeartbeatEvent.swift +31 -0
- package/ios/engine/BGHeartbeatService.swift +51 -0
- package/ios/engine/BGHttpConfig.swift +105 -0
- package/ios/engine/BGHttpErrorCodes.swift +63 -0
- package/ios/engine/BGHttpEvent.swift +34 -0
- package/ios/engine/BGHttpRequest.swift +126 -0
- package/ios/engine/BGHttpResponse.swift +93 -0
- package/ios/engine/BGHttpService.swift +428 -0
- package/ios/engine/BGKalmanFilter.swift +105 -0
- package/ios/engine/BGLMActionNames.swift +55 -0
- package/ios/engine/BGLicenseManager.swift +26 -0
- package/ios/engine/BGLiveActivityManager.swift +327 -0
- package/ios/engine/BGLocation.swift +311 -0
- package/ios/engine/BGLocationAuthorization.swift +427 -0
- package/ios/engine/BGLocationDAO.swift +252 -0
- package/ios/engine/BGLocationErrors.swift +28 -0
- package/ios/engine/BGLocationEvent.swift +43 -0
- package/ios/engine/BGLocationFilter.swift +82 -0
- package/ios/engine/BGLocationFilterConfig.swift +57 -0
- package/ios/engine/BGLocationHelper.swift +54 -0
- package/ios/engine/BGLocationManager.swift +662 -0
- package/ios/engine/BGLocationMetricsEngine.swift +116 -0
- package/ios/engine/BGLocationRequestService.swift +459 -0
- package/ios/engine/BGLocationSatisfier.swift +14 -0
- package/ios/engine/BGLocationStreamEvent.swift +27 -0
- package/ios/engine/BGLog.swift +337 -0
- package/ios/engine/BGLogLevel.swift +26 -0
- package/ios/engine/BGLoggerConfig.swift +60 -0
- package/ios/engine/BGMotionActivity.swift +31 -0
- package/ios/engine/BGMotionActivityClassifier.swift +108 -0
- package/ios/engine/BGMotionActivityManagerAdapter.swift +40 -0
- package/ios/engine/BGMotionActivitySource.swift +46 -0
- package/ios/engine/BGMotionDetector.swift +377 -0
- package/ios/engine/BGMotionPermissionManager.swift +50 -0
- package/ios/engine/BGNativeLogger.swift +48 -0
- package/ios/engine/BGNotificaitons.swift +37 -0
- package/ios/engine/BGOdometer.swift +66 -0
- package/ios/engine/BGPersistenceConfig.swift +29 -0
- package/ios/engine/BGPolygonStreamRequest.swift +48 -0
- package/ios/engine/BGPowerSaveChangeEvent.swift +12 -0
- package/ios/engine/BGPropertySpec.swift +29 -0
- package/ios/engine/BGProviderChangeEvent.swift +31 -0
- package/ios/engine/BGQueue.swift +50 -0
- package/ios/engine/BGRPC.swift +194 -0
- package/ios/engine/BGReachability.swift +58 -0
- package/ios/engine/BGResultSet.swift +157 -0
- package/ios/engine/BGSchedule.swift +228 -0
- package/ios/engine/BGScheduleEvent.swift +13 -0
- package/ios/engine/BGScheduler.swift +116 -0
- package/ios/engine/BGSingleLocationRequest.swift +49 -0
- package/ios/engine/BGStreamLocationRequest.swift +42 -0
- package/ios/engine/BGTemplate.swift +54 -0
- package/ios/engine/BGTimerService.swift +46 -0
- package/ios/engine/BGTrackingAudioManager.swift +286 -0
- package/ios/engine/BGTrackingService.swift +879 -0
- package/ios/engine/BGWatchPositionRequest.swift +63 -0
- package/ios/engine/DatabaseQueue.swift +47 -0
- package/ios/engine/LogQuery.swift +10 -0
- package/ios/engine/SQLQuery.swift +65 -0
- package/ios/engine/TransistorAuthorizationToken.swift +182 -0
- package/ios/liveactivity/BGLiveTrackingAttributes.swift +52 -0
- package/ios/locationpush/BGLocationPushDeliverer.swift +260 -0
- package/ios/locationpush/BGLocationPushService.swift +161 -0
- package/ios/locationpush/BGLocationPushShared.swift +98 -0
- package/ios/locationpush/BGLocationPushSocketClient.swift +198 -0
- package/lib/module/NativeBgGeolocation.js +5 -0
- package/lib/module/NativeBgGeolocation.js.map +1 -0
- package/lib/module/events.js +20 -0
- package/lib/module/events.js.map +1 -0
- package/lib/module/index.js +706 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/NativeBgGeolocation.d.ts +57 -0
- package/lib/typescript/src/NativeBgGeolocation.d.ts.map +1 -0
- package/lib/typescript/src/events.d.ts +18 -0
- package/lib/typescript/src/events.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +238 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +229 -0
- package/lib/typescript/src/types.d.ts.map +1 -0
- package/package.json +141 -0
- package/src/NativeBgGeolocation.ts +236 -0
- package/src/events.ts +17 -0
- package/src/index.tsx +935 -0
- package/src/types.ts +254 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
package com.bggeolocation
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.content.SharedPreferences
|
|
5
|
+
import android.location.Location
|
|
6
|
+
import android.util.Log
|
|
7
|
+
import com.facebook.react.bridge.Arguments
|
|
8
|
+
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Motion state machine — detects moving ↔ stationary transitions.
|
|
12
|
+
*
|
|
13
|
+
* Algorithm (mirrors the original library's logic):
|
|
14
|
+
*
|
|
15
|
+
* MOVING state:
|
|
16
|
+
* - Start a "still timer" when GPS speed drops below SPEED_THRESHOLD AND
|
|
17
|
+
* the activity recognition says STILL.
|
|
18
|
+
* - If the still timer reaches stopTimeout → transition to STATIONARY.
|
|
19
|
+
* - Any movement (speed or activity) resets the still timer.
|
|
20
|
+
*
|
|
21
|
+
* STATIONARY state:
|
|
22
|
+
* - Any movement detected (speed spike or moving activity) → MOVING immediately.
|
|
23
|
+
*
|
|
24
|
+
* The state is persisted in SharedPreferences, so it survives kill/relaunch.
|
|
25
|
+
*/
|
|
26
|
+
object BgGeolocationMotionStateMachine {
|
|
27
|
+
|
|
28
|
+
private const val TAG = "BgGeoMotion"
|
|
29
|
+
|
|
30
|
+
// GPS speed threshold below which we consider the device potentially stationary (m/s).
|
|
31
|
+
// ~2 km/h — low enough to catch a slow walk but ignore GPS jitter.
|
|
32
|
+
private const val SPEED_THRESHOLD_MS = 0.56f
|
|
33
|
+
|
|
34
|
+
private const val KEY_STILL_SINCE = "motion_still_since"
|
|
35
|
+
private const val KEY_INITIALIZED = "motion_initialized"
|
|
36
|
+
|
|
37
|
+
fun update(context: Context, location: Location, prefs: SharedPreferences) {
|
|
38
|
+
val stopTimeoutMs = prefs.getLong("stopTimeout", 60L) * 1000L
|
|
39
|
+
|
|
40
|
+
// Read current state
|
|
41
|
+
val currentlyMoving = prefs.getBoolean(
|
|
42
|
+
BgGeolocationActivityRecognitionReceiver.KEY_IS_MOVING, false
|
|
43
|
+
)
|
|
44
|
+
val initialized = prefs.contains(KEY_INITIALIZED)
|
|
45
|
+
|
|
46
|
+
// Signals from both GPS and activity recognition
|
|
47
|
+
val speed = location.speed
|
|
48
|
+
val gpsMoving = speed > SPEED_THRESHOLD_MS
|
|
49
|
+
val actMoving = BgGeolocationActivityRecognitionReceiver.readIsMoving(context)
|
|
50
|
+
|
|
51
|
+
Log.d("BgGeoTest",
|
|
52
|
+
"[MOTION STATE] speed=${String.format("%.2f", speed)}m/s " +
|
|
53
|
+
"gps=${if (gpsMoving) "MOVING" else "STILL"} " +
|
|
54
|
+
"activity=${if (actMoving) "MOVING" else "STILL"} " +
|
|
55
|
+
"current=${if (currentlyMoving) "MOVING" else "STATIONARY"}"
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
if (!initialized) {
|
|
59
|
+
// First location fix — establish initial state
|
|
60
|
+
val initialMoving = gpsMoving || actMoving
|
|
61
|
+
prefs.edit()
|
|
62
|
+
.putBoolean(KEY_INITIALIZED, true)
|
|
63
|
+
.putBoolean(BgGeolocationActivityRecognitionReceiver.KEY_IS_MOVING, initialMoving)
|
|
64
|
+
.putLong(KEY_STILL_SINCE, 0L)
|
|
65
|
+
.apply()
|
|
66
|
+
Log.d("BgGeoTest", "[MOTION STATE] initialized → ${if (initialMoving) "MOVING" else "STATIONARY"}")
|
|
67
|
+
return
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (currentlyMoving) {
|
|
71
|
+
// ── Currently MOVING — check for stop ────────────────────────────────
|
|
72
|
+
val evidenceOfMovement = gpsMoving || actMoving
|
|
73
|
+
if (!evidenceOfMovement) {
|
|
74
|
+
// Start or continue the still timer
|
|
75
|
+
val stillSince = prefs.getLong(KEY_STILL_SINCE, 0L)
|
|
76
|
+
if (stillSince == 0L) {
|
|
77
|
+
prefs.edit().putLong(KEY_STILL_SINCE, System.currentTimeMillis()).apply()
|
|
78
|
+
Log.d("BgGeoTest", "[MOTION STATE] ⏱ still timer started (stopTimeout=${stopTimeoutMs/1000}s)")
|
|
79
|
+
} else {
|
|
80
|
+
val elapsed = System.currentTimeMillis() - stillSince
|
|
81
|
+
Log.d("BgGeoTest", "[MOTION STATE] still for ${elapsed/1000}s / ${stopTimeoutMs/1000}s")
|
|
82
|
+
if (elapsed >= stopTimeoutMs) {
|
|
83
|
+
Log.d("BgGeoTest", "[MOTION STATE] ⏱ stopTimeout reached → STATIONARY")
|
|
84
|
+
transitionTo(context, prefs, false, location)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
// Device is still moving — clear the still timer if it was running
|
|
89
|
+
if (prefs.getLong(KEY_STILL_SINCE, 0L) != 0L) {
|
|
90
|
+
prefs.edit().putLong(KEY_STILL_SINCE, 0L).apply()
|
|
91
|
+
Log.d("BgGeoTest", "[MOTION STATE] still timer reset (movement detected)")
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
} else {
|
|
95
|
+
// ── Currently STATIONARY — check for movement ─────────────────────────
|
|
96
|
+
if (gpsMoving || actMoving) {
|
|
97
|
+
Log.d("BgGeoTest", "[MOTION STATE] movement detected → MOVING")
|
|
98
|
+
prefs.edit().putLong(KEY_STILL_SINCE, 0L).apply()
|
|
99
|
+
transitionTo(context, prefs, true, location)
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Persist the new moving/stationary state and emit a `motionchange` event.
|
|
106
|
+
*/
|
|
107
|
+
private fun transitionTo(
|
|
108
|
+
context: Context,
|
|
109
|
+
prefs: SharedPreferences,
|
|
110
|
+
moving: Boolean,
|
|
111
|
+
location: Location
|
|
112
|
+
) {
|
|
113
|
+
prefs.edit()
|
|
114
|
+
.putBoolean(BgGeolocationActivityRecognitionReceiver.KEY_IS_MOVING, moving)
|
|
115
|
+
.putLong(KEY_STILL_SINCE, 0L)
|
|
116
|
+
.apply()
|
|
117
|
+
|
|
118
|
+
val activityType = BgGeolocationActivityRecognitionReceiver.readActivityType(context)
|
|
119
|
+
val activityConf = BgGeolocationActivityRecognitionReceiver.readActivityConfidence(context)
|
|
120
|
+
|
|
121
|
+
Log.d("BgGeoTest",
|
|
122
|
+
"[MOTION STATE] 🔄 motionchange isMoving=$moving " +
|
|
123
|
+
"activity=$activityType (${activityConf}%)"
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
val payload = Arguments.createMap().apply {
|
|
127
|
+
putBoolean("isMoving", moving)
|
|
128
|
+
putMap("activity", Arguments.createMap().apply {
|
|
129
|
+
putString("type", activityType)
|
|
130
|
+
putInt("confidence", activityConf)
|
|
131
|
+
})
|
|
132
|
+
putMap("location", Arguments.createMap().apply {
|
|
133
|
+
putDouble("latitude", location.latitude)
|
|
134
|
+
putDouble("longitude", location.longitude)
|
|
135
|
+
putDouble("accuracy", location.accuracy.toDouble())
|
|
136
|
+
})
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
val reactContext = BgGeolocationModule.getReactContext()
|
|
140
|
+
if (reactContext != null) {
|
|
141
|
+
try {
|
|
142
|
+
reactContext
|
|
143
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
144
|
+
?.emit("motionchange", payload)
|
|
145
|
+
Log.d("BgGeoTest", "[MOTION STATE] motionchange → JS")
|
|
146
|
+
} catch (e: Exception) {
|
|
147
|
+
Log.w(TAG, "emit motionchange failed: ${e.message}")
|
|
148
|
+
}
|
|
149
|
+
} else {
|
|
150
|
+
val headlessMap = Arguments.createMap().apply {
|
|
151
|
+
putBoolean("isMoving", moving)
|
|
152
|
+
putString("activityType", activityType)
|
|
153
|
+
putInt("confidence", activityConf)
|
|
154
|
+
}
|
|
155
|
+
BgGeolocationHeadlessTask.onEvent(context, "motionchange", headlessMap)
|
|
156
|
+
Log.d("BgGeoTest", "[MOTION STATE] motionchange → HeadlessTask (app killed)")
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
package com.bggeolocation
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.BaseReactPackage
|
|
4
|
+
import com.facebook.react.bridge.NativeModule
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
+
import com.facebook.react.module.model.ReactModuleInfo
|
|
7
|
+
import com.facebook.react.module.model.ReactModuleInfoProvider
|
|
8
|
+
import java.util.HashMap
|
|
9
|
+
|
|
10
|
+
class BgGeolocationPackage : BaseReactPackage() {
|
|
11
|
+
override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
|
|
12
|
+
return if (name == BgGeolocationModule.NAME) {
|
|
13
|
+
BgGeolocationModule(reactContext)
|
|
14
|
+
} else {
|
|
15
|
+
null
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
override fun getReactModuleInfoProvider() = ReactModuleInfoProvider {
|
|
20
|
+
mapOf(
|
|
21
|
+
BgGeolocationModule.NAME to ReactModuleInfo(
|
|
22
|
+
name = BgGeolocationModule.NAME,
|
|
23
|
+
className = BgGeolocationModule.NAME,
|
|
24
|
+
canOverrideExistingModule = false,
|
|
25
|
+
needsEagerInit = false,
|
|
26
|
+
isCxxModule = false,
|
|
27
|
+
isTurboModule = true
|
|
28
|
+
)
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
2
|
+
android:width="24dp"
|
|
3
|
+
android:height="24dp"
|
|
4
|
+
android:viewportWidth="24"
|
|
5
|
+
android:viewportHeight="24">
|
|
6
|
+
<path
|
|
7
|
+
android:fillColor="#FFFFFFFF"
|
|
8
|
+
android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13c0,-3.87 -3.13,-7 -7,-7zM12,11.5c-1.38,0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5s2.5,1.12 2.5,2.5s-1.12,2.5 -2.5,2.5z" />
|
|
9
|
+
</vector>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//
|
|
2
|
+
// BgGeolocation.h
|
|
3
|
+
//
|
|
4
|
+
// ObjC++ TurboModule wrapper.
|
|
5
|
+
// The location engine is compiled from Swift source (ios/engine/*.swift).
|
|
6
|
+
// No binary dependency — zero billing, works in DEBUG and RELEASE.
|
|
7
|
+
//
|
|
8
|
+
// NOTE: BgGeolocationSpec.h (C++) is imported only in the .mm, not here,
|
|
9
|
+
// so this public header stays C-safe for Swift module scanning.
|
|
10
|
+
//
|
|
11
|
+
#import <React/RCTEventEmitter.h>
|
|
12
|
+
|
|
13
|
+
@interface BgGeolocation : RCTEventEmitter
|
|
14
|
+
@end
|