@@ -11,6 +11,7 @@ import android.os.Looper
1111import androidx.core.app.NotificationCompat
1212import com.facebook.react.bridge.Arguments
1313import com.facebook.react.bridge.ReactContext
14+ import com.facebook.react.bridge.WritableMap
1415import com.facebook.react.modules.core.DeviceEventManagerModule
1516import com.google.android.gms.location.*
1617
@@ -126,11 +127,51 @@ class LocationService : Service() {
126127
127128 private fun handleLocation (location : Location ) {
128129 currentTripId?.let { tripId ->
130+ // Extract all available location data
131+ val accuracy = if (location.hasAccuracy()) location.accuracy else null
132+ val altitude = if (location.hasAltitude()) location.altitude else null
133+ val speed = if (location.hasSpeed()) location.speed else null
134+ val bearing = if (location.hasBearing()) location.bearing else null
135+
136+ // API 26+ fields - check if values are valid (not NaN)
137+ val verticalAccuracyMeters = if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .O ) {
138+ val value = location.verticalAccuracyMeters
139+ if (! value.isNaN()) value else null
140+ } else null
141+
142+ val speedAccuracyMetersPerSecond = if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .O ) {
143+ val value = location.speedAccuracyMetersPerSecond
144+ if (! value.isNaN()) value else null
145+ } else null
146+
147+ val bearingAccuracyDegrees = if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .O ) {
148+ val value = location.bearingAccuracyDegrees
149+ if (! value.isNaN()) value else null
150+ } else null
151+
152+ val elapsedRealtimeNanos = location.elapsedRealtimeNanos
153+ val provider = location.provider
154+
155+ // API 18+ field
156+ val isFromMockProvider = if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .JELLY_BEAN_MR2 ) {
157+ location.isFromMockProvider
158+ } else null
159+
129160 storage.saveLocation(
130161 tripId = tripId,
131162 latitude = location.latitude,
132163 longitude = location.longitude,
133- timestamp = location.time
164+ timestamp = location.time,
165+ accuracy = accuracy,
166+ altitude = altitude,
167+ speed = speed,
168+ bearing = bearing,
169+ verticalAccuracyMeters = verticalAccuracyMeters,
170+ speedAccuracyMetersPerSecond = speedAccuracyMetersPerSecond,
171+ bearingAccuracyDegrees = bearingAccuracyDegrees,
172+ elapsedRealtimeNanos = elapsedRealtimeNanos,
173+ provider = provider,
174+ isFromMockProvider = isFromMockProvider
134175 )
135176
136177 // Emit location update event to React Native
@@ -139,17 +180,12 @@ class LocationService : Service() {
139180 }
140181
141182 /* *
142- * Sends a location update event to React Native
183+ * Sends a location update event to React Native with extended location data
143184 */
144185 private fun sendLocationUpdateEvent (tripId : String , location : Location ) {
145186 reactContext?.let { context ->
146187 try {
147- val eventData = Arguments .createMap().apply {
148- putString(" tripId" , tripId)
149- putString(" latitude" , location.latitude.toString())
150- putString(" longitude" , location.longitude.toString())
151- putDouble(" timestamp" , location.time.toDouble())
152- }
188+ val eventData = createLocationMap(tripId, location)
153189
154190 context
155191 .getJSModule(DeviceEventManagerModule .RCTDeviceEventEmitter ::class .java)
@@ -160,6 +196,60 @@ class LocationService : Service() {
160196 }
161197 }
162198 }
199+
200+ /* *
201+ * Creates a WritableMap with all available location data
202+ */
203+ private fun createLocationMap (tripId : String , location : Location ): WritableMap {
204+ val map = Arguments .createMap().apply {
205+ putString(" tripId" , tripId)
206+ putString(" latitude" , location.latitude.toString())
207+ putString(" longitude" , location.longitude.toString())
208+ putDouble(" timestamp" , location.time.toDouble())
209+
210+ // Add optional fields if available
211+ if (location.hasAccuracy()) {
212+ putDouble(" accuracy" , location.accuracy.toDouble())
213+ }
214+ if (location.hasAltitude()) {
215+ putDouble(" altitude" , location.altitude)
216+ }
217+ if (location.hasSpeed()) {
218+ putDouble(" speed" , location.speed.toDouble())
219+ }
220+ if (location.hasBearing()) {
221+ putDouble(" bearing" , location.bearing.toDouble())
222+ }
223+
224+ // API 26+ fields - check if values are valid (not NaN)
225+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .O ) {
226+ val verticalAccuracy = location.verticalAccuracyMeters
227+ if (! verticalAccuracy.isNaN()) {
228+ putDouble(" verticalAccuracyMeters" , verticalAccuracy.toDouble())
229+ }
230+
231+ val speedAccuracy = location.speedAccuracyMetersPerSecond
232+ if (! speedAccuracy.isNaN()) {
233+ putDouble(" speedAccuracyMetersPerSecond" , speedAccuracy.toDouble())
234+ }
235+
236+ val bearingAccuracy = location.bearingAccuracyDegrees
237+ if (! bearingAccuracy.isNaN()) {
238+ putDouble(" bearingAccuracyDegrees" , bearingAccuracy.toDouble())
239+ }
240+ }
241+
242+ // Always available fields
243+ putDouble(" elapsedRealtimeNanos" , location.elapsedRealtimeNanos.toDouble())
244+ location.provider?.let { putString(" provider" , it) }
245+
246+ // API 18+ field
247+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .JELLY_BEAN_MR2 ) {
248+ putBoolean(" isFromMockProvider" , location.isFromMockProvider)
249+ }
250+ }
251+ return map
252+ }
163253
164254 private fun createNotificationChannel () {
165255 if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .O ) {
0 commit comments