react-native-nitro-location-tracking 0.1.8 → 0.1.10

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 (28) hide show
  1. package/README.md +216 -87
  2. package/android/build.gradle +1 -0
  3. package/android/src/main/java/com/margelo/nitro/nitrolocationtracking/GeofenceManager.kt +10 -0
  4. package/android/src/main/java/com/margelo/nitro/nitrolocationtracking/LocationEngine.kt +3 -0
  5. package/android/src/main/java/com/margelo/nitro/nitrolocationtracking/NitroLocationTracking.kt +23 -0
  6. package/android/src/main/java/com/margelo/nitro/nitrolocationtracking/PermissionStatusMonitor.kt +85 -0
  7. package/ios/GeofenceManager.swift +6 -0
  8. package/ios/LocationEngine.swift +24 -0
  9. package/ios/NitroLocationTracking.swift +18 -0
  10. package/lib/module/index.js.map +1 -1
  11. package/lib/typescript/src/NitroLocationTracking.nitro.d.ts +4 -0
  12. package/lib/typescript/src/NitroLocationTracking.nitro.d.ts.map +1 -1
  13. package/lib/typescript/src/index.d.ts +1 -1
  14. package/lib/typescript/src/index.d.ts.map +1 -1
  15. package/nitrogen/generated/android/c++/JFunc_void_PermissionStatus.hpp +77 -0
  16. package/nitrogen/generated/android/c++/JHybridNitroLocationTrackingSpec.cpp +15 -0
  17. package/nitrogen/generated/android/c++/JHybridNitroLocationTrackingSpec.hpp +3 -0
  18. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrolocationtracking/Func_void_PermissionStatus.kt +80 -0
  19. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrolocationtracking/HybridNitroLocationTrackingSpec.kt +17 -0
  20. package/nitrogen/generated/android/nitrolocationtrackingOnLoad.cpp +2 -0
  21. package/nitrogen/generated/ios/c++/HybridNitroLocationTrackingSpecSwift.hpp +22 -0
  22. package/nitrogen/generated/ios/swift/HybridNitroLocationTrackingSpec.swift +3 -0
  23. package/nitrogen/generated/ios/swift/HybridNitroLocationTrackingSpec_cxx.swift +40 -0
  24. package/nitrogen/generated/shared/c++/HybridNitroLocationTrackingSpec.cpp +3 -0
  25. package/nitrogen/generated/shared/c++/HybridNitroLocationTrackingSpec.hpp +3 -0
  26. package/package.json +1 -1
  27. package/src/NitroLocationTracking.nitro.ts +12 -0
  28. package/src/index.tsx +1 -0
package/README.md CHANGED
@@ -91,7 +91,8 @@ const granted = await requestLocationPermission(
91
91
  },
92
92
  {
93
93
  title: 'Background Location',
94
- message: 'Allow background location to keep tracking while the app is minimized.',
94
+ message:
95
+ 'Allow background location to keep tracking while the app is minimized.',
95
96
  buttonPositive: 'Allow',
96
97
  buttonNegative: 'Deny',
97
98
  }
@@ -109,13 +110,13 @@ import { useDriverLocation } from 'react-native-nitro-location-tracking';
109
110
  import type { LocationConfig } from 'react-native-nitro-location-tracking';
110
111
 
111
112
  const config: LocationConfig = {
112
- desiredAccuracy: 'high', // 'high' | 'balanced' | 'low'
113
- distanceFilter: 10, // meters
114
- intervalMs: 3000, // Android only
115
- fastestIntervalMs: 1000, // Android only
116
- stopTimeout: 5, // minutes before declaring stopped
117
- stopOnTerminate: false, // keep tracking after app close (Android)
118
- startOnBoot: true, // restart tracking after reboot (Android)
113
+ desiredAccuracy: 'high', // 'high' | 'balanced' | 'low'
114
+ distanceFilter: 10, // meters
115
+ intervalMs: 3000, // Android only
116
+ fastestIntervalMs: 1000, // Android only
117
+ stopTimeout: 5, // minutes before declaring stopped
118
+ stopOnTerminate: false, // keep tracking after app close (Android)
119
+ startOnBoot: true, // restart tracking after reboot (Android)
119
120
  foregroundNotificationTitle: 'Tracking Active',
120
121
  foregroundNotificationText: 'Your location is being tracked',
121
122
  };
@@ -155,8 +156,8 @@ const connectionConfig: ConnectionConfig = {
155
156
  authToken: 'your-auth-token',
156
157
  reconnectIntervalMs: 5000,
157
158
  maxReconnectAttempts: 10,
158
- batchSize: 5, // locations per batch upload
159
- syncIntervalMs: 10000, // flush queue every 10s
159
+ batchSize: 5, // locations per batch upload
160
+ syncIntervalMs: 10000, // flush queue every 10s
160
161
  };
161
162
 
