react-native-nitro-location-tracking 0.1.7 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +179 -87
- package/android/src/main/java/com/margelo/nitro/nitrolocationtracking/GeofenceManager.kt +10 -0
- package/android/src/main/java/com/margelo/nitro/nitrolocationtracking/LocationEngine.kt +3 -0
- package/android/src/main/java/com/margelo/nitro/nitrolocationtracking/NitroLocationTracking.kt +83 -7
- package/ios/GeofenceManager.swift +6 -0
- package/ios/LocationEngine.swift +51 -8
- package/ios/NitroLocationTracking.swift +38 -2
- package/lib/typescript/src/NitroLocationTracking.nitro.d.ts +3 -0
- package/lib/typescript/src/NitroLocationTracking.nitro.d.ts.map +1 -1
- package/nitrogen/generated/android/c++/JHybridNitroLocationTrackingSpec.cpp +26 -0
- package/nitrogen/generated/android/c++/JHybridNitroLocationTrackingSpec.hpp +3 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrolocationtracking/HybridNitroLocationTrackingSpec.kt +12 -0
- package/nitrogen/generated/ios/NitroLocationTracking-Swift-Cxx-Bridge.cpp +8 -0
- package/nitrogen/generated/ios/NitroLocationTracking-Swift-Cxx-Bridge.hpp +43 -0
- package/nitrogen/generated/ios/c++/HybridNitroLocationTrackingSpecSwift.hpp +24 -0
- package/nitrogen/generated/ios/swift/Func_void_PermissionStatus.swift +46 -0
- package/nitrogen/generated/ios/swift/HybridNitroLocationTrackingSpec.swift +3 -0
- package/nitrogen/generated/ios/swift/HybridNitroLocationTrackingSpec_cxx.swift +43 -0
- package/nitrogen/generated/shared/c++/HybridNitroLocationTrackingSpec.cpp +3 -0
- package/nitrogen/generated/shared/c++/HybridNitroLocationTrackingSpec.hpp +3 -0
- package/package.json +1 -1
- package/src/NitroLocationTracking.nitro.ts +10 -0
package/README.md
CHANGED
|
@@ -91,7 +91,8 @@ const granted = await requestLocationPermission(
|
|
|
91
91
|
},
|
|
92
92
|
{
|
|
93
93
|
title: 'Background Location',
|
|
94
|
-
message:
|
|
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',
|
|
113
|
-
distanceFilter: 10,
|
|
114
|
-
intervalMs: 3000,
|
|
115
|
-
fastestIntervalMs: 1000,
|
|
116
|
-
stopTimeout: 5,
|
|
117
|
-
stopOnTerminate: false,
|
|
118
|
-
startOnBoot: true,
|
|
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,
|
|
159
|
-
syncIntervalMs: 10000,
|
|
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
|
|
242
|
-
|
|
243
|
-
| Android
|
|
244
|
-
| iOS
|
|
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 {
|
|
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,
|
|
346
|
-
minSpeedKmh: 5,
|
|
347
|
-
checkIntervalMs: 0,
|
|
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,55 @@ switch (status) {
|
|
|
434
481
|
}
|
|
435
482
|
```
|
|
436
483
|
|
|
437
|
-
| Status
|
|
438
|
-
|
|
439
|
-
| `notDetermined` | Not yet asked
|
|
440
|
-
| `denied`
|
|
441
|
-
| `restricted`
|
|
442
|
-
| `whenInUse`
|
|
443
|
-
| `always`
|
|
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. |
|
|
444
533
|
|
|
445
534
|
## API Reference
|
|
446
535
|
|
|
@@ -453,11 +542,11 @@ interface LocationData {
|
|
|
453
542
|
latitude: number;
|
|
454
543
|
longitude: number;
|
|
455
544
|
altitude: number;
|
|
456
|
-
speed: number;
|
|
457
|
-
bearing: number;
|
|
458
|
-
accuracy: number;
|
|
459
|
-
timestamp: number;
|
|
460
|
-
isMockLocation?: boolean;
|
|
545
|
+
speed: number; // m/s
|
|
546
|
+
bearing: number; // degrees
|
|
547
|
+
accuracy: number; // meters
|
|
548
|
+
timestamp: number; // unix ms
|
|
549
|
+
isMockLocation?: boolean; // true when from a mock provider
|
|
461
550
|
}
|
|
462
551
|
```
|
|
463
552
|
|
|
@@ -466,12 +555,12 @@ interface LocationData {
|
|
|
466
555
|
```ts
|
|
467
556
|
interface LocationConfig {
|
|
468
557
|
desiredAccuracy: 'high' | 'balanced' | 'low';
|
|
469
|
-
distanceFilter: number;
|
|
470
|
-
intervalMs: number;
|
|
471
|
-
fastestIntervalMs: number;
|
|
472
|
-
stopTimeout: number;
|
|
473
|
-
stopOnTerminate: boolean;
|
|
474
|
-
startOnBoot: boolean;
|
|
558
|
+
distanceFilter: number; // meters
|
|
559
|
+
intervalMs: number; // Android only
|
|
560
|
+
fastestIntervalMs: number; // Android only
|
|
561
|
+
stopTimeout: number; // minutes before declaring stopped
|
|
562
|
+
stopOnTerminate: boolean; // keep tracking after app close (Android)
|
|
563
|
+
startOnBoot: boolean; // restart tracking after reboot (Android)
|
|
475
564
|
foregroundNotificationTitle: string;
|
|
476
565
|
foregroundNotificationText: string;
|
|
477
566
|
}
|
|
@@ -486,7 +575,7 @@ interface ConnectionConfig {
|
|
|
486
575
|
authToken: string;
|
|
487
576
|
reconnectIntervalMs: number;
|
|
488
577
|
maxReconnectAttempts: number;
|
|
489
|
-
batchSize: number;
|
|
578
|
+
batchSize: number; // locations per batch upload
|
|
490
579
|
syncIntervalMs: number; // how often to flush queue
|
|
491
580
|
}
|
|
492
581
|
```
|
|
@@ -498,7 +587,7 @@ interface GeofenceRegion {
|
|
|
498
587
|
id: string;
|
|
499
588
|
latitude: number;
|
|
500
589
|
longitude: number;
|
|
501
|
-
radius: number;
|
|
590
|
+
radius: number; // meters
|
|
502
591
|
notifyOnEntry: boolean;
|
|
503
592
|
notifyOnExit: boolean;
|
|
504
593
|
}
|
|
@@ -508,9 +597,9 @@ interface GeofenceRegion {
|
|
|
508
597
|
|
|
509
598
|
```ts
|
|
510
599
|
interface SpeedConfig {
|
|
511
|
-
maxSpeedKmh: number;
|
|
512
|
-
minSpeedKmh: number;
|
|
513
|
-
checkIntervalMs: number;
|
|
600
|
+
maxSpeedKmh: number; // speed limit in km/h
|
|
601
|
+
minSpeedKmh: number; // minimum speed threshold
|
|
602
|
+
checkIntervalMs: number; // how often to evaluate
|
|
514
603
|
}
|
|
515
604
|
```
|
|
516
605
|
|
|
@@ -539,58 +628,61 @@ type PermissionStatus =
|
|
|
539
628
|
|
|
540
629
|
### Hooks
|
|
541
630
|
|
|
542
|
-
| Hook
|
|
543
|
-
|
|
544
|
-
| `useDriverLocation(config)` | `{ location, isMoving, isTracking, startTracking, stopTracking }` | Manages location tracking lifecycle
|
|
545
|
-
| `useRideConnection(config)` | `{ connectionState, lastMessage, connect, disconnect, send }`
|
|
631
|
+
| Hook | Returns | Description |
|
|
632
|
+
| --------------------------- | ----------------------------------------------------------------- | -------------------------------------- |
|
|
633
|
+
| `useDriverLocation(config)` | `{ location, isMoving, isTracking, startTracking, stopTracking }` | Manages location tracking lifecycle |
|
|
634
|
+
| `useRideConnection(config)` | `{ connectionState, lastMessage, connect, disconnect, send }` | Manages WebSocket connection lifecycle |
|
|
546
635
|
|
|
547
636
|
### Native Module Methods
|
|
548
637
|
|
|
549
|
-
| Method
|
|
550
|
-
|
|
551
|
-
| `configure(config)`
|
|
552
|
-
| `startTracking()`
|
|
553
|
-
| `stopTracking()`
|
|
554
|
-
| `getCurrentLocation()`
|
|
555
|
-
| `isTracking()`
|
|
556
|
-
| `onLocation(callback)`
|
|
557
|
-
| `onMotionChange(callback)`
|
|
558
|
-
| `configureConnection(config)`
|
|
559
|
-
| `connectWebSocket()`
|
|
560
|
-
| `disconnectWebSocket()`
|
|
561
|
-
| `sendMessage(message)`
|
|
562
|
-
| `getConnectionState()`
|
|
563
|
-
| `onConnectionStateChange(callback)`
|
|
564
|
-
| `onMessage(callback)`
|
|
565
|
-
| `forceSync()`
|
|
566
|
-
| `isFakeGpsEnabled()`
|
|
567
|
-
| `setRejectMockLocations(reject)`
|
|
568
|
-
| `addGeofence(region)`
|
|
569
|
-
| `removeGeofence(regionId)`
|
|
570
|
-
| `removeAllGeofences()`
|
|
571
|
-
| `onGeofenceEvent(callback)`
|
|
572
|
-
| `
|
|
573
|
-
| `
|
|
574
|
-
| `
|
|
575
|
-
| `
|
|
576
|
-
| `
|
|
577
|
-
| `
|
|
578
|
-
| `
|
|
579
|
-
| `
|
|
580
|
-
| `
|
|
581
|
-
| `
|
|
582
|
-
| `
|
|
583
|
-
| `
|
|
584
|
-
| `
|
|
638
|
+
| Method | Returns | Description |
|
|
639
|
+
| -------------------------------------------- | --------------------------- | ---------------------------------------------------------------------------------------- |
|
|
640
|
+
| `configure(config)` | `void` | Set location tracking configuration |
|
|
641
|
+
| `startTracking()` | `void` | Start location tracking |
|
|
642
|
+
| `stopTracking()` | `void` | Stop location tracking |
|
|
643
|
+
| `getCurrentLocation()` | `Promise<LocationData>` | Get a one-shot location |
|
|
644
|
+
| `isTracking()` | `boolean` | Check if tracking is active |
|
|
645
|
+
| `onLocation(callback)` | `void` | Register location update callback |
|
|
646
|
+
| `onMotionChange(callback)` | `void` | Register motion state callback |
|
|
647
|
+
| `configureConnection(config)` | `void` | Set WebSocket/REST configuration |
|
|
648
|
+
| `connectWebSocket()` | `void` | Open WebSocket connection |
|
|
649
|
+
| `disconnectWebSocket()` | `void` | Close WebSocket connection |
|
|
650
|
+
| `sendMessage(message)` | `void` | Send a message via WebSocket |
|
|
651
|
+
| `getConnectionState()` | `ConnectionState` | Get current connection state |
|
|
652
|
+
| `onConnectionStateChange(callback)` | `void` | Register connection state callback |
|
|
653
|
+
| `onMessage(callback)` | `void` | Register incoming message callback |
|
|
654
|
+
| `forceSync()` | `Promise<boolean>` | Flush queued locations to server |
|
|
655
|
+
| `isFakeGpsEnabled()` | `boolean` | Check if device-level mock location is enabled |
|
|
656
|
+
| `setRejectMockLocations(reject)` | `void` | Auto-reject mock locations when `true` |
|
|
657
|
+
| `addGeofence(region)` | `void` | Start monitoring a circular geofence region |
|
|
658
|
+
| `removeGeofence(regionId)` | `void` | Stop monitoring a specific geofence |
|
|
659
|
+
| `removeAllGeofences()` | `void` | Remove all active geofences |
|
|
660
|
+
| `onGeofenceEvent(callback)` | `void` | Register geofence enter/exit callback |
|
|
661
|
+
| `getDistanceBetween(lat1, lon1, lat2, lon2)` | `number` | Calculate distance between two points in meters (native Haversine) |
|
|
662
|
+
| `getDistanceToGeofence(regionId)` | `number` | Get distance in meters from last known location to a geofence center (`-1` if not found) |
|
|
663
|
+
| `configureSpeedMonitor(config)` | `void` | Set speed monitoring thresholds |
|
|
664
|
+
| `onSpeedAlert(callback)` | `void` | Register speed state-transition callback |
|
|
665
|
+
| `getCurrentSpeed()` | `number` | Get current speed in km/h |
|
|
666
|
+
| `startTripCalculation()` | `void` | Start recording trip distance/stats |
|
|
667
|
+
| `stopTripCalculation()` | `TripStats` | Stop recording and get final stats |
|
|
668
|
+
| `getTripStats()` | `TripStats` | Get current trip stats without stopping |
|
|
669
|
+
| `resetTripCalculation()` | `void` | Reset trip calculator |
|
|
670
|
+
| `isLocationServicesEnabled()` | `boolean` | Check if GPS/location is enabled on device |
|
|
671
|
+
| `onProviderStatusChange(callback)` | `void` | Register GPS/network provider status callback |
|
|
672
|
+
| `getLocationPermissionStatus()` | `PermissionStatus` | Check current location permission without prompting |
|
|
673
|
+
| `requestLocationPermission()` | `Promise<PermissionStatus>` | Request location permission and return the resulting status |
|
|
674
|
+
| `showLocalNotification(title, body)` | `void` | Show a local notification |
|
|
675
|
+
| `updateForegroundNotification(title, body)` | `void` | Update the foreground service notification |
|
|
676
|
+
| `destroy()` | `void` | Stop tracking and disconnect |
|
|
585
677
|
|
|
586
678
|
### Utility Exports
|
|
587
679
|
|
|
588
|
-
| Export
|
|
589
|
-
|
|
590
|
-
| `LocationSmoother`
|
|
591
|
-
| `calculateBearing(from, to)`
|
|
592
|
-
| `shortestRotation(from, to)`
|
|
593
|
-
| `requestLocationPermission()` | Request location + notification permissions (Android)
|
|
680
|
+
| Export | Description |
|
|
681
|
+
| ----------------------------- | ---------------------------------------------------------- |
|
|
682
|
+
| `LocationSmoother` | Class for smooth map marker animation between updates |
|
|
683
|
+
| `calculateBearing(from, to)` | Calculate bearing between two coordinates (degrees, 0-360) |
|
|
684
|
+
| `shortestRotation(from, to)` | Calculate shortest rotation path to avoid spinning |
|
|
685
|
+
| `requestLocationPermission()` | Request location + notification permissions (Android) |
|
|
594
686
|
|
|
595
687
|
## Publishing to npm
|
|
596
688
|
|
|
@@ -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
|
package/android/src/main/java/com/margelo/nitro/nitrolocationtracking/NitroLocationTracking.kt
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
package com.margelo.nitro.nitrolocationtracking
|
|
2
2
|
|
|
3
|
+
import android.content.pm.PackageManager
|
|
3
4
|
import android.util.Log
|
|
5
|
+
import androidx.core.app.ActivityCompat
|
|
6
|
+
import androidx.core.content.ContextCompat
|
|
4
7
|
import com.facebook.proguard.annotations.DoNotStrip
|
|
8
|
+
import com.facebook.react.bridge.ReactContext
|
|
5
9
|
import com.margelo.nitro.NitroModules
|
|
6
10
|
import com.margelo.nitro.core.Promise
|
|
7
11
|
import kotlin.coroutines.resume
|
|
@@ -13,6 +17,7 @@ class NitroLocationTracking : HybridNitroLocationTrackingSpec() {
|
|
|
13
17
|
|
|
14
18
|
companion object {
|
|
15
19
|
private const val TAG = "NitroLocationTracking"
|
|
20
|
+
private const val PERMISSION_REQUEST_CODE = 9001
|
|
16
21
|
}
|
|
17
22
|
|
|
18
23
|
private var locationEngine: LocationEngine? = null
|
|
@@ -32,6 +37,7 @@ class NitroLocationTracking : HybridNitroLocationTrackingSpec() {
|
|
|
32
37
|
|
|
33
38
|
private var locationConfig: LocationConfig? = null
|
|
34
39
|
|
|
40
|
+
|
|
35
41
|
private fun ensureInitialized(): Boolean {
|
|
36
42
|
if (locationEngine != null) return true
|
|
37
43
|
val context = NitroModules.applicationContext
|
|
@@ -260,22 +266,19 @@ class NitroLocationTracking : HybridNitroLocationTrackingSpec() {
|
|
|
260
266
|
override fun getLocationPermissionStatus(): PermissionStatus {
|
|
261
267
|
val context = NitroModules.applicationContext ?: return PermissionStatus.NOTDETERMINED
|
|
262
268
|
|
|
263
|
-
val fineGranted =
|
|
269
|
+
val fineGranted = ContextCompat.checkSelfPermission(
|
|
264
270
|
context, android.Manifest.permission.ACCESS_FINE_LOCATION
|
|
265
|
-
) ==
|
|
271
|
+
) == PackageManager.PERMISSION_GRANTED
|
|
266
272
|
|
|
267
273
|
if (!fineGranted) {
|
|
268
|
-
// Check if we've ever asked — if the app just installed, it's "notDetermined"
|
|
269
|
-
// Android doesn't have a direct "notDetermined" state, so we treat
|
|
270
|
-
// not-granted as DENIED (the JS side can use requestPermission to prompt)
|
|
271
274
|
return PermissionStatus.DENIED
|
|
272
275
|
}
|
|
273
276
|
|
|
274
277
|
// Fine location granted — check background
|
|
275
278
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
|
|
276
|
-
val bgGranted =
|
|
279
|
+
val bgGranted = ContextCompat.checkSelfPermission(
|
|
277
280
|
context, android.Manifest.permission.ACCESS_BACKGROUND_LOCATION
|
|
278
|
-
) ==
|
|
281
|
+
) == PackageManager.PERMISSION_GRANTED
|
|
279
282
|
return if (bgGranted) PermissionStatus.ALWAYS else PermissionStatus.WHENINUSE
|
|
280
283
|
}
|
|
281
284
|
|
|
@@ -283,6 +286,79 @@ class NitroLocationTracking : HybridNitroLocationTrackingSpec() {
|
|
|
283
286
|
return PermissionStatus.ALWAYS
|
|
284
287
|
}
|
|
285
288
|
|
|
289
|
+
override fun requestLocationPermission(): Promise<PermissionStatus> {
|
|
290
|
+
return Promise.async {
|
|
291
|
+
suspendCoroutine { cont ->
|
|
292
|
+
val context = NitroModules.applicationContext
|
|
293
|
+
if (context == null) {
|
|
294
|
+
cont.resume(PermissionStatus.DENIED)
|
|
295
|
+
return@suspendCoroutine
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// Already granted — return current status immediately
|
|
299
|
+
val fineGranted = ContextCompat.checkSelfPermission(
|
|
300
|
+
context, android.Manifest.permission.ACCESS_FINE_LOCATION
|
|
301
|
+
) == PackageManager.PERMISSION_GRANTED
|
|
302
|
+
|
|
303
|
+
if (fineGranted) {
|
|
304
|
+
cont.resume(getLocationPermissionStatus())
|
|
305
|
+
return@suspendCoroutine
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// Need to request — get the current Activity
|
|
309
|
+
val activity = (context as? ReactContext)?.currentActivity
|
|
310
|
+
if (activity == null) {
|
|
311
|
+
Log.e(TAG, "requestLocationPermission — no current Activity available")
|
|
312
|
+
cont.resume(PermissionStatus.DENIED)
|
|
313
|
+
return@suspendCoroutine
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Use PermissionAwareActivity if available (React Native's Activity)
|
|
317
|
+
if (activity is com.facebook.react.modules.core.PermissionAwareActivity) {
|
|
318
|
+
activity.requestPermissions(
|
|
319
|
+
arrayOf(
|
|
320
|
+
android.Manifest.permission.ACCESS_FINE_LOCATION,
|
|
321
|
+
android.Manifest.permission.ACCESS_COARSE_LOCATION
|
|
322
|
+
),
|
|
323
|
+
PERMISSION_REQUEST_CODE
|
|
324
|
+
) { requestCode, _, _ ->
|
|
325
|
+
if (requestCode == PERMISSION_REQUEST_CODE) {
|
|
326
|
+
cont.resume(getLocationPermissionStatus())
|
|
327
|
+
}
|
|
328
|
+
true // PermissionListener requires Boolean return
|
|
329
|
+
}
|
|
330
|
+
} else {
|
|
331
|
+
// Fallback: use ActivityCompat (result won't be captured directly)
|
|
332
|
+
ActivityCompat.requestPermissions(
|
|
333
|
+
activity,
|
|
334
|
+
arrayOf(
|
|
335
|
+
android.Manifest.permission.ACCESS_FINE_LOCATION,
|
|
336
|
+
android.Manifest.permission.ACCESS_COARSE_LOCATION
|
|
337
|
+
),
|
|
338
|
+
PERMISSION_REQUEST_CODE
|
|
339
|
+
)
|
|
340
|
+
// Poll for result after user interacts with the dialog
|
|
341
|
+
android.os.Handler(android.os.Looper.getMainLooper()).postDelayed({
|
|
342
|
+
cont.resume(getLocationPermissionStatus())
|
|
343
|
+
}, 5000)
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// === Distance Utilities ===
|
|
350
|
+
|
|
351
|
+
override fun getDistanceBetween(lat1: Double, lon1: Double, lat2: Double, lon2: Double): Double {
|
|
352
|
+
val results = FloatArray(1)
|
|
353
|
+
android.location.Location.distanceBetween(lat1, lon1, lat2, lon2, results)
|
|
354
|
+
return results[0].toDouble()
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
override fun getDistanceToGeofence(regionId: String): Double {
|
|
358
|
+
ensureInitialized()
|
|
359
|
+
return geofenceManager?.distanceTo(regionId, locationEngine?.lastLocation) ?: -1.0
|
|
360
|
+
}
|
|
361
|
+
|
|
286
362
|
// === Notifications ===
|
|
287
363
|
|
|
288
364
|
override fun showLocalNotification(title: String, body: String) {
|
|
@@ -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
|
package/ios/LocationEngine.swift
CHANGED
|
@@ -11,6 +11,8 @@ class LocationEngine: NSObject, CLLocationManagerDelegate {
|
|
|
11
11
|
return mgr
|
|
12
12
|
}()
|
|
13
13
|
private var tracking = false
|
|
14
|
+
private var pendingPermissionCompletion: ((CLAuthorizationStatus) -> Void)?
|
|
15
|
+
private var pendingStartAfterPermission = false
|
|
14
16
|
|
|
15
17
|
var onLocation: ((LocationData) -> Void)?
|
|
16
18
|
var onMotionChange: ((Bool) -> Void)?
|
|
@@ -21,6 +23,11 @@ class LocationEngine: NSObject, CLLocationManagerDelegate {
|
|
|
21
23
|
let tripCalculator = TripCalculator()
|
|
22
24
|
var providerStatusCallback: ((LocationProviderStatus, LocationProviderStatus) -> Void)?
|
|
23
25
|
|
|
26
|
+
/// The most recently received location from Core Location (for distance calculations)
|
|
27
|
+
var lastCLLocation: CLLocation? {
|
|
28
|
+
return locationManager.location
|
|
29
|
+
}
|
|
30
|
+
|
|
24
31
|
override init() {
|
|
25
32
|
super.init()
|
|
26
33
|
locationManager.delegate = self
|
|
@@ -45,6 +52,7 @@ class LocationEngine: NSObject, CLLocationManagerDelegate {
|
|
|
45
52
|
func start() {
|
|
46
53
|
guard CLLocationManager.authorizationStatus() == .authorizedAlways ||
|
|
47
54
|
CLLocationManager.authorizationStatus() == .authorizedWhenInUse else {
|
|
55
|
+
pendingStartAfterPermission = true
|
|
48
56
|
locationManager.requestAlwaysAuthorization()
|
|
49
57
|
return
|
|
50
58
|
}
|
|
@@ -52,10 +60,21 @@ class LocationEngine: NSObject, CLLocationManagerDelegate {
|
|
|
52
60
|
tracking = true
|
|
53
61
|
}
|
|
54
62
|
|
|
63
|
+
func requestPermission(completion: @escaping (CLAuthorizationStatus) -> Void) {
|
|
64
|
+
let currentStatus = CLLocationManager.authorizationStatus()
|
|
65
|
+
if currentStatus != .notDetermined {
|
|
66
|
+
completion(currentStatus)
|
|
67
|
+
return
|
|
68
|
+
}
|
|
69
|
+
pendingPermissionCompletion = completion
|
|
70
|
+
locationManager.requestAlwaysAuthorization()
|
|
71
|
+
}
|
|
72
|
+
|
|
55
73
|
func stop() {
|
|
56
74
|
locationManager.stopUpdatingLocation()
|
|
57
75
|
tracking = false
|
|
58
76
|
}
|
|
77
|
+
|
|
59
78
|
|
|
60
79
|
var isTracking: Bool { tracking }
|
|
61
80
|
|
|
@@ -80,11 +99,11 @@ class LocationEngine: NSObject, CLLocationManagerDelegate {
|
|
|
80
99
|
}
|
|
81
100
|
// Use a SEPARATE manager for one-shot requests so we never
|
|
82
101
|
// stop the continuous startUpdatingLocation() on locationManager.
|
|
83
|
-
|
|
102
|
+
pendingLocationCompletions.append(completion)
|
|
84
103
|
oneShotManager.requestLocation()
|
|
85
104
|
}
|
|
86
105
|
|
|
87
|
-
private var
|
|
106
|
+
private var pendingLocationCompletions: [(LocationData?) -> Void] = []
|
|
88
107
|
|
|
89
108
|
func locationManager(_ manager: CLLocationManager,
|
|
90
109
|
didUpdateLocations locations: [CLLocation]) {
|
|
@@ -104,9 +123,12 @@ class LocationEngine: NSObject, CLLocationManagerDelegate {
|
|
|
104
123
|
)
|
|
105
124
|
|
|
106
125
|
// Handle pending one-shot request (from oneShotManager)
|
|
107
|
-
if manager === oneShotManager
|
|
108
|
-
|
|
109
|
-
|
|
126
|
+
if manager === oneShotManager {
|
|
127
|
+
let completions = pendingLocationCompletions
|
|
128
|
+
pendingLocationCompletions.removeAll()
|
|
129
|
+
for completion in completions {
|
|
130
|
+
completion(data)
|
|
131
|
+
}
|
|
110
132
|
return
|
|
111
133
|
}
|
|
112
134
|
|
|
@@ -131,9 +153,12 @@ class LocationEngine: NSObject, CLLocationManagerDelegate {
|
|
|
131
153
|
|
|
132
154
|
func locationManager(_ manager: CLLocationManager,
|
|
133
155
|
didFailWithError error: Error) {
|
|
134
|
-
if manager === oneShotManager
|
|
135
|
-
|
|
136
|
-
|
|
156
|
+
if manager === oneShotManager {
|
|
157
|
+
let completions = pendingLocationCompletions
|
|
158
|
+
pendingLocationCompletions.removeAll()
|
|
159
|
+
for completion in completions {
|
|
160
|
+
completion(nil)
|
|
161
|
+
}
|
|
137
162
|
}
|
|
138
163
|
}
|
|
139
164
|
|
|
@@ -169,6 +194,24 @@ class LocationEngine: NSObject, CLLocationManagerDelegate {
|
|
|
169
194
|
|
|
170
195
|
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
|
|
171
196
|
guard manager === locationManager else { return }
|
|
197
|
+
|
|
198
|
+
let authStatus = CLLocationManager.authorizationStatus()
|
|
199
|
+
|
|
200
|
+
// Resolve pending permission request
|
|
201
|
+
if let completion = pendingPermissionCompletion {
|
|
202
|
+
pendingPermissionCompletion = nil
|
|
203
|
+
completion(authStatus)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Auto-start tracking if permission was granted after start() was called
|
|
207
|
+
if pendingStartAfterPermission {
|
|
208
|
+
pendingStartAfterPermission = false
|
|
209
|
+
if authStatus == .authorizedAlways || authStatus == .authorizedWhenInUse {
|
|
210
|
+
locationManager.startUpdatingLocation()
|
|
211
|
+
tracking = true
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
172
215
|
let enabled = CLLocationManager.locationServicesEnabled()
|
|
173
216
|
let status: LocationProviderStatus = enabled ? .enabled : .disabled
|
|
174
217
|
providerStatusCallback?(status, status)
|
|
@@ -3,7 +3,6 @@ import CoreLocation
|
|
|
3
3
|
import NitroModules
|
|
4
4
|
|
|
5
5
|
class NitroLocationTracking: HybridNitroLocationTrackingSpec {
|
|
6
|
-
|
|
7
6
|
private let locationEngine = LocationEngine()
|
|
8
7
|
private let connectionManager = ConnectionManager()
|
|
9
8
|
private let dbWriter = NativeDBWriter()
|
|
@@ -17,6 +16,7 @@ class NitroLocationTracking: HybridNitroLocationTrackingSpec {
|
|
|
17
16
|
private var geofenceCallback: ((GeofenceEvent, String) -> Void)?
|
|
18
17
|
private var speedAlertCallback: ((SpeedAlertType, Double) -> Void)?
|
|
19
18
|
private var providerStatusCallback: ((LocationProviderStatus, LocationProviderStatus) -> Void)?
|
|
19
|
+
private var permissionPromise: Promise<PermissionStatus>?
|
|
20
20
|
|
|
21
21
|
override init() {
|
|
22
22
|
super.init()
|
|
@@ -44,6 +44,7 @@ class NitroLocationTracking: HybridNitroLocationTrackingSpec {
|
|
|
44
44
|
locationEngine.stop()
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
|
|
47
48
|
func getCurrentLocation() throws -> Promise<LocationData> {
|
|
48
49
|
let promise = Promise<LocationData>()
|
|
49
50
|
locationEngine.getCurrentLocation { data in
|
|
@@ -58,7 +59,7 @@ class NitroLocationTracking: HybridNitroLocationTrackingSpec {
|
|
|
58
59
|
return promise
|
|
59
60
|
}
|
|
60
61
|
|
|
61
|
-
|
|
62
|
+
func isTracking() throws -> Bool {
|
|
62
63
|
return locationEngine.isTracking
|
|
63
64
|
}
|
|
64
65
|
|
|
@@ -212,6 +213,41 @@ class NitroLocationTracking: HybridNitroLocationTrackingSpec {
|
|
|
212
213
|
}
|
|
213
214
|
}
|
|
214
215
|
|
|
216
|
+
func requestLocationPermission() throws -> Promise<PermissionStatus> {
|
|
217
|
+
let promise = Promise<PermissionStatus>()
|
|
218
|
+
locationEngine.requestPermission { authStatus in
|
|
219
|
+
let result: PermissionStatus
|
|
220
|
+
switch authStatus {
|
|
221
|
+
case .notDetermined:
|
|
222
|
+
result = .notdetermined
|
|
223
|
+
case .restricted:
|
|
224
|
+
result = .restricted
|
|
225
|
+
case .denied:
|
|
226
|
+
result = .denied
|
|
227
|
+
case .authorizedWhenInUse:
|
|
228
|
+
result = .wheninuse
|
|
229
|
+
case .authorizedAlways:
|
|
230
|
+
result = .always
|
|
231
|
+
@unknown default:
|
|
232
|
+
result = .notdetermined
|
|
233
|
+
}
|
|
234
|
+
promise.resolve(withResult: result)
|
|
235
|
+
}
|
|
236
|
+
return promise
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// MARK: - Distance Utilities
|
|
240
|
+
|
|
241
|
+
func getDistanceBetween(lat1: Double, lon1: Double, lat2: Double, lon2: Double) throws -> Double {
|
|
242
|
+
let loc1 = CLLocation(latitude: lat1, longitude: lon1)
|
|
243
|
+
let loc2 = CLLocation(latitude: lat2, longitude: lon2)
|
|
244
|
+
return loc1.distance(from: loc2)
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
func getDistanceToGeofence(regionId: String) throws -> Double {
|
|
248
|
+
return geofenceManager.distanceTo(regionId: regionId, from: locationEngine.lastCLLocation)
|
|
249
|
+
}
|
|
250
|
+
|
|
215
251
|
// MARK: - Notifications
|
|
216
252
|
|
|
217
253
|
func showLocalNotification(title: String, body: String) throws {
|
|
@@ -96,6 +96,9 @@ export interface NitroLocationTracking extends HybridObject<{
|
|
|
96
96
|
isLocationServicesEnabled(): boolean;
|
|
97
97
|
onProviderStatusChange(callback: ProviderStatusCallback): void;
|
|
98
98
|
getLocationPermissionStatus(): PermissionStatus;
|
|
99
|
+
requestLocationPermission(): Promise<PermissionStatus>;
|
|
100
|
+
getDistanceBetween(lat1: number, lon1: number, lat2: number, lon2: number): number;
|
|
101
|
+
getDistanceToGeofence(regionId: string): number;
|
|
99
102
|
showLocalNotification(title: string, body: string): void;
|
|
100
103
|
updateForegroundNotification(title: string, body: string): void;
|
|
101
104
|
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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"}
|
|
@@ -265,6 +265,32 @@ namespace margelo::nitro::nitrolocationtracking {
|
|
|
265
265
|
auto __result = method(_javaPart);
|
|
266
266
|
return __result->toCpp();
|
|
267
267
|
}
|
|
268
|
+
std::shared_ptr<Promise<PermissionStatus>> JHybridNitroLocationTrackingSpec::requestLocationPermission() {
|
|
269
|
+
static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>()>("requestLocationPermission");
|
|
270
|
+
auto __result = method(_javaPart);
|
|
271
|
+
return [&]() {
|
|
272
|
+
auto __promise = Promise<PermissionStatus>::create();
|
|
273
|
+
__result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
|
|
274
|
+
auto __result = jni::static_ref_cast<JPermissionStatus>(__boxedResult);
|
|
275
|
+
__promise->resolve(__result->toCpp());
|
|
276
|
+
});
|
|
277
|
+
__result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
|
|
278
|
+
jni::JniException __jniError(__throwable);
|
|
279
|
+
__promise->reject(std::make_exception_ptr(__jniError));
|
|
280
|
+
});
|
|
281
|
+
return __promise;
|
|
282
|
+
}();
|
|
283
|
+
}
|
|
284
|
+
double JHybridNitroLocationTrackingSpec::getDistanceBetween(double lat1, double lon1, double lat2, double lon2) {
|
|
285
|
+
static const auto method = javaClassStatic()->getMethod<double(double /* lat1 */, double /* lon1 */, double /* lat2 */, double /* lon2 */)>("getDistanceBetween");
|
|
286
|
+
auto __result = method(_javaPart, lat1, lon1, lat2, lon2);
|
|
287
|
+
return __result;
|
|
288
|
+
}
|
|
289
|
+
double JHybridNitroLocationTrackingSpec::getDistanceToGeofence(const std::string& regionId) {
|
|
290
|
+
static const auto method = javaClassStatic()->getMethod<double(jni::alias_ref<jni::JString> /* regionId */)>("getDistanceToGeofence");
|
|
291
|
+
auto __result = method(_javaPart, jni::make_jstring(regionId));
|
|
292
|
+
return __result;
|
|
293
|
+
}
|
|
268
294
|
void JHybridNitroLocationTrackingSpec::showLocalNotification(const std::string& title, const std::string& body) {
|
|
269
295
|
static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* title */, jni::alias_ref<jni::JString> /* body */)>("showLocalNotification");
|
|
270
296
|
method(_javaPart, jni::make_jstring(title), jni::make_jstring(body));
|
|
@@ -86,6 +86,9 @@ namespace margelo::nitro::nitrolocationtracking {
|
|
|
86
86
|
bool isLocationServicesEnabled() override;
|
|
87
87
|
void onProviderStatusChange(const std::function<void(LocationProviderStatus /* gps */, LocationProviderStatus /* network */)>& callback) override;
|
|
88
88
|
PermissionStatus getLocationPermissionStatus() override;
|
|
89
|
+
std::shared_ptr<Promise<PermissionStatus>> requestLocationPermission() override;
|
|
90
|
+
double getDistanceBetween(double lat1, double lon1, double lat2, double lon2) override;
|
|
91
|
+
double getDistanceToGeofence(const std::string& regionId) override;
|
|
89
92
|
void showLocalNotification(const std::string& title, const std::string& body) override;
|
|
90
93
|
void updateForegroundNotification(const std::string& title, const std::string& body) override;
|
|
91
94
|
void destroy() override;
|
|
@@ -205,6 +205,18 @@ abstract class HybridNitroLocationTrackingSpec: HybridObject() {
|
|
|
205
205
|
@Keep
|
|
206
206
|
abstract fun getLocationPermissionStatus(): PermissionStatus
|
|
207
207
|
|
|
208
|
+
@DoNotStrip
|
|
209
|
+
@Keep
|
|
210
|
+
abstract fun requestLocationPermission(): Promise<PermissionStatus>
|
|
211
|
+
|
|
212
|
+
@DoNotStrip
|
|
213
|
+
@Keep
|
|
214
|
+
abstract fun getDistanceBetween(lat1: Double, lon1: Double, lat2: Double, lon2: Double): Double
|
|
215
|
+
|
|
216
|
+
@DoNotStrip
|
|
217
|
+
@Keep
|
|
218
|
+
abstract fun getDistanceToGeofence(regionId: String): Double
|
|
219
|
+
|
|
208
220
|
@DoNotStrip
|
|
209
221
|
@Keep
|
|
210
222
|
abstract fun showLocalNotification(title: String, body: String): Unit
|
|
@@ -78,6 +78,14 @@ namespace margelo::nitro::nitrolocationtracking::bridge::swift {
|
|
|
78
78
|
};
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
// pragma MARK: std::function<void(PermissionStatus /* result */)>
|
|
82
|
+
Func_void_PermissionStatus create_Func_void_PermissionStatus(void* NON_NULL swiftClosureWrapper) noexcept {
|
|
83
|
+
auto swiftClosure = NitroLocationTracking::Func_void_PermissionStatus::fromUnsafe(swiftClosureWrapper);
|
|
84
|
+
return [swiftClosure = std::move(swiftClosure)](PermissionStatus result) mutable -> void {
|
|
85
|
+
swiftClosure.call(static_cast<int>(result));
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
81
89
|
// pragma MARK: std::shared_ptr<HybridNitroLocationTrackingSpec>
|
|
82
90
|
std::shared_ptr<HybridNitroLocationTrackingSpec> create_std__shared_ptr_HybridNitroLocationTrackingSpec_(void* NON_NULL swiftUnsafePointer) noexcept {
|
|
83
91
|
NitroLocationTracking::HybridNitroLocationTrackingSpec_cxx swiftPart = NitroLocationTracking::HybridNitroLocationTrackingSpec_cxx::fromUnsafe(swiftUnsafePointer);
|
|
@@ -268,6 +268,40 @@ namespace margelo::nitro::nitrolocationtracking::bridge::swift {
|
|
|
268
268
|
return Func_void_LocationProviderStatus_LocationProviderStatus_Wrapper(std::move(value));
|
|
269
269
|
}
|
|
270
270
|
|
|
271
|
+
// pragma MARK: std::shared_ptr<Promise<PermissionStatus>>
|
|
272
|
+
/**
|
|
273
|
+
* Specialized version of `std::shared_ptr<Promise<PermissionStatus>>`.
|
|
274
|
+
*/
|
|
275
|
+
using std__shared_ptr_Promise_PermissionStatus__ = std::shared_ptr<Promise<PermissionStatus>>;
|
|
276
|
+
inline std::shared_ptr<Promise<PermissionStatus>> create_std__shared_ptr_Promise_PermissionStatus__() noexcept {
|
|
277
|
+
return Promise<PermissionStatus>::create();
|
|
278
|
+
}
|
|
279
|
+
inline PromiseHolder<PermissionStatus> wrap_std__shared_ptr_Promise_PermissionStatus__(std::shared_ptr<Promise<PermissionStatus>> promise) noexcept {
|
|
280
|
+
return PromiseHolder<PermissionStatus>(std::move(promise));
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// pragma MARK: std::function<void(PermissionStatus /* result */)>
|
|
284
|
+
/**
|
|
285
|
+
* Specialized version of `std::function<void(PermissionStatus)>`.
|
|
286
|
+
*/
|
|
287
|
+
using Func_void_PermissionStatus = std::function<void(PermissionStatus /* result */)>;
|
|
288
|
+
/**
|
|
289
|
+
* Wrapper class for a `std::function<void(PermissionStatus / * result * /)>`, this can be used from Swift.
|
|
290
|
+
*/
|
|
291
|
+
class Func_void_PermissionStatus_Wrapper final {
|
|
292
|
+
public:
|
|
293
|
+
explicit Func_void_PermissionStatus_Wrapper(std::function<void(PermissionStatus /* result */)>&& func): _function(std::make_unique<std::function<void(PermissionStatus /* result */)>>(std::move(func))) {}
|
|
294
|
+
inline void call(int result) const noexcept {
|
|
295
|
+
_function->operator()(static_cast<PermissionStatus>(result));
|
|
296
|
+
}
|
|
297
|
+
private:
|
|
298
|
+
std::unique_ptr<std::function<void(PermissionStatus /* result */)>> _function;
|
|
299
|
+
} SWIFT_NONCOPYABLE;
|
|
300
|
+
Func_void_PermissionStatus create_Func_void_PermissionStatus(void* NON_NULL swiftClosureWrapper) noexcept;
|
|
301
|
+
inline Func_void_PermissionStatus_Wrapper wrap_Func_void_PermissionStatus(Func_void_PermissionStatus value) noexcept {
|
|
302
|
+
return Func_void_PermissionStatus_Wrapper(std::move(value));
|
|
303
|
+
}
|
|
304
|
+
|
|
271
305
|
// pragma MARK: std::shared_ptr<HybridNitroLocationTrackingSpec>
|
|
272
306
|
/**
|
|
273
307
|
* Specialized version of `std::shared_ptr<HybridNitroLocationTrackingSpec>`.
|
|
@@ -351,5 +385,14 @@ namespace margelo::nitro::nitrolocationtracking::bridge::swift {
|
|
|
351
385
|
inline Result_PermissionStatus_ create_Result_PermissionStatus_(const std::exception_ptr& error) noexcept {
|
|
352
386
|
return Result<PermissionStatus>::withError(error);
|
|
353
387
|
}
|
|
388
|
+
|
|
389
|
+
// pragma MARK: Result<std::shared_ptr<Promise<PermissionStatus>>>
|
|
390
|
+
using Result_std__shared_ptr_Promise_PermissionStatus___ = Result<std::shared_ptr<Promise<PermissionStatus>>>;
|
|
391
|
+
inline Result_std__shared_ptr_Promise_PermissionStatus___ create_Result_std__shared_ptr_Promise_PermissionStatus___(const std::shared_ptr<Promise<PermissionStatus>>& value) noexcept {
|
|
392
|
+
return Result<std::shared_ptr<Promise<PermissionStatus>>>::withValue(value);
|
|
393
|
+
}
|
|
394
|
+
inline Result_std__shared_ptr_Promise_PermissionStatus___ create_Result_std__shared_ptr_Promise_PermissionStatus___(const std::exception_ptr& error) noexcept {
|
|
395
|
+
return Result<std::shared_ptr<Promise<PermissionStatus>>>::withError(error);
|
|
396
|
+
}
|
|
354
397
|
|
|
355
398
|
} // namespace margelo::nitro::nitrolocationtracking::bridge::swift
|
|
@@ -310,6 +310,30 @@ namespace margelo::nitro::nitrolocationtracking {
|
|
|
310
310
|
auto __value = std::move(__result.value());
|
|
311
311
|
return __value;
|
|
312
312
|
}
|
|
313
|
+
inline std::shared_ptr<Promise<PermissionStatus>> requestLocationPermission() override {
|
|
314
|
+
auto __result = _swiftPart.requestLocationPermission();
|
|
315
|
+
if (__result.hasError()) [[unlikely]] {
|
|
316
|
+
std::rethrow_exception(__result.error());
|
|
317
|
+
}
|
|
318
|
+
auto __value = std::move(__result.value());
|
|
319
|
+
return __value;
|
|
320
|
+
}
|
|
321
|
+
inline double getDistanceBetween(double lat1, double lon1, double lat2, double lon2) override {
|
|
322
|
+
auto __result = _swiftPart.getDistanceBetween(std::forward<decltype(lat1)>(lat1), std::forward<decltype(lon1)>(lon1), std::forward<decltype(lat2)>(lat2), std::forward<decltype(lon2)>(lon2));
|
|
323
|
+
if (__result.hasError()) [[unlikely]] {
|
|
324
|
+
std::rethrow_exception(__result.error());
|
|
325
|
+
}
|
|
326
|
+
auto __value = std::move(__result.value());
|
|
327
|
+
return __value;
|
|
328
|
+
}
|
|
329
|
+
inline double getDistanceToGeofence(const std::string& regionId) override {
|
|
330
|
+
auto __result = _swiftPart.getDistanceToGeofence(regionId);
|
|
331
|
+
if (__result.hasError()) [[unlikely]] {
|
|
332
|
+
std::rethrow_exception(__result.error());
|
|
333
|
+
}
|
|
334
|
+
auto __value = std::move(__result.value());
|
|
335
|
+
return __value;
|
|
336
|
+
}
|
|
313
337
|
inline void showLocalNotification(const std::string& title, const std::string& body) override {
|
|
314
338
|
auto __result = _swiftPart.showLocalNotification(title, body);
|
|
315
339
|
if (__result.hasError()) [[unlikely]] {
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// Func_void_PermissionStatus.swift
|
|
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
|
+
import NitroModules
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Wraps a Swift `(_ value: PermissionStatus) -> Void` as a class.
|
|
12
|
+
* This class can be used from C++, e.g. to wrap the Swift closure as a `std::function`.
|
|
13
|
+
*/
|
|
14
|
+
public final class Func_void_PermissionStatus {
|
|
15
|
+
public typealias bridge = margelo.nitro.nitrolocationtracking.bridge.swift
|
|
16
|
+
|
|
17
|
+
private let closure: (_ value: PermissionStatus) -> Void
|
|
18
|
+
|
|
19
|
+
public init(_ closure: @escaping (_ value: PermissionStatus) -> Void) {
|
|
20
|
+
self.closure = closure
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@inline(__always)
|
|
24
|
+
public func call(value: Int32) -> Void {
|
|
25
|
+
self.closure(margelo.nitro.nitrolocationtracking.PermissionStatus(rawValue: value)!)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Casts this instance to a retained unsafe raw pointer.
|
|
30
|
+
* This acquires one additional strong reference on the object!
|
|
31
|
+
*/
|
|
32
|
+
@inline(__always)
|
|
33
|
+
public func toUnsafe() -> UnsafeMutableRawPointer {
|
|
34
|
+
return Unmanaged.passRetained(self).toOpaque()
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Casts an unsafe pointer to a `Func_void_PermissionStatus`.
|
|
39
|
+
* The pointer has to be a retained opaque `Unmanaged<Func_void_PermissionStatus>`.
|
|
40
|
+
* This removes one strong reference from the object!
|
|
41
|
+
*/
|
|
42
|
+
@inline(__always)
|
|
43
|
+
public static func fromUnsafe(_ pointer: UnsafeMutableRawPointer) -> Func_void_PermissionStatus {
|
|
44
|
+
return Unmanaged<Func_void_PermissionStatus>.fromOpaque(pointer).takeRetainedValue()
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -44,6 +44,9 @@ public protocol HybridNitroLocationTrackingSpec_protocol: HybridObject {
|
|
|
44
44
|
func isLocationServicesEnabled() throws -> Bool
|
|
45
45
|
func onProviderStatusChange(callback: @escaping (_ gps: LocationProviderStatus, _ network: LocationProviderStatus) -> Void) throws -> Void
|
|
46
46
|
func getLocationPermissionStatus() throws -> PermissionStatus
|
|
47
|
+
func requestLocationPermission() throws -> Promise<PermissionStatus>
|
|
48
|
+
func getDistanceBetween(lat1: Double, lon1: Double, lat2: Double, lon2: Double) throws -> Double
|
|
49
|
+
func getDistanceToGeofence(regionId: String) throws -> Double
|
|
47
50
|
func showLocalNotification(title: String, body: String) throws -> Void
|
|
48
51
|
func updateForegroundNotification(title: String, body: String) throws -> Void
|
|
49
52
|
func destroy() throws -> Void
|
|
@@ -524,6 +524,49 @@ open class HybridNitroLocationTrackingSpec_cxx {
|
|
|
524
524
|
}
|
|
525
525
|
}
|
|
526
526
|
|
|
527
|
+
@inline(__always)
|
|
528
|
+
public final func requestLocationPermission() -> bridge.Result_std__shared_ptr_Promise_PermissionStatus___ {
|
|
529
|
+
do {
|
|
530
|
+
let __result = try self.__implementation.requestLocationPermission()
|
|
531
|
+
let __resultCpp = { () -> bridge.std__shared_ptr_Promise_PermissionStatus__ in
|
|
532
|
+
let __promise = bridge.create_std__shared_ptr_Promise_PermissionStatus__()
|
|
533
|
+
let __promiseHolder = bridge.wrap_std__shared_ptr_Promise_PermissionStatus__(__promise)
|
|
534
|
+
__result
|
|
535
|
+
.then({ __result in __promiseHolder.resolve(__result) })
|
|
536
|
+
.catch({ __error in __promiseHolder.reject(__error.toCpp()) })
|
|
537
|
+
return __promise
|
|
538
|
+
}()
|
|
539
|
+
return bridge.create_Result_std__shared_ptr_Promise_PermissionStatus___(__resultCpp)
|
|
540
|
+
} catch (let __error) {
|
|
541
|
+
let __exceptionPtr = __error.toCpp()
|
|
542
|
+
return bridge.create_Result_std__shared_ptr_Promise_PermissionStatus___(__exceptionPtr)
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
@inline(__always)
|
|
547
|
+
public final func getDistanceBetween(lat1: Double, lon1: Double, lat2: Double, lon2: Double) -> bridge.Result_double_ {
|
|
548
|
+
do {
|
|
549
|
+
let __result = try self.__implementation.getDistanceBetween(lat1: lat1, lon1: lon1, lat2: lat2, lon2: lon2)
|
|
550
|
+
let __resultCpp = __result
|
|
551
|
+
return bridge.create_Result_double_(__resultCpp)
|
|
552
|
+
} catch (let __error) {
|
|
553
|
+
let __exceptionPtr = __error.toCpp()
|
|
554
|
+
return bridge.create_Result_double_(__exceptionPtr)
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
@inline(__always)
|
|
559
|
+
public final func getDistanceToGeofence(regionId: std.string) -> bridge.Result_double_ {
|
|
560
|
+
do {
|
|
561
|
+
let __result = try self.__implementation.getDistanceToGeofence(regionId: String(regionId))
|
|
562
|
+
let __resultCpp = __result
|
|
563
|
+
return bridge.create_Result_double_(__resultCpp)
|
|
564
|
+
} catch (let __error) {
|
|
565
|
+
let __exceptionPtr = __error.toCpp()
|
|
566
|
+
return bridge.create_Result_double_(__exceptionPtr)
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
|
|
527
570
|
@inline(__always)
|
|
528
571
|
public final func showLocalNotification(title: std.string, body: std.string) -> bridge.Result_void_ {
|
|
529
572
|
do {
|
|
@@ -45,6 +45,9 @@ namespace margelo::nitro::nitrolocationtracking {
|
|
|
45
45
|
prototype.registerHybridMethod("isLocationServicesEnabled", &HybridNitroLocationTrackingSpec::isLocationServicesEnabled);
|
|
46
46
|
prototype.registerHybridMethod("onProviderStatusChange", &HybridNitroLocationTrackingSpec::onProviderStatusChange);
|
|
47
47
|
prototype.registerHybridMethod("getLocationPermissionStatus", &HybridNitroLocationTrackingSpec::getLocationPermissionStatus);
|
|
48
|
+
prototype.registerHybridMethod("requestLocationPermission", &HybridNitroLocationTrackingSpec::requestLocationPermission);
|
|
49
|
+
prototype.registerHybridMethod("getDistanceBetween", &HybridNitroLocationTrackingSpec::getDistanceBetween);
|
|
50
|
+
prototype.registerHybridMethod("getDistanceToGeofence", &HybridNitroLocationTrackingSpec::getDistanceToGeofence);
|
|
48
51
|
prototype.registerHybridMethod("showLocalNotification", &HybridNitroLocationTrackingSpec::showLocalNotification);
|
|
49
52
|
prototype.registerHybridMethod("updateForegroundNotification", &HybridNitroLocationTrackingSpec::updateForegroundNotification);
|
|
50
53
|
prototype.registerHybridMethod("destroy", &HybridNitroLocationTrackingSpec::destroy);
|
|
@@ -113,6 +113,9 @@ namespace margelo::nitro::nitrolocationtracking {
|
|
|
113
113
|
virtual bool isLocationServicesEnabled() = 0;
|
|
114
114
|
virtual void onProviderStatusChange(const std::function<void(LocationProviderStatus /* gps */, LocationProviderStatus /* network */)>& callback) = 0;
|
|
115
115
|
virtual PermissionStatus getLocationPermissionStatus() = 0;
|
|
116
|
+
virtual std::shared_ptr<Promise<PermissionStatus>> requestLocationPermission() = 0;
|
|
117
|
+
virtual double getDistanceBetween(double lat1, double lon1, double lat2, double lon2) = 0;
|
|
118
|
+
virtual double getDistanceToGeofence(const std::string& regionId) = 0;
|
|
116
119
|
virtual void showLocalNotification(const std::string& title, const std::string& body) = 0;
|
|
117
120
|
virtual void updateForegroundNotification(const std::string& title, const std::string& body) = 0;
|
|
118
121
|
virtual void destroy() = 0;
|
package/package.json
CHANGED
|
@@ -143,6 +143,16 @@ export interface NitroLocationTracking
|
|
|
143
143
|
|
|
144
144
|
// === Permission Status ===
|
|
145
145
|
getLocationPermissionStatus(): PermissionStatus;
|
|
146
|
+
requestLocationPermission(): Promise<PermissionStatus>;
|
|
147
|
+
|
|
148
|
+
// === Distance Utilities ===
|
|
149
|
+
getDistanceBetween(
|
|
150
|
+
lat1: number,
|
|
151
|
+
lon1: number,
|
|
152
|
+
lat2: number,
|
|
153
|
+
lon2: number
|
|
154
|
+
): number; // meters
|
|
155
|
+
getDistanceToGeofence(regionId: string): number; // meters from last known location to geofence center, -1 if not found
|
|
146
156
|
|
|
147
157
|
// === Notifications ===
|
|
148
158
|
showLocalNotification(title: string, body: string): void;
|