react-native-nitro-location-tracking 0.1.13 → 0.1.14

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 CHANGED
@@ -453,6 +453,36 @@ NitroLocationModule.onProviderStatusChange((gps, network) => {
453
453
  });
454
454
  ```
455
455
 
456
+ ### Prompt user to enable GPS
457
+
458
+ Ask the user to turn on device location. On Android this shows the native
459
+ Google Play Services in-app dialog ("For better experience, turn on device
460
+ location…") without leaving the app. On iOS there is no equivalent system
461
+ dialog, so this opens your app's Settings page and resolves after the user
462
+ returns to the app.
463
+
464
+ ```tsx
465
+ import NitroLocationModule from 'react-native-nitro-location-tracking';
466
+
467
+ async function ensureGpsOn() {
468
+ if (NitroLocationModule.isLocationServicesEnabled()) {
469
+ return true;
470
+ }
471
+ const enabled = await NitroLocationModule.openLocationSettings();
472
+ if (enabled) {
473
+ NitroLocationModule.startTracking();
474
+ } else {
475
+ // User declined the dialog (Android) or did not enable GPS (iOS)
476
+ }
477
+ return enabled;
478
+ }
479
+ ```
480
+
481
+ **Platform behavior:**
482
+
483
+ - **Android** — Uses `SettingsClient.checkLocationSettings()` + `startResolutionForResult`. Resolves `true` if GPS is already on or if the user accepts the dialog, `false` if the user declines or the dialog cannot be shown.
484
+ - **iOS** — Opens the app's Settings page via `UIApplication.openSettingsURLString` and listens for `UIApplication.didBecomeActiveNotification` to detect the return to foreground. Resolves `true` if `CLLocationManager.locationServicesEnabled()` is on after the user returns, `false` otherwise.
485
+
456
486
  ### Permission Status
457
487
 
458
488
  Check the current location permission status without prompting the user:
@@ -703,17 +733,17 @@ type PermissionStatus =
703
733
  | `stopTripCalculation()` | `TripStats` | Stop recording and get final stats |
704
734
  | `getTripStats()` | `TripStats` | Get current trip stats without stopping |
705
735
  | `resetTripCalculation()` | `void` | Reset trip calculator |
706
- | `isLocationServicesEnabled()` | `boolean` | Check if GPS/location is enabled on device |
707
- | `openLocationSettings(accuracy, interval)` | `void` | Native app dialog to enable GPS or redirect to system settings |
708
- | `onProviderStatusChange(callback)` | `void` | Register GPS/network provider status callback |
709
- | `isAirplaneModeEnabled()` | `boolean` | Check if Airplane mode is active on Android |
710
- | `onAirplaneModeChange(callback)` | `void` | Register Airplane mode state-transition callback |
711
- | `getLocationPermissionStatus()` | `PermissionStatus` | Check current location permission without prompting |
712
- | `requestLocationPermission()` | `Promise<PermissionStatus>` | Request location permission and return the resulting status |
713
- | `onPermissionStatusChange(callback)` | `void` | Register a callback that fires when location permission status changes |
714
- | `showLocalNotification(title, body)` | `void` | Show a local notification |
715
- | `updateForegroundNotification(title, body)` | `void` | Update the foreground service notification |
716
- | `destroy()` | `void` | Stop tracking and disconnect |
736
+ | `isLocationServicesEnabled()` | `boolean` | Check if GPS/location is enabled on device |
737
+ | `openLocationSettings()` | `Promise<boolean>` | Prompt user to enable GPS. Resolves `true` if enabled, `false` if not |
738
+ | `onProviderStatusChange(callback)` | `void` | Register GPS/network provider status callback |
739
+ | `isAirplaneModeEnabled()` | `boolean` | Check if Airplane mode is active on Android |
740
+ | `onAirplaneModeChange(callback)` | `void` | Register Airplane mode state-transition callback |
741
+ | `getLocationPermissionStatus()` | `PermissionStatus` | Check current location permission without prompting |
742
+ | `requestLocationPermission()` | `Promise<PermissionStatus>` | Request location permission and return the resulting status |
743
+ | `onPermissionStatusChange(callback)` | `void` | Register a callback that fires when location permission status changes |
744
+ | `showLocalNotification(title, body)` | `void` | Show a local notification |
745
+ | `updateForegroundNotification(title, body)` | `void` | Update the foreground service notification |
746
+ | `destroy()` | `void` | Stop tracking and disconnect |
717
747
 
718
748
  ### Utility Exports
719
749
 
@@ -34,7 +34,7 @@ class LocationEngine(private val context: Context) {
34
34
  val isTracking: Boolean get() = tracking
35
35
 
36
36
  @SuppressLint("MissingPermission")
37
- fun start(config: LocationConfig) {
37
+ fun start(config: LocationConfig): Boolean {
38
38
  if (tracking) {
39
39
  locationCallback?.let { fusedClient.removeLocationUpdates(it) }
40
40
  }
@@ -59,9 +59,25 @@ class LocationEngine(private val context: Context) {
59
59
  Log.d(TAG, "onLocationAvailability — isLocationAvailable=${availability.isLocationAvailable}")
60
60
  }
61
61
  }
62
- fusedClient.requestLocationUpdates(
63
- request, locationCallback!!, Looper.getMainLooper())
64
- tracking = true
62
+ return try {
63
+ fusedClient.requestLocationUpdates(
64
+ request, locationCallback!!, Looper.getMainLooper())
65
+ tracking = true
66
+ true
67
+ } catch (e: SecurityException) {
68
+ // Permission was revoked between our caller's check and this call, or
69
+ // the FusedLocationProvider is otherwise refusing access. Fail closed
70
+ // instead of crashing the process.
71
+ Log.w(TAG, "requestLocationUpdates refused — permission missing: ${e.message}")
72
+ locationCallback = null
73
+ tracking = false
74
+ false
75
+ } catch (e: Exception) {
76
+ Log.e(TAG, "requestLocationUpdates failed: ${e.message}")
77
+ locationCallback = null
78
+ tracking = false
79
+ false
80
+ }
65
81
  }
66
82
 
67
83
  fun stop() {
@@ -72,13 +88,18 @@ class LocationEngine(private val context: Context) {
72
88
 
73
89
  @SuppressLint("MissingPermission")
74
90
  fun getCurrentLocation(callback: (LocationData?) -> Unit) {
75
- fusedClient.lastLocation.addOnSuccessListener { location ->
76
- if (location != null) {
77
- callback(locationToData(location))
78
- } else {
91
+ try {
92
+ fusedClient.lastLocation.addOnSuccessListener { location ->
93
+ if (location != null) {
94
+ callback(locationToData(location))
95
+ } else {
96
+ callback(null)
97
+ }
98
+ }.addOnFailureListener {
79
99
  callback(null)
80
100
  }
81
- }.addOnFailureListener {
101
+ } catch (e: SecurityException) {
102
+ Log.w(TAG, "getCurrentLocation refused — permission missing: ${e.message}")
82
103
  callback(null)
83
104
  }
84
105
  }
@@ -1,13 +1,17 @@
1
1
  package com.margelo.nitro.nitrolocationtracking
2
2
 
3
+ import android.app.Activity
4
+ import android.content.Intent
3
5
  import android.content.pm.PackageManager
4
6
  import android.util.Log
5
7
  import androidx.core.app.ActivityCompat
6
8
  import androidx.core.content.ContextCompat
7
9
  import com.facebook.proguard.annotations.DoNotStrip
10
+ import com.facebook.react.bridge.BaseActivityEventListener
8
11
  import com.facebook.react.bridge.ReactContext
9
12
  import com.margelo.nitro.NitroModules
10
13
  import com.margelo.nitro.core.Promise
14
+ import java.util.concurrent.atomic.AtomicBoolean
11
15
  import kotlin.coroutines.resume
12
16
  import kotlin.coroutines.resumeWithException
13
17
  import kotlin.coroutines.suspendCoroutine
@@ -18,6 +22,7 @@ class NitroLocationTracking : HybridNitroLocationTrackingSpec() {
18
22
  companion object {
19
23
  private const val TAG = "NitroLocationTracking"
20
24
  private const val PERMISSION_REQUEST_CODE = 9001
25
+ private const val GPS_RESOLUTION_REQUEST_CODE = 9002
21
26
  }
22
27
 
23
28
  private var locationEngine: LocationEngine? = null
@@ -61,6 +66,26 @@ class NitroLocationTracking : HybridNitroLocationTrackingSpec() {
61
66
  airplaneModeMonitor = AirplaneModeMonitor(context)
62
67
  locationEngine?.dbWriter = dbWriter
63
68
  connectionManager.dbWriter = dbWriter
69
+
70
+ // Always watch for permission revocation so we can proactively tear
71
+ // down tracking + the foreground service before the OS kills us for
72
+ // holding a location-type FGS without the matching permission.
73
+ permissionStatusMonitor?.setInternalCallback { status ->
74
+ if (status == PermissionStatus.DENIED || status == PermissionStatus.RESTRICTED) {
75
+ Log.w(TAG, "Location permission revoked — stopping tracking and foreground service")
76
+ try {
77
+ locationEngine?.stop()
78
+ } catch (e: Exception) {
79
+ Log.w(TAG, "Error stopping location engine: ${e.message}")
80
+ }
81
+ try {
82
+ notificationService?.stopForegroundService()
83
+ } catch (e: Exception) {
84
+ Log.w(TAG, "Error stopping foreground service: ${e.message}")
85
+ }
86
+ }
87
+ }
88
+
64
89
  Log.d(TAG, "Components initialized successfully")
65
90
  return true
66
91
  }
@@ -81,6 +106,20 @@ class NitroLocationTracking : HybridNitroLocationTrackingSpec() {
81
106
  Log.e(TAG, "startTracking failed — could not initialize components")
82
107
  return
83
108
  }
109
+
110
+ // Permission guard. Starting a foreground service of type `location`
111
+ // without holding ACCESS_FINE_LOCATION throws SecurityException on
112
+ // Android 14+. And even on older versions, requestLocationUpdates
113
+ // will throw SecurityException. Fail closed and notify JS instead
114
+ // of crashing the process.
115
+ val permissionStatus = getLocationPermissionStatus()
116
+ if (permissionStatus == PermissionStatus.DENIED ||
117
+ permissionStatus == PermissionStatus.RESTRICTED) {
118
+ Log.w(TAG, "startTracking aborted — location permission is $permissionStatus")
119
+ permissionStatusCallback?.invoke(permissionStatus)
120
+ return
121
+ }
122
+
84
123
  val engine = locationEngine ?: return
85
124
  engine.onLocation = { data ->
86
125
  locationCallback?.invoke(data)
@@ -88,7 +127,14 @@ class NitroLocationTracking : HybridNitroLocationTrackingSpec() {
88
127
  engine.onMotionChange = { isMoving ->
89
128
  motionCallback?.invoke(isMoving)
90
129
  }
91
- engine.start(config)
130
+ val started = engine.start(config)
131
+ if (!started) {
132
+ // engine.start() already logged the reason. Don't start the FGS
133
+ // if tracking itself could not be started — the FGS would just
134
+ // be killed immediately by the OS.
135
+ Log.w(TAG, "startTracking aborted — location engine refused to start")
136
+ return
137
+ }
92
138
 
93
139
  try {
94
140
  notificationService?.startForegroundService(
@@ -97,6 +143,12 @@ class NitroLocationTracking : HybridNitroLocationTrackingSpec() {
97
143
  )
98
144
  } catch (e: SecurityException) {
99
145
  Log.w(TAG, "Could not start foreground service — missing runtime permissions: ${e.message}")
146
+ // Roll back the tracking session so we don't leak a location
147
+ // request with no owning foreground service.
148
+ try { engine.stop() } catch (_: Exception) {}
149
+ } catch (e: Exception) {
150
+ Log.w(TAG, "Could not start foreground service: ${e.message}")
151
+ try { engine.stop() } catch (_: Exception) {}
100
152
  }
101
153
  }
102
154
 
@@ -367,41 +419,96 @@ class NitroLocationTracking : HybridNitroLocationTrackingSpec() {
367
419
  }
368
420
  }
369
421
 
370
- override fun openLocationSettings(accuracy: AccuracyLevel, intervalMs: Double) {
371
- val context = NitroModules.applicationContext ?: return
372
- val activity = (context as? com.facebook.react.bridge.ReactContext)?.currentActivity
373
-
374
- if (activity != null) {
375
- val priority = when (accuracy) {
376
- AccuracyLevel.BALANCED -> com.google.android.gms.location.Priority.PRIORITY_BALANCED_POWER_ACCURACY
377
- AccuracyLevel.LOW -> com.google.android.gms.location.Priority.PRIORITY_LOW_POWER
378
- else -> com.google.android.gms.location.Priority.PRIORITY_HIGH_ACCURACY
379
- }
380
- val interval = intervalMs.toLong()
381
-
382
- val locationRequest = com.google.android.gms.location.LocationRequest.Builder(
383
- priority, interval
384
- ).build()
385
- val builder = com.google.android.gms.location.LocationSettingsRequest.Builder()
386
- .addLocationRequest(locationRequest)
387
- .setAlwaysShow(true)
388
-
389
- val client = com.google.android.gms.location.LocationServices.getSettingsClient(context)
390
- val task = client.checkLocationSettings(builder.build())
391
-
392
- task.addOnFailureListener { exception ->
393
- if (exception is com.google.android.gms.common.api.ResolvableApiException) {
394
- try {
395
- exception.startResolutionForResult(activity, 9002) // arbitrary request code
396
- } catch (e: Exception) {
422
+ override fun openLocationSettings(): Promise<Boolean> {
423
+ return Promise.async {
424
+ suspendCoroutine { cont ->
425
+ val context = NitroModules.applicationContext
426
+ if (context == null) {
427
+ cont.resume(false)
428
+ return@suspendCoroutine
429
+ }
430
+
431
+ val reactContext = context as? ReactContext
432
+ val activity = reactContext?.currentActivity
433
+ if (reactContext == null || activity == null) {
434
+ Log.w(TAG, "openLocationSettings no current Activity, using fallback")
435
+ openLocationSettingsFallback(context)
436
+ cont.resume(isLocationServicesEnabled())
437
+ return@suspendCoroutine
438
+ }
439
+
440
+ // Use a high-accuracy location request for the settings check.
441
+ // These values are internal to the SettingsClient call — they do
442
+ // not affect the tracking configuration.
443
+ val locationRequest = com.google.android.gms.location.LocationRequest.Builder(
444
+ com.google.android.gms.location.Priority.PRIORITY_HIGH_ACCURACY,
445
+ 10_000L
446
+ ).build()
447
+
448
+ val settingsRequest = com.google.android.gms.location.LocationSettingsRequest.Builder()
449
+ .addLocationRequest(locationRequest)
450
+ .setAlwaysShow(true)
451
+ .build()
452
+
453
+ val client = com.google.android.gms.location.LocationServices.getSettingsClient(context)
454
+ val task = client.checkLocationSettings(settingsRequest)
455
+
456
+ // Guard against double-resume — the continuation may otherwise
457
+ // be resumed by both the success listener and the activity
458
+ // result listener in rare race conditions.
459
+ val resumed = AtomicBoolean(false)
460
+ fun safeResume(value: Boolean) {
461
+ if (resumed.compareAndSet(false, true)) {
462
+ cont.resume(value)
463
+ }
464
+ }
465
+
466
+ task.addOnSuccessListener {
467
+ // Location settings are already satisfied — GPS is on.
468
+ safeResume(true)
469
+ }
470
+
471
+ task.addOnFailureListener { exception ->
472
+ if (exception is com.google.android.gms.common.api.ResolvableApiException) {
473
+ // Register the activity result listener BEFORE showing
474
+ // the dialog so we cannot miss the result.
475
+ val listener = object : BaseActivityEventListener() {
476
+ override fun onActivityResult(
477
+ activity: Activity?,
478
+ requestCode: Int,
479
+ resultCode: Int,
480
+ data: Intent?
481
+ ) {
482
+ if (requestCode != GPS_RESOLUTION_REQUEST_CODE) return
483
+ reactContext.removeActivityEventListener(this)
484
+ // RESULT_OK = user tapped "OK" in the dialog and GPS is now on.
485
+ // RESULT_CANCELED = user tapped "No thanks" or dismissed.
486
+ val enabled = resultCode == Activity.RESULT_OK
487
+ safeResume(enabled)
488
+ }
489
+ }
490
+ reactContext.addActivityEventListener(listener)
491
+
492
+ try {
493
+ exception.startResolutionForResult(
494
+ activity, GPS_RESOLUTION_REQUEST_CODE
495
+ )
496
+ } catch (e: Exception) {
497
+ Log.w(TAG, "Failed to show resolution dialog: ${e.message}")
498
+ reactContext.removeActivityEventListener(listener)
499
+ openLocationSettingsFallback(context)
500
+ safeResume(isLocationServicesEnabled())
501
+ }
502
+ } else {
503
+ // Not resolvable (e.g. SETTINGS_CHANGE_UNAVAILABLE on an
504
+ // airplane-mode-locked device) — fall back to the system
505
+ // settings screen.
506
+ Log.w(TAG, "Location settings not resolvable: ${exception.message}")
397
507
  openLocationSettingsFallback(context)
508
+ safeResume(isLocationServicesEnabled())
398
509
  }
399
- } else {
400
- openLocationSettingsFallback(context)
401
510
  }
402
511
  }
403
- } else {
404
- openLocationSettingsFallback(context)
405
512
  }
406
513
  }
407
514
 
@@ -25,7 +25,9 @@ class PermissionStatusMonitor(private val context: Context) {
25
25
  }
26
26
 
27
27
  private var callback: ((PermissionStatus) -> Unit)? = null
28
+ private var internalCallback: ((PermissionStatus) -> Unit)? = null
28
29
  private var lastStatus: PermissionStatus? = null
30
+ private var observerRegistered = false
29
31
  private val mainHandler = Handler(Looper.getMainLooper())
30
32
 
31
33
  private val lifecycleObserver = object : DefaultLifecycleObserver {
@@ -36,8 +38,25 @@ class PermissionStatusMonitor(private val context: Context) {
36
38
 
37
39
  fun setCallback(callback: (PermissionStatus) -> Unit) {
38
40
  this.callback = callback
41
+ ensureObserverRegistered()
42
+ }
43
+
44
+ /**
45
+ * Internal callback used by the native module to react to permission loss
46
+ * (e.g. auto-stop tracking) independently of any JS listener. Registering
47
+ * this also starts the lifecycle observer, so native cleanup works even
48
+ * when the user has not called onPermissionStatusChange() from JS.
49
+ */
50
+ fun setInternalCallback(callback: (PermissionStatus) -> Unit) {
51
+ this.internalCallback = callback
52
+ ensureObserverRegistered()
53
+ }
54
+
55
+ private fun ensureObserverRegistered() {
56
+ if (observerRegistered) return
39
57
  // Capture the current status so we only fire on actual changes
40
58
  lastStatus = getCurrentPermissionStatus()
59
+ observerRegistered = true
41
60
 
42
61
  // addObserver MUST be called on the main thread
43
62
  mainHandler.post {
@@ -46,6 +65,7 @@ class PermissionStatusMonitor(private val context: Context) {
46
65
  Log.d(TAG, "Registered lifecycle observer for permission changes")
47
66
  } catch (e: Exception) {
48
67
  Log.e(TAG, "Failed to register lifecycle observer: ${e.message}")
68
+ observerRegistered = false
49
69
  }
50
70
  }
51
71
  }
@@ -55,6 +75,10 @@ class PermissionStatusMonitor(private val context: Context) {
55
75
  if (current != lastStatus) {
56
76
  Log.d(TAG, "Permission status changed: $lastStatus -> $current")
57
77
  lastStatus = current
78
+ // Native cleanup first, JS notification second — so by the time JS
79
+ // hears about the denial, the native side has already released
80
+ // resources (tracking session, foreground service).
81
+ internalCallback?.invoke(current)
58
82
  callback?.invoke(current)
59
83
  }
60
84
  }
@@ -86,7 +110,9 @@ class PermissionStatusMonitor(private val context: Context) {
86
110
  ProcessLifecycleOwner.get().lifecycle.removeObserver(lifecycleObserver)
87
111
  } catch (_: Exception) {}
88
112
  }
113
+ observerRegistered = false
89
114
  callback = null
115
+ internalCallback = null
90
116
  lastStatus = null
91
117
  }
92
118
  }
@@ -238,6 +238,17 @@ class LocationEngine: NSObject, CLLocationManagerDelegate {
238
238
  }
239
239
  }
240
240
 
241
+ // Auto-stop if permission was revoked while tracking. Without this the
242
+ // engine stays flagged as tracking but Core Location silently delivers
243
+ // nothing, leaving the app in an inconsistent state.
244
+ if authStatus == .denied || authStatus == .restricted {
245
+ if tracking {
246
+ locationManager.stopUpdatingLocation()
247
+ tracking = false
248
+ pendingStartAfterPermission = false
249
+ }
250
+ }
251
+
241
252
  // Notify JS about permission status change (deduplicated)
242
253
  let permStatus = Self.mapAuthStatus(authStatus)
243
254
  if permStatus != lastPermissionStatus {
@@ -1,6 +1,7 @@
1
1
  import Foundation
2
2
  import CoreLocation
3
3
  import NitroModules
4
+ import UIKit
4
5
 
5
6
  class NitroLocationTracking: HybridNitroLocationTrackingSpec {
6
7
  private let locationEngine = LocationEngine()
@@ -249,14 +250,60 @@ class NitroLocationTracking: HybridNitroLocationTrackingSpec {
249
250
  locationEngine.permissionStatusCallback = callback
250
251
  }
251
252
 
252
- func openLocationSettings(accuracy: AccuracyLevel, intervalMs: Double) throws {
253
+ func openLocationSettings() throws -> Promise<Bool> {
254
+ let promise = Promise<Bool>()
255
+
256
+ // Guard against double-resolve — didBecomeActive can fire more than
257
+ // once while the user bounces between apps, and we also resolve from
258
+ // the open(url) completion handler on failure.
259
+ let resolvedLock = NSLock()
260
+ var hasResolved = false
261
+ func safeResolve(_ value: Bool) {
262
+ resolvedLock.lock()
263
+ defer { resolvedLock.unlock() }
264
+ if hasResolved { return }
265
+ hasResolved = true
266
+ promise.resolve(withResult: value)
267
+ }
268
+
253
269
  DispatchQueue.main.async {
254
- if let url = URL(string: UIApplication.openSettingsURLString) {
255
- if UIApplication.shared.canOpenURL(url) {
256
- UIApplication.shared.open(url, options: [:], completionHandler: nil)
270
+ guard let url = URL(string: UIApplication.openSettingsURLString),
271
+ UIApplication.shared.canOpenURL(url) else {
272
+ safeResolve(CLLocationManager.locationServicesEnabled())
273
+ return
274
+ }
275
+
276
+ // Register the observer BEFORE opening Settings so we never miss
277
+ // the return-to-foreground event.
278
+ var observer: NSObjectProtocol?
279
+ observer = NotificationCenter.default.addObserver(
280
+ forName: UIApplication.didBecomeActiveNotification,
281
+ object: nil,
282
+ queue: .main
283
+ ) { _ in
284
+ if let obs = observer {
285
+ NotificationCenter.default.removeObserver(obs)
286
+ observer = nil
287
+ }
288
+ // Give iOS a short beat to refresh the location-services flag
289
+ // after the user toggles it in Settings.
290
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
291
+ safeResolve(CLLocationManager.locationServicesEnabled())
292
+ }
293
+ }
294
+
295
+ UIApplication.shared.open(url, options: [:]) { success in
296
+ if !success {
297
+ if let obs = observer {
298
+ NotificationCenter.default.removeObserver(obs)
299
+ observer = nil
300
+ }
301
+ safeResolve(CLLocationManager.locationServicesEnabled())
257
302
  }
258
303
  }
259
304
  }
305
+
306
+ return promise
260
307
  }
261
308
 
262
309
  // MARK: - Device State Monitoring
@@ -101,7 +101,21 @@ export interface NitroLocationTracking extends HybridObject<{
101
101
  getLocationPermissionStatus(): PermissionStatus;
102
102
  requestLocationPermission(): Promise<PermissionStatus>;
103
103
  onPermissionStatusChange(callback: PermissionStatusCallback): void;
104
- openLocationSettings(accuracy: AccuracyLevel, intervalMs: number): void;
104
+ /**
105
+ * Prompt the user to enable device location (GPS).
106
+ *
107
+ * On Android this shows the native Google Play Services in-app resolution
108
+ * dialog ("For better experience, turn on device location…"). The promise
109
+ * resolves `true` if GPS is enabled (either because it already was, or
110
+ * because the user accepted the dialog), and `false` if the user declined
111
+ * or the dialog could not be shown.
112
+ *
113
+ * On iOS there is no in-app dialog for enabling location services, so this
114
+ * opens the app's Settings page. The promise resolves after the app
115
+ * returns to foreground: `true` if `locationServicesEnabled()` is now on,
116
+ * `false` otherwise.
117
+ */
118
+ openLocationSettings(): Promise<boolean>;
105
119
  isAirplaneModeEnabled(): boolean;
106
120
  onAirplaneModeChange(callback: (isEnabled: boolean) => void): void;
107
121
  getDistanceBetween(lat1: number, lon1: number, lat2: number, lon2: number): number;
@@ -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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"}
@@ -290,9 +290,21 @@ namespace margelo::nitro::nitrolocationtracking {
290
290
  static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<JFunc_void_PermissionStatus::javaobject> /* callback */)>("onPermissionStatusChange_cxx");
291
291
  method(_javaPart, JFunc_void_PermissionStatus_cxx::fromCpp(callback));
292
292
  }
293
- void JHybridNitroLocationTrackingSpec::openLocationSettings(AccuracyLevel accuracy, double intervalMs) {
294
- static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<JAccuracyLevel> /* accuracy */, double /* intervalMs */)>("openLocationSettings");
295
- method(_javaPart, JAccuracyLevel::fromCpp(accuracy), intervalMs);
293
+ std::shared_ptr<Promise<bool>> JHybridNitroLocationTrackingSpec::openLocationSettings() {
294
+ static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>()>("openLocationSettings");
295
+ auto __result = method(_javaPart);
296
+ return [&]() {
297
+ auto __promise = Promise<bool>::create();
298
+ __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
299
+ auto __result = jni::static_ref_cast<jni::JBoolean>(__boxedResult);
300
+ __promise->resolve(static_cast<bool>(__result->value()));
301
+ });
302
+ __result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
303
+ jni::JniException __jniError(__throwable);
304
+ __promise->reject(std::make_exception_ptr(__jniError));
305
+ });
306
+ return __promise;
307
+ }();
296
308
  }
297
309
  bool JHybridNitroLocationTrackingSpec::isAirplaneModeEnabled() {
298
310
  static const auto method = javaClassStatic()->getMethod<jboolean()>("isAirplaneModeEnabled");
@@ -89,7 +89,7 @@ namespace margelo::nitro::nitrolocationtracking {
89
89
  PermissionStatus getLocationPermissionStatus() override;
90
90
  std::shared_ptr<Promise<PermissionStatus>> requestLocationPermission() override;
91
91
  void onPermissionStatusChange(const std::function<void(PermissionStatus /* status */)>& callback) override;
92
- void openLocationSettings(AccuracyLevel accuracy, double intervalMs) override;
92
+ std::shared_ptr<Promise<bool>> openLocationSettings() override;
93
93
  bool isAirplaneModeEnabled() override;
94
94
  void onAirplaneModeChange(const std::function<void(bool /* isEnabled */)>& callback) override;
95
95
  double getDistanceBetween(double lat1, double lon1, double lat2, double lon2) override;
@@ -229,7 +229,7 @@ abstract class HybridNitroLocationTrackingSpec: HybridObject() {
229
229
 
230
230
  @DoNotStrip
231
231
  @Keep
232
- abstract fun openLocationSettings(accuracy: AccuracyLevel, intervalMs: Double): Unit
232
+ abstract fun openLocationSettings(): Promise<Boolean>
233
233
 
234
234
  @DoNotStrip
235
235
  @Keep
@@ -330,11 +330,13 @@ namespace margelo::nitro::nitrolocationtracking {
330
330
  std::rethrow_exception(__result.error());
331
331
  }
332
332
  }
333
- inline void openLocationSettings(AccuracyLevel accuracy, double intervalMs) override {
334
- auto __result = _swiftPart.openLocationSettings(static_cast<int>(accuracy), std::forward<decltype(intervalMs)>(intervalMs));
333
+ inline std::shared_ptr<Promise<bool>> openLocationSettings() override {
334
+ auto __result = _swiftPart.openLocationSettings();
335
335
  if (__result.hasError()) [[unlikely]] {
336
336
  std::rethrow_exception(__result.error());
337
337
  }
338
+ auto __value = std::move(__result.value());
339
+ return __value;
338
340
  }
339
341
  inline bool isAirplaneModeEnabled() override {
340
342
  auto __result = _swiftPart.isAirplaneModeEnabled();
@@ -47,7 +47,7 @@ public protocol HybridNitroLocationTrackingSpec_protocol: HybridObject {
47
47
  func getLocationPermissionStatus() throws -> PermissionStatus
48
48
  func requestLocationPermission() throws -> Promise<PermissionStatus>
49
49
  func onPermissionStatusChange(callback: @escaping (_ status: PermissionStatus) -> Void) throws -> Void
50
- func openLocationSettings(accuracy: AccuracyLevel, intervalMs: Double) throws -> Void
50
+ func openLocationSettings() throws -> Promise<Bool>
51
51
  func isAirplaneModeEnabled() throws -> Bool
52
52
  func onAirplaneModeChange(callback: @escaping (_ isEnabled: Bool) -> Void) throws -> Void
53
53
  func getDistanceBetween(lat1: Double, lon1: Double, lat2: Double, lon2: Double) throws -> Double
@@ -576,13 +576,21 @@ open class HybridNitroLocationTrackingSpec_cxx {
576
576
  }
577
577
 
578
578
  @inline(__always)
579
- public final func openLocationSettings(accuracy: Int32, intervalMs: Double) -> bridge.Result_void_ {
579
+ public final func openLocationSettings() -> bridge.Result_std__shared_ptr_Promise_bool___ {
580
580
  do {
581
- try self.__implementation.openLocationSettings(accuracy: margelo.nitro.nitrolocationtracking.AccuracyLevel(rawValue: accuracy)!, intervalMs: intervalMs)
582
- return bridge.create_Result_void_()
581
+ let __result = try self.__implementation.openLocationSettings()
582
+ let __resultCpp = { () -> bridge.std__shared_ptr_Promise_bool__ in
583
+ let __promise = bridge.create_std__shared_ptr_Promise_bool__()
584
+ let __promiseHolder = bridge.wrap_std__shared_ptr_Promise_bool__(__promise)
585
+ __result
586
+ .then({ __result in __promiseHolder.resolve(__result) })
587
+ .catch({ __error in __promiseHolder.reject(__error.toCpp()) })
588
+ return __promise
589
+ }()
590
+ return bridge.create_Result_std__shared_ptr_Promise_bool___(__resultCpp)
583
591
  } catch (let __error) {
584
592
  let __exceptionPtr = __error.toCpp()
585
- return bridge.create_Result_void_(__exceptionPtr)
593
+ return bridge.create_Result_std__shared_ptr_Promise_bool___(__exceptionPtr)
586
594
  }
587
595
  }
588
596
 
@@ -35,8 +35,6 @@ namespace margelo::nitro::nitrolocationtracking { struct TripStats; }
35
35
  namespace margelo::nitro::nitrolocationtracking { enum class LocationProviderStatus; }
36
36
  // Forward declaration of `PermissionStatus` to properly resolve imports.
37
37
  namespace margelo::nitro::nitrolocationtracking { enum class PermissionStatus; }
38
- // Forward declaration of `AccuracyLevel` to properly resolve imports.
39
- namespace margelo::nitro::nitrolocationtracking { enum class AccuracyLevel; }
40
38
 
41
39
  #include "LocationConfig.hpp"
42
40
  #include "LocationData.hpp"
@@ -52,7 +50,6 @@ namespace margelo::nitro::nitrolocationtracking { enum class AccuracyLevel; }
52
50
  #include "TripStats.hpp"
53
51
  #include "LocationProviderStatus.hpp"
54
52
  #include "PermissionStatus.hpp"
55
- #include "AccuracyLevel.hpp"
56
53
 
57
54
  namespace margelo::nitro::nitrolocationtracking {
58
55
 
@@ -119,7 +116,7 @@ namespace margelo::nitro::nitrolocationtracking {
119
116
  virtual PermissionStatus getLocationPermissionStatus() = 0;
120
117
  virtual std::shared_ptr<Promise<PermissionStatus>> requestLocationPermission() = 0;
121
118
  virtual void onPermissionStatusChange(const std::function<void(PermissionStatus /* status */)>& callback) = 0;
122
- virtual void openLocationSettings(AccuracyLevel accuracy, double intervalMs) = 0;
119
+ virtual std::shared_ptr<Promise<bool>> openLocationSettings() = 0;
123
120
  virtual bool isAirplaneModeEnabled() = 0;
124
121
  virtual void onAirplaneModeChange(const std::function<void(bool /* isEnabled */)>& callback) = 0;
125
122
  virtual double getDistanceBetween(double lat1, double lon1, double lat2, double lon2) = 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-nitro-location-tracking",
3
- "version": "0.1.13",
3
+ "version": "0.1.14",
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",
@@ -149,7 +149,21 @@ export interface NitroLocationTracking
149
149
  getLocationPermissionStatus(): PermissionStatus;
150
150
  requestLocationPermission(): Promise<PermissionStatus>;
151
151
  onPermissionStatusChange(callback: PermissionStatusCallback): void;
152
- openLocationSettings(accuracy: AccuracyLevel, intervalMs: number): void;
152
+ /**
153
+ * Prompt the user to enable device location (GPS).
154
+ *
155
+ * On Android this shows the native Google Play Services in-app resolution
156
+ * dialog ("For better experience, turn on device location…"). The promise
157
+ * resolves `true` if GPS is enabled (either because it already was, or
158
+ * because the user accepted the dialog), and `false` if the user declined
159
+ * or the dialog could not be shown.
160
+ *
161
+ * On iOS there is no in-app dialog for enabling location services, so this
162
+ * opens the app's Settings page. The promise resolves after the app
163
+ * returns to foreground: `true` if `locationServicesEnabled()` is now on,
164
+ * `false` otherwise.
165
+ */
166
+ openLocationSettings(): Promise<boolean>;
153
167
 
154
168
  // === Device State Monitoring ===
155
169
  isAirplaneModeEnabled(): boolean;