162
163
  function RideScreen() {
@@ -238,10 +239,10 @@ NitroLocationModule.onLocation((location) => {
238
239
 
239
240
  **Platform behavior:**
240
241
 
241
- | Platform | Per-location detection | Device-level detection |
242
- |----------|----------------------|------------------------|
243
- | Android | `Location.isMock` (API 31+) / `isFromMockProvider` (API 18+) | `AppOpsManager` mock location check |
244
- | iOS | `CLLocation.sourceInformation.isSimulatedBySoftware` (iOS 15+) | Simulator detection |
242
+ | Platform | Per-location detection | Device-level detection |
243
+ | -------- | -------------------------------------------------------------- | ----------------------------------- |
244
+ | Android | `Location.isMock` (API 31+) / `isFromMockProvider` (API 18+) | `AppOpsManager` mock location check |
245
+ | iOS | `CLLocation.sourceInformation.isSimulatedBySoftware` (iOS 15+) | Simulator detection |
245
246
 
246
247
  ### Smooth Map Marker Animation
247
248
 
@@ -287,7 +288,10 @@ function MapScreen() {
287
288
  Calculate bearing between two coordinates and handle rotation smoothing:
288
289
 
289
290
  ```tsx
290
- import { calculateBearing, shortestRotation } from 'react-native-nitro-location-tracking';
291
+ import {
292
+ calculateBearing,
293
+ shortestRotation,
294
+ } from 'react-native-nitro-location-tracking';
291
295
 
292
296
  // Calculate bearing from point A to point B (in degrees, 0-360)
293
297
  const bearing = calculateBearing(
@@ -333,6 +337,49 @@ NitroLocationModule.removeAllGeofences();
333
337
 
334
338
  > **Note:** iOS limits geofence regions to 20 per app. Android supports up to 100.
335
339
 
340
+ ### Distance Utilities
341
+
342
+ Calculate distance between two points or from the current location to a registered geofence:
343
+
344
+ ```tsx
345
+ import NitroLocationModule from 'react-native-nitro-location-tracking';
346
+
347
+ // Calculate distance between any two coordinates (returns meters)
348
+ const meters = NitroLocationModule.getDistanceBetween(
349
+ 41.311158,
350
+ 69.279737, // point A
351
+ 41.3152,
352
+ 69.2851 // point B
353
+ );
354
+ console.log(`Distance: ${meters.toFixed(0)}m`);
355
+
356
+ // Get distance from current location to a registered geofence center
357
+ // First, register a geofence
358
+ NitroLocationModule.addGeofence({
359
+ id: 'branch-123',
360
+ latitude: 41.311158,
361
+ longitude: 69.279737,
362
+ radius: 150,
363
+ notifyOnEntry: true,
364
+ notifyOnExit: true,
365
+ });
366
+
367
+ // Then query distance using the same region id
368
+ const distToBranch = NitroLocationModule.getDistanceToGeofence('branch-123');
369
+ if (distToBranch >= 0) {
370
+ console.log(`Distance to branch: ${distToBranch.toFixed(0)}m`);
371
+ } else {
372
+ console.warn('Geofence not found or no location available');
373
+ }
374
+ ```
375
+
376
+ **Key points:**
377
+
378
+ - Both methods use **native distance APIs** (`CLLocation.distance(from:)` on iOS, `Location.distanceBetween()` on Android) — no JS-thread computation.
379
+ - `getDistanceBetween()` is a pure utility — pass any two lat/lng pairs.
380
+ - `getDistanceToGeofence()` uses the device's **last known native location** and the registered geofence center. Returns `-1` if the region ID is not found or no location is available.
381
+ - The `regionId` is the `id` string you set when calling `addGeofence()`.
382
+
336
383
  ### Speed Monitoring
337
384
 
338
385
  Get alerts when speed crosses configurable thresholds:
@@ -342,9 +389,9 @@ import NitroLocationModule from 'react-native-nitro-location-tracking';
342
389
 
343
390
  // Configure speed thresholds
344
391
  NitroLocationModule.configureSpeedMonitor({
345
- maxSpeedKmh: 120, // alert when exceeding 120 km/h
346
- minSpeedKmh: 5, // alert when below 5 km/h (idle detection)
347
- checkIntervalMs: 0, // check on every location update
392
+ maxSpeedKmh: 120, // alert when exceeding 120 km/h
393
+ minSpeedKmh: 5, // alert when below 5 km/h (idle detection)
394
+ checkIntervalMs: 0, // check on every location update
348
395
  });
349
396
 
350
397
  // Listen for speed state transitions
@@ -434,13 +481,91 @@ switch (status) {
434
481
  }
435
482
  ```
436
483
 
437
- | Status | iOS | Android |
438
- |--------|-----|----------|
439
- | `notDetermined` | Not yet asked | N/A (returns `denied`) |
440
- | `denied` | User denied | Fine location not granted |
441
- | `restricted` | Parental/MDM restriction | N/A (returns `denied`) |
442
- | `whenInUse` | Authorized when in use | Fine granted, background not |
443
- | `always` | Authorized always | Fine + background granted |
484
+ | Status | iOS | Android |
485
+ | --------------- | ------------------------ | ---------------------------- |
486
+ | `notDetermined` | Not yet asked | N/A (returns `denied`) |
487
+ | `denied` | User denied | Fine location not granted |
488
+ | `restricted` | Parental/MDM restriction | N/A (returns `denied`) |
489
+ | `whenInUse` | Authorized when in use | Fine granted, background not |
490
+ | `always` | Authorized always | Fine + background granted |
491
+
492
+ ### Request Permission (Native)
493
+
494
+ Request location permission directly via the native module and get the resulting status:
495
+
496
+ ```tsx
497
+ import NitroLocationModule from 'react-native-nitro-location-tracking';
498
+
499
+ async function setup() {
500
+ // Check current status first (no dialog)
501
+ const current = NitroLocationModule.getLocationPermissionStatus();
502
+
503
+ if (current === 'always' || current === 'whenInUse') {
504
+ // Already granted — start tracking
505
+ NitroLocationModule.startTracking();
506
+ return;
507
+ }
508
+
509
+ // Request permission — shows the system dialog
510
+ const status = await NitroLocationModule.requestLocationPermission();
511
+
512
+ switch (status) {
513
+ case 'always':
514
+ case 'whenInUse':
515
+ NitroLocationModule.startTracking();
516
+ break;
517
+ case 'denied':
518
+ Alert.alert('Location Required', 'Please enable location in Settings');
519
+ break;
520
+ case 'restricted':
521
+ // Parental controls / MDM — cannot request
522
+ break;
523
+ }
524
+ }
525
+ ```
526
+
527
+ **Platform behavior:**
528
+
529
+ | Platform | Behavior |
530
+ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
531
+ | iOS | Calls `requestAlwaysAuthorization()`. If permission is already determined, resolves immediately with current status. If `start()` was called before permission was granted, tracking auto-starts once the user allows. |
532
+ | Android | Uses React Native's `PermissionAwareActivity` to show the system permission dialog for `ACCESS_FINE_LOCATION` + `ACCESS_COARSE_LOCATION`. Resolves with the resulting status after the user responds. |
533
+
534
+ ### Permission Change Listener
535
+
536
+ Listen for permission changes in real time. The callback fires whenever the user changes the location permission (via the system dialog, the Settings app, or MDM policy changes):
537
+
538
+ ```tsx
539
+ import NitroLocationModule from 'react-native-nitro-location-tracking';
540
+
541
+ // Register a listener — fires whenever the permission status changes
542
+ NitroLocationModule.onPermissionStatusChange((status) => {
543
+ console.log('Permission changed to:', status);
544
+ // status: 'notDetermined' | 'denied' | 'restricted' | 'whenInUse' | 'always'
545
+
546
+ switch (status) {
547
+ case 'always':
548
+ console.log('Background location granted — full tracking available');
549
+ break;
550
+ case 'whenInUse':
551
+ console.log('Foreground only — background tracking may not work');
552
+ break;
553
+ case 'denied':
554
+ Alert.alert('Location Required', 'Please re-enable location in Settings');
555
+ break;
556
+ case 'restricted':
557
+ console.warn('Location restricted by parental controls or MDM');
558
+ break;
559
+ }
560
+ });
561
+ ```
562
+
563
+ **Platform behavior:**
564
+
565
+ | Platform | Mechanism | When the callback fires |
566
+ | -------- | --------- | ----------------------- |
567
+ | iOS | `locationManagerDidChangeAuthorization` delegate | Immediately when the user changes permission (system dialog, Settings, MDM) |
568
+ | Android | `ProcessLifecycleOwner` lifecycle observer | When the app returns to foreground after the user changes permission in Settings |
444
569
 
445
570
  ## API Reference
446
571
 
@@ -453,11 +578,11 @@ interface LocationData {
453
578
  latitude: number;
454
579
  longitude: number;
455
580
  altitude: number;
456
- speed: number; // m/s
457
- bearing: number; // degrees
458
- accuracy: number; // meters
459
- timestamp: number; // unix ms
460
- isMockLocation?: boolean; // true when from a mock provider
581
+ speed: number; // m/s
582
+ bearing: number; // degrees
583
+ accuracy: number; // meters
584
+ timestamp: number; // unix ms
585
+ isMockLocation?: boolean; // true when from a mock provider
461
586
  }
462
587
  ```
463
588
 
@@ -466,12 +591,12 @@ interface LocationData {
466
591
  ```ts
467
592
  interface LocationConfig {
468
593
  desiredAccuracy: 'high' | 'balanced' | 'low';
469
- distanceFilter: number; // meters
470
- intervalMs: number; // Android only
471
- fastestIntervalMs: number; // Android only
472
- stopTimeout: number; // minutes before declaring stopped
473
- stopOnTerminate: boolean; // keep tracking after app close (Android)
474
- startOnBoot: boolean; // restart tracking after reboot (Android)
594
+ distanceFilter: number; // meters
595
+ intervalMs: number; // Android only
596
+ fastestIntervalMs: number; // Android only
597
+ stopTimeout: number; // minutes before declaring stopped
598
+ stopOnTerminate: boolean; // keep tracking after app close (Android)
599
+ startOnBoot: boolean; // restart tracking after reboot (Android)
475
600
  foregroundNotificationTitle: string;
476
601
  foregroundNotificationText: string;
477
602
  }
@@ -486,7 +611,7 @@ interface ConnectionConfig {
486
611
  authToken: string;
487
612
  reconnectIntervalMs: number;
488
613
  maxReconnectAttempts: number;
489
- batchSize: number; // locations per batch upload
614
+ batchSize: number; // locations per batch upload
490
615
  syncIntervalMs: number; // how often to flush queue
491
616
  }
492
617
  ```
@@ -498,7 +623,7 @@ interface GeofenceRegion {
498
623
  id: string;
499
624
  latitude: number;
500
625
  longitude: number;
501
- radius: number; // meters
626
+ radius: number; // meters
502
627
  notifyOnEntry: boolean;
503
628
  notifyOnExit: boolean;
504
629
  }
@@ -508,9 +633,9 @@ interface GeofenceRegion {
508
633
 
509
634
  ```ts
510
635
  interface SpeedConfig {
511
- maxSpeedKmh: number; // speed limit in km/h
512
- minSpeedKmh: number; // minimum speed threshold
513
- checkIntervalMs: number; // how often to evaluate
636
+ maxSpeedKmh: number; // speed limit in km/h
637
+ minSpeedKmh: number; // minimum speed threshold
638
+ checkIntervalMs: number; // how often to evaluate
514
639
  }
515
640
  ```
516
641
 
@@ -539,58 +664,62 @@ type PermissionStatus =
539
664
 
540
665
  ### Hooks
541
666
 
542
- | Hook | Returns | Description |
543
- |------|---------|-------------|
544
- | `useDriverLocation(config)` | `{ location, isMoving, isTracking, startTracking, stopTracking }` | Manages location tracking lifecycle |
545
- | `useRideConnection(config)` | `{ connectionState, lastMessage, connect, disconnect, send }` | Manages WebSocket connection lifecycle |
667
+ | Hook | Returns | Description |
668
+ | --------------------------- | ----------------------------------------------------------------- | -------------------------------------- |
669
+ | `useDriverLocation(config)` | `{ location, isMoving, isTracking, startTracking, stopTracking }` | Manages location tracking lifecycle |
670
+ | `useRideConnection(config)` | `{ connectionState, lastMessage, connect, disconnect, send }` | Manages WebSocket connection lifecycle |
546
671
 
547
672
  ### Native Module Methods
548
673
 
549
- | Method | Returns | Description |
550
- |--------|---------|-------------|
551
- | `configure(config)` | `void` | Set location tracking configuration |
552
- | `startTracking()` | `void` | Start location tracking |
553
- | `stopTracking()` | `void` | Stop location tracking |
554
- | `getCurrentLocation()` | `Promise<LocationData>` | Get a one-shot location |
555
- | `isTracking()` | `boolean` | Check if tracking is active |
556
- | `onLocation(callback)` | `void` | Register location update callback |
557
- | `onMotionChange(callback)` | `void` | Register motion state callback |
558
- | `configureConnection(config)` | `void` | Set WebSocket/REST configuration |
559
- | `connectWebSocket()` | `void` | Open WebSocket connection |
560
- | `disconnectWebSocket()` | `void` | Close WebSocket connection |
561
- | `sendMessage(message)` | `void` | Send a message via WebSocket |
562
- | `getConnectionState()` | `ConnectionState` | Get current connection state |
563
- | `onConnectionStateChange(callback)` | `void` | Register connection state callback |
564
- | `onMessage(callback)` | `void` | Register incoming message callback |
565
- | `forceSync()` | `Promise<boolean>` | Flush queued locations to server |
566
- | `isFakeGpsEnabled()` | `boolean` | Check if device-level mock location is enabled |
567
- | `setRejectMockLocations(reject)` | `void` | Auto-reject mock locations when `true` |
568
- | `addGeofence(region)` | `void` | Start monitoring a circular geofence region |
569
- | `removeGeofence(regionId)` | `void` | Stop monitoring a specific geofence |
570
- | `removeAllGeofences()` | `void` | Remove all active geofences |
571
- | `onGeofenceEvent(callback)` | `void` | Register geofence enter/exit callback |
572
- | `configureSpeedMonitor(config)` | `void` | Set speed monitoring thresholds |
573
- | `onSpeedAlert(callback)` | `void` | Register speed state-transition callback |
574
- | `getCurrentSpeed()` | `number` | Get current speed in km/h |
575
- | `startTripCalculation()` | `void` | Start recording trip distance/stats |
576
- | `stopTripCalculation()` | `TripStats` | Stop recording and get final stats |
577
- | `getTripStats()` | `TripStats` | Get current trip stats without stopping |
578
- | `resetTripCalculation()` | `void` | Reset trip calculator |
579
- | `isLocationServicesEnabled()` | `boolean` | Check if GPS/location is enabled on device |
580
- | `onProviderStatusChange(callback)` | `void` | Register GPS/network provider status callback |
581
- | `getLocationPermissionStatus()` | `PermissionStatus` | Check current location permission without prompting |
582
- | `showLocalNotification(title, body)` | `void` | Show a local notification |
583
- | `updateForegroundNotification(title, body)` | `void` | Update the foreground service notification |
584
- | `destroy()` | `void` | Stop tracking and disconnect |
674
+ | Method | Returns | Description |
675
+ | -------------------------------------------- | --------------------------- | ---------------------------------------------------------------------------------------- |
676
+ | `configure(config)` | `void` | Set location tracking configuration |
677
+ | `startTracking()` | `void` | Start location tracking |
678
+ | `stopTracking()` | `void` | Stop location tracking |
679
+ | `getCurrentLocation()` | `Promise<LocationData>` | Get a one-shot location |
680
+ | `isTracking()` | `boolean` | Check if tracking is active |
681
+ | `onLocation(callback)` | `void` | Register location update callback |
682
+ | `onMotionChange(callback)` | `void` | Register motion state callback |
683
+ | `configureConnection(config)` | `void` | Set WebSocket/REST configuration |
684
+ | `connectWebSocket()` | `void` | Open WebSocket connection |
685
+ | `disconnectWebSocket()` | `void` | Close WebSocket connection |
686
+ | `sendMessage(message)` | `void` | Send a message via WebSocket |
687
+ | `getConnectionState()` | `ConnectionState` | Get current connection state |
688
+ | `onConnectionStateChange(callback)` | `void` | Register connection state callback |
689
+ | `onMessage(callback)` | `void` | Register incoming message callback |
690
+ | `forceSync()` | `Promise<boolean>` | Flush queued locations to server |
691
+ | `isFakeGpsEnabled()` | `boolean` | Check if device-level mock location is enabled |
692
+ | `setRejectMockLocations(reject)` | `void` | Auto-reject mock locations when `true` |
693
+ | `addGeofence(region)` | `void` | Start monitoring a circular geofence region |
694
+ | `removeGeofence(regionId)` | `void` | Stop monitoring a specific geofence |
695
+ | `removeAllGeofences()` | `void` | Remove all active geofences |
696
+ | `onGeofenceEvent(callback)` | `void` | Register geofence enter/exit callback |
697
+ | `getDistanceBetween(lat1, lon1, lat2, lon2)` | `number` | Calculate distance between two points in meters (native Haversine) |
698
+ | `getDistanceToGeofence(regionId)` | `number` | Get distance in meters from last known location to a geofence center (`-1` if not found) |
699
+ | `configureSpeedMonitor(config)` | `void` | Set speed monitoring thresholds |
700
+ | `onSpeedAlert(callback)` | `void` | Register speed state-transition callback |
701
+ | `getCurrentSpeed()` | `number` | Get current speed in km/h |
702
+ | `startTripCalculation()` | `void` | Start recording trip distance/stats |
703
+ | `stopTripCalculation()` | `TripStats` | Stop recording and get final stats |
704
+ | `getTripStats()` | `TripStats` | Get current trip stats without stopping |
705
+ | `resetTripCalculation()` | `void` | Reset trip calculator |
706
+ | `isLocationServicesEnabled()` | `boolean` | Check if GPS/location is enabled on device |
707
+ | `onProviderStatusChange(callback)` | `void` | Register GPS/network provider status callback |
708
+ | `getLocationPermissionStatus()` | `PermissionStatus` | Check current location permission without prompting |
709
+ | `requestLocationPermission()` | `Promise<PermissionStatus>` | Request location permission and return the resulting status |
710
+ | `onPermissionStatusChange(callback)` | `void` | Register a callback that fires when location permission status changes |
711
+ | `showLocalNotification(title, body)` | `void` | Show a local notification |
712
+ | `updateForegroundNotification(title, body)` | `void` | Update the foreground service notification |
713
+ | `destroy()` | `void` | Stop tracking and disconnect |
585
714
 
586
715
  ### Utility Exports
587
716
 
588
- | Export | Description |
589
- |--------|-------------|
590
- | `LocationSmoother` | Class for smooth map marker animation between updates |
591
- | `calculateBearing(from, to)` | Calculate bearing between two coordinates (degrees, 0-360) |
592
- | `shortestRotation(from, to)` | Calculate shortest rotation path to avoid spinning |
593
- | `requestLocationPermission()` | Request location + notification permissions (Android) |
717
+ | Export | Description |
718
+ | ----------------------------- | ---------------------------------------------------------- |
719
+ | `LocationSmoother` | Class for smooth map marker animation between updates |
720
+ | `calculateBearing(from, to)` | Calculate bearing between two coordinates (degrees, 0-360) |
721
+ | `shortestRotation(from, to)` | Calculate shortest rotation path to avoid spinning |
722
+ | `requestLocationPermission()` | Request location + notification permissions (Android) |
594
723
 
595
724
  ## Publishing to npm
596
725
 
@@ -119,4 +119,5 @@ dependencies {
119
119
  implementation "com.squareup.okhttp3:okhttp:4.12.0"
120
120
  implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0"
121
121
  implementation "androidx.core:core-ktx:1.15.0"
122
+ implementation "androidx.lifecycle:lifecycle-process:2.8.7"
122
123
  }
@@ -135,6 +135,16 @@ class GeofenceManager(private val context: Context) {
135
135
  }
136
136
  }
137
137
 
138
+ fun distanceTo(regionId: String, lastLocation: android.location.Location?): Double {
139
+ val region = activeRegions[regionId] ?: return -1.0
140
+ val loc = lastLocation ?: return -1.0
141
+ val results = FloatArray(1)
142
+ android.location.Location.distanceBetween(
143
+ loc.latitude, loc.longitude, region.latitude, region.longitude, results
144
+ )
145
+ return results[0].toDouble()
146
+ }
147
+
138
148
  fun destroy() {
139
149
  removeAllGeofences()
140
150
  receiver?.let {
@@ -28,6 +28,8 @@ class LocationEngine(private val context: Context) {
28
28
  val tripCalculator = TripCalculator()
29
29
  private var lastSpeed = 0f
30
30
  private var tracking = false
31
+ var lastLocation: Location? = null
32
+ private set
31
33
 
32
34
  val isTracking: Boolean get() = tracking
33
35
 
@@ -90,6 +92,7 @@ class LocationEngine(private val context: Context) {
90
92
  // }
91
93
 
92
94
  private fun processLocation(location: Location) {
95
+ lastLocation = location
93
96
  val data = locationToData(location)
94
97
 
95
98
  // Skip mock locations if rejection is enabled
@@ -26,6 +26,7 @@ class NitroLocationTracking : HybridNitroLocationTrackingSpec() {
26
26
  private var notificationService: NotificationService? = null
27
27
  private var geofenceManager: GeofenceManager? = null
28
28
  private var providerStatusMonitor: ProviderStatusMonitor? = null
29
+ private var permissionStatusMonitor: PermissionStatusMonitor? = null
29
30
 
30
31
  private var locationCallback: ((LocationData) -> Unit)? = null
31
32
  private var motionCallback: ((Boolean) -> Unit)? = null
@@ -34,6 +35,7 @@ class NitroLocationTracking : HybridNitroLocationTrackingSpec() {
34
35
  private var geofenceCallback: ((GeofenceEvent, String) -> Unit)? = null
35
36
  private var speedAlertCallback: ((SpeedAlertType, Double) -> Unit)? = null
36
37
  private var providerStatusCallback: ((LocationProviderStatus, LocationProviderStatus) -> Unit)? = null
38
+ private var permissionStatusCallback: ((PermissionStatus) -> Unit)? = null
37
39
 
38
40
  private var locationConfig: LocationConfig? = null
39
41
 
@@ -50,6 +52,7 @@ class NitroLocationTracking : HybridNitroLocationTrackingSpec() {
50
52
  notificationService = NotificationService(context)
51
53
  geofenceManager = GeofenceManager(context)
52
54
  providerStatusMonitor = ProviderStatusMonitor(context)
55
+ permissionStatusMonitor = PermissionStatusMonitor(context)
53
56
  locationEngine?.dbWriter = dbWriter
54
57
  connectionManager.dbWriter = dbWriter
55
58
  Log.d(TAG, "Components initialized successfully")
@@ -286,6 +289,12 @@ class NitroLocationTracking : HybridNitroLocationTrackingSpec() {
286
289
  return PermissionStatus.ALWAYS
287
290
  }
288
291
 
292
+ override fun onPermissionStatusChange(callback: (status: PermissionStatus) -> Unit) {
293
+ permissionStatusCallback = callback
294
+ ensureInitialized()
295
+ permissionStatusMonitor?.setCallback(callback)
296
+ }
297
+
289
298
  override fun requestLocationPermission(): Promise<PermissionStatus> {
290
299
  return Promise.async {
291
300
  suspendCoroutine { cont ->
@@ -346,6 +355,19 @@ class NitroLocationTracking : HybridNitroLocationTrackingSpec() {
346
355
  }
347
356
  }
348
357
 
358
+ // === Distance Utilities ===
359
+
360
+ override fun getDistanceBetween(lat1: Double, lon1: Double, lat2: Double, lon2: Double): Double {
361
+ val results = FloatArray(1)
362
+ android.location.Location.distanceBetween(lat1, lon1, lat2, lon2, results)
363
+ return results[0].toDouble()
364
+ }
365
+
366
+ override fun getDistanceToGeofence(regionId: String): Double {
367
+ ensureInitialized()
368
+ return geofenceManager?.distanceTo(regionId, locationEngine?.lastLocation) ?: -1.0
369
+ }
370
+
349
371
  // === Notifications ===
350
372
 
351
373
  override fun showLocalNotification(title: String, body: String) {
@@ -366,5 +388,6 @@ class NitroLocationTracking : HybridNitroLocationTrackingSpec() {
366
388
  notificationService?.stopForegroundService()
367
389
  geofenceManager?.destroy()
368
390
  providerStatusMonitor?.destroy()
391
+ permissionStatusMonitor?.destroy()
369
392
  }
370
393
  }
@@ -0,0 +1,85 @@
1
+ package com.margelo.nitro.nitrolocationtracking
2
+
3
+ import android.content.Context
4
+ import android.content.pm.PackageManager
5
+ import android.os.Build
6
+ import android.util.Log
7
+ import androidx.core.content.ContextCompat
8
+ import androidx.lifecycle.DefaultLifecycleObserver
9
+ import androidx.lifecycle.LifecycleOwner
10
+ import androidx.lifecycle.ProcessLifecycleOwner
11
+
12
+ /**
13
+ * Monitors location‐permission changes by comparing the permission status
14
+ * every time the app comes to the foreground (`ON_START`).
15
+ *
16
+ * Android has no broadcast for permission changes, so consuming the
17
+ * lifecycle is the standard approach (same as react-native-permissions).
18
+ */
19
+ class PermissionStatusMonitor(private val context: Context) {
20
+
21
+ companion object {
22
+ private const val TAG = "PermissionStatusMonitor"
23
+ }
24
+
25
+ private var callback: ((PermissionStatus) -> Unit)? = null
26
+ private var lastStatus: PermissionStatus? = null
27
+
28
+ private val lifecycleObserver = object : DefaultLifecycleObserver {
29
+ override fun onStart(owner: LifecycleOwner) {
30
+ checkAndNotify()
31
+ }
32
+ }
33
+
34
+ fun setCallback(callback: (PermissionStatus) -> Unit) {
35
+ this.callback = callback
36
+ // Capture the current status so we only fire on actual changes
37
+ lastStatus = getCurrentPermissionStatus()
38
+
39
+ // Observe the process lifecycle (app foreground / background)
40
+ try {
41
+ ProcessLifecycleOwner.get().lifecycle.addObserver(lifecycleObserver)
42
+ Log.d(TAG, "Registered lifecycle observer for permission changes")
43
+ } catch (e: Exception) {
44
+ Log.e(TAG, "Failed to register lifecycle observer: ${e.message}")
45
+ }
46
+ }
47
+
48
+ private fun checkAndNotify() {
49
+ val current = getCurrentPermissionStatus()
50
+ if (current != lastStatus) {
51
+ Log.d(TAG, "Permission status changed: $lastStatus -> $current")
52
+ lastStatus = current
53
+ callback?.invoke(current)
54
+ }
55
+ }
56
+
57
+ private fun getCurrentPermissionStatus(): PermissionStatus {
58
+ val fineGranted = ContextCompat.checkSelfPermission(
59
+ context, android.Manifest.permission.ACCESS_FINE_LOCATION
60
+ ) == PackageManager.PERMISSION_GRANTED
61
+
62
+ if (!fineGranted) {
63
+ return PermissionStatus.DENIED
64
+ }
65
+
66
+ // Fine location granted — check background
67
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
68
+ val bgGranted = ContextCompat.checkSelfPermission(
69
+ context, android.Manifest.permission.ACCESS_BACKGROUND_LOCATION
70
+ ) == PackageManager.PERMISSION_GRANTED
71
+ return if (bgGranted) PermissionStatus.ALWAYS else PermissionStatus.WHENINUSE
72
+ }
73
+
74
+ // Pre-Android 10: fine location = always
75
+ return PermissionStatus.ALWAYS
76
+ }
77
+
78
+ fun destroy() {
79
+ try {
80
+ ProcessLifecycleOwner.get().lifecycle.removeObserver(lifecycleObserver)
81
+ } catch (_: Exception) {}
82
+ callback = null
83
+ lastStatus = null
84
+ }
85
+ }
@@ -62,6 +62,12 @@ class GeofenceManager: NSObject, CLLocationManagerDelegate {
62
62
  }
63
63
  }
64
64
 
65
+ func distanceTo(regionId: String, from location: CLLocation?) -> Double {
66
+ guard let region = activeRegions[regionId], let location = location else { return -1 }
67
+ let center = CLLocation(latitude: region.latitude, longitude: region.longitude)
68
+ return location.distance(from: center)
69
+ }
70
+
65
71
  func destroy() {
66
72
  removeAllGeofences()
67
73
  callback = nil
@@ -22,6 +22,12 @@ class LocationEngine: NSObject, CLLocationManagerDelegate {
22
22
  let speedMonitor = SpeedMonitor()
23
23
  let tripCalculator = TripCalculator()
24
24
  var providerStatusCallback: ((LocationProviderStatus, LocationProviderStatus) -> Void)?
25
+ var permissionStatusCallback: ((PermissionStatus) -> Void)?
26
+
27
+ /// The most recently received location from Core Location (for distance calculations)
28
+ var lastCLLocation: CLLocation? {
29
+ return locationManager.location
30
+ }
25
31
 
26
32
  override init() {
27
33
  super.init()
@@ -207,6 +213,24 @@ class LocationEngine: NSObject, CLLocationManagerDelegate {
207
213
  }
208
214
  }
209
215
 
216
+ // Notify JS about permission status change
217
+ let permStatus: PermissionStatus
218
+ switch authStatus {
219
+ case .notDetermined:
220
+ permStatus = .notdetermined
221
+ case .restricted:
222
+ permStatus = .restricted
223
+ case .denied:
224
+ permStatus = .denied
225
+ case .authorizedWhenInUse:
226
+ permStatus = .wheninuse
227
+ case .authorizedAlways:
228
+ permStatus = .always
229
+ @unknown default:
230
+ permStatus = .notdetermined
231
+ }
232
+ permissionStatusCallback?(permStatus)
233
+
210
234
  let enabled = CLLocationManager.locationServicesEnabled()
211
235
  let status: LocationProviderStatus = enabled ? .enabled : .disabled
212
236
  providerStatusCallback?(status, status)
@@ -16,6 +16,7 @@ class NitroLocationTracking: HybridNitroLocationTrackingSpec {
16
16
  private var geofenceCallback: ((GeofenceEvent, String) -> Void)?
17
17
  private var speedAlertCallback: ((SpeedAlertType, Double) -> Void)?
18
18
  private var providerStatusCallback: ((LocationProviderStatus, LocationProviderStatus) -> Void)?
19
+ private var permissionStatusCallback: ((PermissionStatus) -> Void)?
19
20
  private var permissionPromise: Promise<PermissionStatus>?
20
21
 
21
22
  override init() {
@@ -236,6 +237,23 @@ class NitroLocationTracking: HybridNitroLocationTrackingSpec {
236
237
  return promise
237
238
  }
238
239
 
240
+ func onPermissionStatusChange(callback: @escaping (PermissionStatus) -> Void) throws {
241
+ permissionStatusCallback = callback
242
+ locationEngine.permissionStatusCallback = callback
243
+ }
244
+
245
+ // MARK: - Distance Utilities
246
+
247
+ func getDistanceBetween(lat1: Double, lon1: Double, lat2: Double, lon2: Double) throws -> Double {
248
+ let loc1 = CLLocation(latitude: lat1, longitude: lon1)
249
+ let loc2 = CLLocation(latitude: lat2, longitude: lon2)
250
+ return loc1.distance(from: loc2)
251
+ }
252
+
253
+ func getDistanceToGeofence(regionId: String) throws -> Double {
254
+ return geofenceManager.distanceTo(regionId: regionId, from: locationEngine.lastCLLocation)
255
+ }
256
+
239
257
  // MARK: - Notifications
240
258
 
241
259
  func showLocalNotification(title: String, body: String) throws {
@@ -1 +1 @@
1
- {"version":3,"names":["useState","useEffect","useCallback","useRef","NitroModules","NitroLocationModule","createHybridObject","requestLocationPermission","LocationSmoother","shortestRotation","calculateBearing","useDriverLocation","config","location","setLocation","isMoving","setIsMoving","isTracking","setIsTracking","configJson","JSON","stringify","trackingRef","parsed","parse","configure","onLocation","onMotionChange","current","stopTracking","startTracking","useRideConnection","connectionState","setConnectionState","lastMessage","setLastMessage","configureConnection","onConnectionStateChange","onMessage","disconnectWebSocket","connect","connectWebSocket","disconnect","send","m","sendMessage"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["useState","useEffect","useCallback","useRef","NitroModules","NitroLocationModule","createHybridObject","requestLocationPermission","LocationSmoother","shortestRotation","calculateBearing","useDriverLocation","config","location","setLocation","isMoving","setIsMoving","isTracking","setIsTracking","configJson","JSON","stringify","trackingRef","parsed","parse","configure","onLocation","onMotionChange","current","stopTracking","startTracking","useRideConnection","connectionState","setConnectionState","lastMessage","setLastMessage","configureConnection","onConnectionStateChange","onMessage","disconnectWebSocket","connect","connectWebSocket","disconnect","send","m","sendMessage"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SAASA,QAAQ,EAAEC,SAAS,EAAEC,WAAW,EAAEC,MAAM,QAAQ,OAAO;AAChE,SAASC,YAAY,QAAQ,4BAA4B;AAQzD,MAAMC,mBAAmB,GACvBD,YAAY,CAACE,kBAAkB,CAC7B,uBACF,CAAC;AAEH,eAAeD,mBAAmB;AAClC,SAASE,yBAAyB,QAAQ,wBAAqB;AAC/D,SAASC,gBAAgB,QAAQ,uBAAoB;AACrD,SAASC,gBAAgB,EAAEC,gBAAgB,QAAQ,cAAW;AAC9D;;AAmBA,OAAO,SAASC,iBAAiBA,CAACC,MAAsB,EAAE;EACxD,MAAM,CAACC,QAAQ,EAAEC,WAAW,CAAC,GAAGd,QAAQ,CAAsB,IAAI,CAAC;EACnE,MAAM,CAACe,QAAQ,EAAEC,WAAW,CAAC,GAAGhB,QAAQ,CAAC,KAAK,CAAC;EAC/C,MAAM,CAACiB,UAAU,EAAEC,aAAa,CAAC,GAAGlB,QAAQ,CAAC,KAAK,CAAC;;EAEnD;EACA,MAAMmB,UAAU,GAAGC,IAAI,CAACC,SAAS,CAACT,MAAM,CAAC;;EAEzC;EACA,MAAMU,WAAW,GAAGnB,MAAM,CAAC,KAAK,CAAC;EAEjCF,SAAS,CAAC,MAAM;IACd,MAAMsB,MAAM,GAAGH,IAAI,CAACI,KAAK,CAACL,UAAU,CAAmB;IACvDd,mBAAmB,CAACoB,SAAS,CAACF,MAAM,CAAC;IACrClB,mBAAmB,CAACqB,UAAU,CAACZ,WAAW,CAAC;IAC3CT,mBAAmB,CAACsB,cAAc,CAACX,WAAW,CAAC;IAC/C,OAAO,MAAM;MACX,IAAIM,WAAW,CAACM,OAAO,EAAE;QACvBvB,mBAAmB,CAACwB,YAAY,CAAC,CAAC;QAClCP,WAAW,CAACM,OAAO,GAAG,KAAK;MAC7B;IACF,CAAC;EACH,CAAC,EAAE,CAACT,UAAU,CAAC,CAAC;EAEhB,OAAO;IACLN,QAAQ;IACRE,QAAQ;IACRE,UAAU;IACVa,aAAa,EAAE5B,WAAW,CAAC,MAAM;MAC/BG,mBAAmB,CAACyB,aAAa,CAAC,CAAC;MACnCR,WAAW,CAACM,OAAO,GAAG,IAAI;MAC1BV,aAAa,CAAC,IAAI,CAAC;IACrB,CAAC,EAAE,EAAE,CAAC;IACNW,YAAY,EAAE3B,WAAW,CAAC,MAAM;MAC9BG,mBAAmB,CAACwB,YAAY,CAAC,CAAC;MAClCP,WAAW,CAACM,OAAO,GAAG,KAAK;MAC3BV,aAAa,CAAC,KAAK,CAAC;IACtB,CAAC,EAAE,EAAE;EACP,CAAC;AACH;AAEA,OAAO,SAASa,iBAAiBA,CAACnB,MAAwB,EAAE;EAC1D,MAAM,CAACoB,eAAe,EAAEC,kBAAkB,CAAC,GAAGjC,QAAQ,CAEpD,cAAc,CAAC;EACjB,MAAM,CAACkC,WAAW,EAAEC,cAAc,CAAC,GAAGnC,QAAQ,CAAgB,IAAI,CAAC;EAEnEC,SAAS,CAAC,MAAM;IACdI,mBAAmB,CAAC+B,mBAAmB,CAACxB,MAAM,CAAC;IAC/CP,mBAAmB,CAACgC,uBAAuB,CAACJ,kBAAkB,CAAC;IAC/D5B,mBAAmB,CAACiC,SAAS,CAACH,cAAc,CAAC;IAC7C,OAAO,MAAM;MACX9B,mBAAmB,CAACkC,mBAAmB,CAAC,CAAC;IAC3C,CAAC;EACH,CAAC,EAAE,CAAC3B,MAAM,CAAC,CAAC;EAEZ,OAAO;IACLoB,eAAe;IACfE,WAAW;IACXM,OAAO,EAAEtC,WAAW,CAAC,MAAMG,mBAAmB,CAACoC,gBAAgB,CAAC,CAAC,EAAE,EAAE,CAAC;IACtEC,UAAU,EAAExC,WAAW,CACrB,MAAMG,mBAAmB,CAACkC,mBAAmB,CAAC,CAAC,EAC/C,EACF,CAAC;IACDI,IAAI,EAAEzC,WAAW,CAAE0C,CAAS,IAAKvC,mBAAmB,CAACwC,WAAW,CAACD,CAAC,CAAC,EAAE,EAAE;EACzE,CAAC;AACH","ignoreList":[]}
@@ -61,6 +61,7 @@ export interface TripStats {
61
61
  export type LocationProviderStatus = 'enabled' | 'disabled';
62
62
  export type ProviderStatusCallback = (gps: LocationProviderStatus, network: LocationProviderStatus) => void;
63
63
  export type PermissionStatus = 'notDetermined' | 'denied' | 'restricted' | 'whenInUse' | 'always';
64
+ export type PermissionStatusCallback = (status: PermissionStatus) => void;
64
65
  export interface NitroLocationTracking extends HybridObject<{
65
66
  ios: 'swift';
66
67
  android: 'kotlin';
@@ -97,6 +98,9 @@ export interface NitroLocationTracking extends HybridObject<{
97
98
  onProviderStatusChange(callback: ProviderStatusCallback): void;
98
99
  getLocationPermissionStatus(): PermissionStatus;
99
100
  requestLocationPermission(): Promise<PermissionStatus>;
101
+ onPermissionStatusChange(callback: PermissionStatusCallback): void;
102
+ getDistanceBetween(lat1: number, lon1: number, lat2: number, lon2: number): number;
103
+ getDistanceToGeofence(regionId: string): number;
100
104
  showLocalNotification(title: string, body: string): void;
101
105
  updateForegroundNotification(title: string, body: string): void;
102
106
  destroy(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"NitroLocationTracking.nitro.d.ts","sourceRoot":"","sources":["../../../src/NitroLocationTracking.nitro.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"NitroLocationTracking.nitro.d.ts","sourceRoot":"","sources":["../../../src/NitroLocationTracking.nitro.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@ export default NitroLocationModule;
4
4
  export { requestLocationPermission } from './requestPermission';
5
5
  export { LocationSmoother } from './LocationSmoother';
6
6
  export { shortestRotation, calculateBearing } from './bearing';
7
- export type { NitroLocationTracking, LocationData, LocationConfig, ConnectionConfig, GeofenceRegion, GeofenceEvent, GeofenceCallback, SpeedConfig, SpeedAlertType, SpeedAlertCallback, TripStats, LocationProviderStatus, ProviderStatusCallback, PermissionStatus, } from './NitroLocationTracking.nitro';
7
+ export type { NitroLocationTracking, LocationData, LocationConfig, ConnectionConfig, GeofenceRegion, GeofenceEvent, GeofenceCallback, SpeedConfig, SpeedAlertType, SpeedAlertCallback, TripStats, LocationProviderStatus, ProviderStatusCallback, PermissionStatus, PermissionStatusCallback, } from './NitroLocationTracking.nitro';
8
8
  export declare function useDriverLocation(config: LocationConfig): {
9
9
  location: LocationData | null;
10
10
  isMoving: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,qBAAqB,EACrB,YAAY,EACZ,cAAc,EACd,gBAAgB,EACjB,MAAM,+BAA+B,CAAC;AAEvC,QAAA,MAAM,mBAAmB,uBAGtB,CAAC;AAEJ,eAAe,mBAAmB,CAAC;AACnC,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE/D,YAAY,EACV,qBAAqB,EACrB,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,SAAS,EACT,sBAAsB,EACtB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,+BAA+B,CAAC;AAEvC,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc;;;;;;EAuCvD;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,gBAAgB;;;;;cAuBhC,MAAM;EAE/B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,qBAAqB,EACrB,YAAY,EACZ,cAAc,EACd,gBAAgB,EACjB,MAAM,+BAA+B,CAAC;AAEvC,QAAA,MAAM,mBAAmB,uBAGtB,CAAC;AAEJ,eAAe,mBAAmB,CAAC;AACnC,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE/D,YAAY,EACV,qBAAqB,EACrB,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,SAAS,EACT,sBAAsB,EACtB,sBAAsB,EACtB,gBAAgB,EAChB,wBAAwB,GACzB,MAAM,+BAA+B,CAAC;AAEvC,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc;;;;;;EAuCvD;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,gBAAgB;;;;;cAuBhC,MAAM;EAE/B"}
@@ -0,0 +1,77 @@
1
+ ///
2
+ /// JFunc_void_PermissionStatus.hpp
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ #pragma once
9
+
10
+ #include <fbjni/fbjni.h>
11
+ #include <functional>
12
+
13
+ #include "PermissionStatus.hpp"
14
+ #include <functional>
15
+ #include <NitroModules/JNICallable.hpp>
16
+ #include "JPermissionStatus.hpp"
17
+
18
+ namespace margelo::nitro::nitrolocationtracking {
19
+
20
+ using namespace facebook;
21
+
22
+ /**
23
+ * Represents the Java/Kotlin callback `(status: PermissionStatus) -> Unit`.
24
+ * This can be passed around between C++ and Java/Kotlin.
25
+ */
26
+ struct JFunc_void_PermissionStatus: public jni::JavaClass<JFunc_void_PermissionStatus> {
27
+ public:
28
+ static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/nitrolocationtracking/Func_void_PermissionStatus;";
29
+
30
+ public:
31
+ /**
32
+ * Invokes the function this `JFunc_void_PermissionStatus` instance holds through JNI.
33
+ */
34
+ void invoke(PermissionStatus status) const {
35
+ static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<JPermissionStatus> /* status */)>("invoke");
36
+ method(self(), JPermissionStatus::fromCpp(status));
37
+ }
38
+ };
39
+
40
+ /**
41
+ * An implementation of Func_void_PermissionStatus that is backed by a C++ implementation (using `std::function<...>`)
42
+ */
43
+ class JFunc_void_PermissionStatus_cxx final: public jni::HybridClass<JFunc_void_PermissionStatus_cxx, JFunc_void_PermissionStatus> {
44
+ public:
45
+ static jni::local_ref<JFunc_void_PermissionStatus::javaobject> fromCpp(const std::function<void(PermissionStatus /* status */)>& func) {
46
+ return JFunc_void_PermissionStatus_cxx::newObjectCxxArgs(func);
47
+ }
48
+
49
+ public:
50
+ /**
51
+ * Invokes the C++ `std::function<...>` this `JFunc_void_PermissionStatus_cxx` instance holds.
52
+ */
53
+ void invoke_cxx(jni::alias_ref<JPermissionStatus> status) {
54
+ _func(status->toCpp());
55
+ }
56
+
57
+ public:
58
+ [[nodiscard]]
59
+ inline const std::function<void(PermissionStatus /* status */)>& getFunction() const {
60
+ return _func;
61
+ }
62
+
63
+ public:
64
+ static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/nitrolocationtracking/Func_void_PermissionStatus_cxx;";
65
+ static void registerNatives() {
66
+ registerHybrid({makeNativeMethod("invoke_cxx", JFunc_void_PermissionStatus_cxx::invoke_cxx)});
67
+ }
68
+
69
+ private:
70
+ explicit JFunc_void_PermissionStatus_cxx(const std::function<void(PermissionStatus /* status */)>& func): _func(func) { }
71
+
72
+ private:
73
+ friend HybridBase;
74
+ std::function<void(PermissionStatus /* status */)> _func;
75
+ };
76
+
77
+ } // namespace margelo::nitro::nitrolocationtracking
@@ -69,6 +69,7 @@ namespace margelo::nitro::nitrolocationtracking { enum class LocationProviderSta
69
69
  #include "LocationProviderStatus.hpp"
70
70
  #include "JFunc_void_LocationProviderStatus_LocationProviderStatus.hpp"
71
71
  #include "JLocationProviderStatus.hpp"
72
+ #include "JFunc_void_PermissionStatus.hpp"
72
73
 
73
74
  namespace margelo::nitro::nitrolocationtracking {
74
75
 
@@ -281,6 +282,20 @@ namespace margelo::nitro::nitrolocationtracking {
281
282
  return __promise;
282
283
  }();
283
284
  }
285
+ void JHybridNitroLocationTrackingSpec::onPermissionStatusChange(const std::function<void(PermissionStatus /* status */)>& callback) {
286
+ static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<JFunc_void_PermissionStatus::javaobject> /* callback */)>("onPermissionStatusChange_cxx");
287
+ method(_javaPart, JFunc_void_PermissionStatus_cxx::fromCpp(callback));
288
+ }
289
+ double JHybridNitroLocationTrackingSpec::getDistanceBetween(double lat1, double lon1, double lat2, double lon2) {
290
+ static const auto method = javaClassStatic()->getMethod<double(double /* lat1 */, double /* lon1 */, double /* lat2 */, double /* lon2 */)>("getDistanceBetween");
291
+ auto __result = method(_javaPart, lat1, lon1, lat2, lon2);
292
+ return __result;
293
+ }
294
+ double JHybridNitroLocationTrackingSpec::getDistanceToGeofence(const std::string& regionId) {
295
+ static const auto method = javaClassStatic()->getMethod<double(jni::alias_ref<jni::JString> /* regionId */)>("getDistanceToGeofence");
296
+ auto __result = method(_javaPart, jni::make_jstring(regionId));
297
+ return __result;
298
+ }
284
299
  void JHybridNitroLocationTrackingSpec::showLocalNotification(const std::string& title, const std::string& body) {
285
300
  static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* title */, jni::alias_ref<jni::JString> /* body */)>("showLocalNotification");
286
301
  method(_javaPart, jni::make_jstring(title), jni::make_jstring(body));
@@ -87,6 +87,9 @@ namespace margelo::nitro::nitrolocationtracking {
87
87
  void onProviderStatusChange(const std::function<void(LocationProviderStatus /* gps */, LocationProviderStatus /* network */)>& callback) override;
88
88
  PermissionStatus getLocationPermissionStatus() override;
89
89
  std::shared_ptr<Promise<PermissionStatus>> requestLocationPermission() override;
90
+ void onPermissionStatusChange(const std::function<void(PermissionStatus /* status */)>& callback) override;
91
+ double getDistanceBetween(double lat1, double lon1, double lat2, double lon2) override;
92
+ double getDistanceToGeofence(const std::string& regionId) override;
90
93
  void showLocalNotification(const std::string& title, const std::string& body) override;
91
94
  void updateForegroundNotification(const std::string& title, const std::string& body) override;
92
95
  void destroy() override;
@@ -0,0 +1,80 @@
1
+ ///
2
+ /// Func_void_PermissionStatus.kt
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ package com.margelo.nitro.nitrolocationtracking
9
+
10
+ import androidx.annotation.Keep
11
+ import com.facebook.jni.HybridData
12
+ import com.facebook.proguard.annotations.DoNotStrip
13
+ import dalvik.annotation.optimization.FastNative
14
+
15
+
16
+ /**
17
+ * Represents the JavaScript callback `(status: enum) => void`.
18
+ * This can be either implemented in C++ (in which case it might be a callback coming from JS),
19
+ * or in Kotlin/Java (in which case it is a native callback).
20
+ */
21
+ @DoNotStrip
22
+ @Keep
23
+ @Suppress("ClassName", "RedundantUnitReturnType")
24
+ fun interface Func_void_PermissionStatus: (PermissionStatus) -> Unit {
25
+ /**
26
+ * Call the given JS callback.
27
+ * @throws Throwable if the JS function itself throws an error, or if the JS function/runtime has already been deleted.
28
+ */
29
+ @DoNotStrip
30
+ @Keep
31
+ override fun invoke(status: PermissionStatus): Unit
32
+ }
33
+
34
+ /**
35
+ * Represents the JavaScript callback `(status: enum) => void`.
36
+ * This is implemented in C++, via a `std::function<...>`.
37
+ * The callback might be coming from JS.
38
+ */
39
+ @DoNotStrip
40
+ @Keep
41
+ @Suppress(
42
+ "KotlinJniMissingFunction", "unused",
43
+ "RedundantSuppression", "RedundantUnitReturnType", "FunctionName",
44
+ "ConvertSecondaryConstructorToPrimary", "ClassName", "LocalVariableName",
45
+ )
46
+ class Func_void_PermissionStatus_cxx: Func_void_PermissionStatus {
47
+ @DoNotStrip
48
+ @Keep
49
+ private val mHybridData: HybridData
50
+
51
+ @DoNotStrip
52
+ @Keep
53
+ private constructor(hybridData: HybridData) {
54
+ mHybridData = hybridData
55
+ }
56
+
57
+ @DoNotStrip
58
+ @Keep
59
+ override fun invoke(status: PermissionStatus): Unit
60
+ = invoke_cxx(status)
61
+
62
+ @FastNative
63
+ private external fun invoke_cxx(status: PermissionStatus): Unit
64
+ }
65
+
66
+ /**
67
+ * Represents the JavaScript callback `(status: enum) => void`.
68
+ * This is implemented in Java/Kotlin, via a `(PermissionStatus) -> Unit`.
69
+ * The callback is always coming from native.
70
+ */
71
+ @DoNotStrip
72
+ @Keep
73
+ @Suppress("ClassName", "RedundantUnitReturnType", "unused")
74
+ class Func_void_PermissionStatus_java(private val function: (PermissionStatus) -> Unit): Func_void_PermissionStatus {
75
+ @DoNotStrip
76
+ @Keep
77
+ override fun invoke(status: PermissionStatus): Unit {
78
+ return this.function(status)
79
+ }
80
+ }
@@ -209,6 +209,23 @@ abstract class HybridNitroLocationTrackingSpec: HybridObject() {
209
209
  @Keep
210
210
  abstract fun requestLocationPermission(): Promise<PermissionStatus>
211
211
 
212
+ abstract fun onPermissionStatusChange(callback: (status: PermissionStatus) -> Unit): Unit
213
+
214
+ @DoNotStrip
215
+ @Keep
216
+ private fun onPermissionStatusChange_cxx(callback: Func_void_PermissionStatus): Unit {
217
+ val __result = onPermissionStatusChange(callback)
218
+ return __result
219
+ }
220
+
221
+ @DoNotStrip
222
+ @Keep
223
+ abstract fun getDistanceBetween(lat1: Double, lon1: Double, lat2: Double, lon2: Double): Double
224
+
225
+ @DoNotStrip
226
+ @Keep
227
+ abstract fun getDistanceToGeofence(regionId: String): Double
228
+
212
229
  @DoNotStrip
213
230
  @Keep
214
231
  abstract fun showLocalNotification(title: String, body: String): Unit
@@ -23,6 +23,7 @@
23
23
  #include "JFunc_void_GeofenceEvent_std__string.hpp"
24
24
  #include "JFunc_void_SpeedAlertType_double.hpp"
25
25
  #include "JFunc_void_LocationProviderStatus_LocationProviderStatus.hpp"
26
+ #include "JFunc_void_PermissionStatus.hpp"
26
27
  #include <NitroModules/DefaultConstructableObject.hpp>
27
28
 
28
29
  namespace margelo::nitro::nitrolocationtracking {
@@ -42,6 +43,7 @@ int initialize(JavaVM* vm) {
42
43
  margelo::nitro::nitrolocationtracking::JFunc_void_GeofenceEvent_std__string_cxx::registerNatives();
43
44
  margelo::nitro::nitrolocationtracking::JFunc_void_SpeedAlertType_double_cxx::registerNatives();
44
45
  margelo::nitro::nitrolocationtracking::JFunc_void_LocationProviderStatus_LocationProviderStatus_cxx::registerNatives();
46
+ margelo::nitro::nitrolocationtracking::JFunc_void_PermissionStatus_cxx::registerNatives();
45
47
 
46
48
  // Register Nitro Hybrid Objects
47
49
  HybridObjectRegistry::registerHybridObjectConstructor(
@@ -318,6 +318,28 @@ namespace margelo::nitro::nitrolocationtracking {
318
318
  auto __value = std::move(__result.value());
319
319
  return __value;
320
320
  }
321
+ inline void onPermissionStatusChange(const std::function<void(PermissionStatus /* status */)>& callback) override {
322
+ auto __result = _swiftPart.onPermissionStatusChange(callback);
323
+ if (__result.hasError()) [[unlikely]] {
324
+ std::rethrow_exception(__result.error());
325
+ }
326
+ }
327
+ inline double getDistanceBetween(double lat1, double lon1, double lat2, double lon2) override {
328
+ auto __result = _swiftPart.getDistanceBetween(std::forward<decltype(lat1)>(lat1), std::forward<decltype(lon1)>(lon1), std::forward<decltype(lat2)>(lat2), std::forward<decltype(lon2)>(lon2));
329
+ if (__result.hasError()) [[unlikely]] {
330
+ std::rethrow_exception(__result.error());
331
+ }
332
+ auto __value = std::move(__result.value());
333
+ return __value;
334
+ }
335
+ inline double getDistanceToGeofence(const std::string& regionId) override {
336
+ auto __result = _swiftPart.getDistanceToGeofence(regionId);
337
+ if (__result.hasError()) [[unlikely]] {
338
+ std::rethrow_exception(__result.error());
339
+ }
340
+ auto __value = std::move(__result.value());
341
+ return __value;
342
+ }
321
343
  inline void showLocalNotification(const std::string& title, const std::string& body) override {
322
344
  auto __result = _swiftPart.showLocalNotification(title, body);
323
345
  if (__result.hasError()) [[unlikely]] {
@@ -45,6 +45,9 @@ public protocol HybridNitroLocationTrackingSpec_protocol: HybridObject {
45
45
  func onProviderStatusChange(callback: @escaping (_ gps: LocationProviderStatus, _ network: LocationProviderStatus) -> Void) throws -> Void
46
46
  func getLocationPermissionStatus() throws -> PermissionStatus
47
47
  func requestLocationPermission() throws -> Promise<PermissionStatus>
48
+ func onPermissionStatusChange(callback: @escaping (_ status: PermissionStatus) -> Void) throws -> Void
49
+ func getDistanceBetween(lat1: Double, lon1: Double, lat2: Double, lon2: Double) throws -> Double
50
+ func getDistanceToGeofence(regionId: String) throws -> Double
48
51
  func showLocalNotification(title: String, body: String) throws -> Void
49
52
  func updateForegroundNotification(title: String, body: String) throws -> Void
50
53
  func destroy() throws -> Void
@@ -543,6 +543,46 @@ open class HybridNitroLocationTrackingSpec_cxx {
543
543
  }
544
544
  }
545
545
 
546
+ @inline(__always)
547
+ public final func onPermissionStatusChange(callback: bridge.Func_void_PermissionStatus) -> bridge.Result_void_ {
548
+ do {
549
+ try self.__implementation.onPermissionStatusChange(callback: { () -> (PermissionStatus) -> Void in
550
+ let __wrappedFunction = bridge.wrap_Func_void_PermissionStatus(callback)
551
+ return { (__status: PermissionStatus) -> Void in
552
+ __wrappedFunction.call(__status.rawValue)
553
+ }
554
+ }())
555
+ return bridge.create_Result_void_()
556
+ } catch (let __error) {
557
+ let __exceptionPtr = __error.toCpp()
558
+ return bridge.create_Result_void_(__exceptionPtr)
559
+ }
560
+ }
561
+
562
+ @inline(__always)
563
+ public final func getDistanceBetween(lat1: Double, lon1: Double, lat2: Double, lon2: Double) -> bridge.Result_double_ {
564
+ do {
565
+ let __result = try self.__implementation.getDistanceBetween(lat1: lat1, lon1: lon1, lat2: lat2, lon2: lon2)
566
+ let __resultCpp = __result
567
+ return bridge.create_Result_double_(__resultCpp)
568
+ } catch (let __error) {
569
+ let __exceptionPtr = __error.toCpp()
570
+ return bridge.create_Result_double_(__exceptionPtr)
571
+ }
572
+ }
573
+
574
+ @inline(__always)
575
+ public final func getDistanceToGeofence(regionId: std.string) -> bridge.Result_double_ {
576
+ do {
577
+ let __result = try self.__implementation.getDistanceToGeofence(regionId: String(regionId))
578
+ let __resultCpp = __result
579
+ return bridge.create_Result_double_(__resultCpp)
580
+ } catch (let __error) {
581
+ let __exceptionPtr = __error.toCpp()
582
+ return bridge.create_Result_double_(__exceptionPtr)
583
+ }
584
+ }
585
+
546
586
  @inline(__always)
547
587
  public final func showLocalNotification(title: std.string, body: std.string) -> bridge.Result_void_ {
548
588
  do {
@@ -46,6 +46,9 @@ namespace margelo::nitro::nitrolocationtracking {
46
46
  prototype.registerHybridMethod("onProviderStatusChange", &HybridNitroLocationTrackingSpec::onProviderStatusChange);
47
47
  prototype.registerHybridMethod("getLocationPermissionStatus", &HybridNitroLocationTrackingSpec::getLocationPermissionStatus);
48
48
  prototype.registerHybridMethod("requestLocationPermission", &HybridNitroLocationTrackingSpec::requestLocationPermission);
49
+ prototype.registerHybridMethod("onPermissionStatusChange", &HybridNitroLocationTrackingSpec::onPermissionStatusChange);
50
+ prototype.registerHybridMethod("getDistanceBetween", &HybridNitroLocationTrackingSpec::getDistanceBetween);
51
+ prototype.registerHybridMethod("getDistanceToGeofence", &HybridNitroLocationTrackingSpec::getDistanceToGeofence);
49
52
  prototype.registerHybridMethod("showLocalNotification", &HybridNitroLocationTrackingSpec::showLocalNotification);
50
53
  prototype.registerHybridMethod("updateForegroundNotification", &HybridNitroLocationTrackingSpec::updateForegroundNotification);
51
54
  prototype.registerHybridMethod("destroy", &HybridNitroLocationTrackingSpec::destroy);
@@ -114,6 +114,9 @@ namespace margelo::nitro::nitrolocationtracking {
114
114
  virtual void onProviderStatusChange(const std::function<void(LocationProviderStatus /* gps */, LocationProviderStatus /* network */)>& callback) = 0;
115
115
  virtual PermissionStatus getLocationPermissionStatus() = 0;
116
116
  virtual std::shared_ptr<Promise<PermissionStatus>> requestLocationPermission() = 0;
117
+ virtual void onPermissionStatusChange(const std::function<void(PermissionStatus /* status */)>& callback) = 0;
118
+ virtual double getDistanceBetween(double lat1, double lon1, double lat2, double lon2) = 0;
119
+ virtual double getDistanceToGeofence(const std::string& regionId) = 0;
117
120
  virtual void showLocalNotification(const std::string& title, const std::string& body) = 0;
118
121
  virtual void updateForegroundNotification(const std::string& title, const std::string& body) = 0;
119
122
  virtual void destroy() = 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-nitro-location-tracking",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "A React Native Nitro module for location tracking",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -89,6 +89,8 @@ export type PermissionStatus =
89
89
  | 'whenInUse'
90
90
  | 'always';
91
91
 
92
+ export type PermissionStatusCallback = (status: PermissionStatus) => void;
93
+
92
94
  // ─── Hybrid Object ──────────────────────────────────
93
95
 
94
96
  export interface NitroLocationTracking
@@ -144,6 +146,16 @@ export interface NitroLocationTracking
144
146
  // === Permission Status ===
145
147
  getLocationPermissionStatus(): PermissionStatus;
146
148
  requestLocationPermission(): Promise<PermissionStatus>;
149
+ onPermissionStatusChange(callback: PermissionStatusCallback): void;
150
+
151
+ // === Distance Utilities ===
152
+ getDistanceBetween(
153
+ lat1: number,
154
+ lon1: number,
155
+ lat2: number,
156
+ lon2: number
157
+ ): number; // meters
158
+ getDistanceToGeofence(regionId: string): number; // meters from last known location to geofence center, -1 if not found
147
159
 
148
160
  // === Notifications ===
149
161
  showLocalNotification(title: string, body: string): void;
package/src/index.tsx CHANGED
@@ -32,6 +32,7 @@ export type {
32
32
  LocationProviderStatus,
33
33
  ProviderStatusCallback,
34
34
  PermissionStatus,
35
+ PermissionStatusCallback,
35
36
  } from './NitroLocationTracking.nitro';
36
37
 
37
38
  export function useDriverLocation(config: LocationConfig) {