react-native-nitro-location-tracking 0.1.6 → 0.1.8
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/android/src/main/java/com/margelo/nitro/nitrolocationtracking/LocationEngine.kt +8 -9
- package/android/src/main/java/com/margelo/nitro/nitrolocationtracking/NativeDBWriter.kt +61 -53
- package/android/src/main/java/com/margelo/nitro/nitrolocationtracking/NitroLocationTracking.kt +70 -7
- package/ios/LocationEngine.swift +46 -8
- package/ios/NativeDBWriter.swift +2 -1
- package/ios/NitroLocationTracking.swift +30 -5
- package/lib/typescript/src/NitroLocationTracking.nitro.d.ts +1 -0
- package/lib/typescript/src/NitroLocationTracking.nitro.d.ts.map +1 -1
- package/nitrogen/generated/android/c++/JHybridNitroLocationTrackingSpec.cpp +16 -0
- package/nitrogen/generated/android/c++/JHybridNitroLocationTrackingSpec.hpp +1 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrolocationtracking/HybridNitroLocationTrackingSpec.kt +4 -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 +8 -0
- package/nitrogen/generated/ios/swift/Func_void_PermissionStatus.swift +46 -0
- package/nitrogen/generated/ios/swift/HybridNitroLocationTrackingSpec.swift +1 -0
- package/nitrogen/generated/ios/swift/HybridNitroLocationTrackingSpec_cxx.swift +19 -0
- package/nitrogen/generated/shared/c++/HybridNitroLocationTrackingSpec.cpp +1 -0
- package/nitrogen/generated/shared/c++/HybridNitroLocationTrackingSpec.hpp +1 -0
- package/package.json +2 -2
- package/src/NitroLocationTracking.nitro.ts +14 -10
|
@@ -9,7 +9,6 @@ import android.os.Looper
|
|
|
9
9
|
import android.provider.Settings
|
|
10
10
|
import android.util.Log
|
|
11
11
|
import com.google.android.gms.location.*
|
|
12
|
-
import kotlin.coroutines.resume
|
|
13
12
|
|
|
14
13
|
class LocationEngine(private val context: Context) {
|
|
15
14
|
companion object {
|
|
@@ -23,7 +22,7 @@ class LocationEngine(private val context: Context) {
|
|
|
23
22
|
var onLocation: ((LocationData) -> Unit)? = null
|
|
24
23
|
var onMotionChange: ((Boolean) -> Unit)? = null
|
|
25
24
|
var dbWriter: NativeDBWriter? = null
|
|
26
|
-
var currentRideId: String? = null
|
|
25
|
+
// var currentRideId: String? = null
|
|
27
26
|
var rejectMockLocations: Boolean = false
|
|
28
27
|
val speedMonitor = SpeedMonitor()
|
|
29
28
|
val tripCalculator = TripCalculator()
|
|
@@ -82,13 +81,13 @@ class LocationEngine(private val context: Context) {
|
|
|
82
81
|
}
|
|
83
82
|
}
|
|
84
83
|
|
|
85
|
-
suspend fun getCurrentLocationSuspend(): LocationData? {
|
|
86
|
-
return kotlin.coroutines.suspendCoroutine { cont ->
|
|
87
|
-
getCurrentLocation { data ->
|
|
88
|
-
cont.resume(data)
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
84
|
+
// suspend fun getCurrentLocationSuspend(): LocationData? {
|
|
85
|
+
// return kotlin.coroutines.suspendCoroutine { cont ->
|
|
86
|
+
// getCurrentLocation { data ->
|
|
87
|
+
// cont.resume(data)
|
|
88
|
+
// }
|
|
89
|
+
// }
|
|
90
|
+
// }
|
|
92
91
|
|
|
93
92
|
private fun processLocation(location: Location) {
|
|
94
93
|
val data = locationToData(location)
|
|
@@ -7,10 +7,11 @@ import android.database.sqlite.SQLiteOpenHelper
|
|
|
7
7
|
import java.util.UUID
|
|
8
8
|
|
|
9
9
|
class NativeDBWriter(context: Context) :
|
|
10
|
-
|
|
10
|
+
SQLiteOpenHelper(context, "nitro_location.db", null, 1) {
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
override fun onCreate(db: SQLiteDatabase) {
|
|
13
|
+
db.execSQL(
|
|
14
|
+
"""
|
|
14
15
|
CREATE TABLE IF NOT EXISTS locations (
|
|
15
16
|
id TEXT PRIMARY KEY,
|
|
16
17
|
latitude REAL NOT NULL, longitude REAL NOT NULL,
|
|
@@ -19,62 +20,69 @@ class NativeDBWriter(context: Context) :
|
|
|
19
20
|
synced INTEGER DEFAULT 0, retry_count INTEGER DEFAULT 0,
|
|
20
21
|
created_at INTEGER DEFAULT (strftime('%s','now') * 1000)
|
|
21
22
|
)
|
|
22
|
-
"""
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
"""
|
|
24
|
+
)
|
|
25
|
+
db.execSQL("CREATE INDEX IF NOT EXISTS idx_locations_synced ON locations(synced)")
|
|
26
|
+
db.execSQL("CREATE INDEX IF NOT EXISTS idx_locations_timestamp ON locations(timestamp)")
|
|
27
|
+
db.execSQL("CREATE INDEX IF NOT EXISTS idx_locations_ride_id ON locations(ride_id)")
|
|
28
|
+
db.execSQL("PRAGMA journal_mode = WAL")
|
|
29
|
+
}
|
|
28
30
|
|
|
29
|
-
|
|
31
|
+
override fun onUpgrade(db: SQLiteDatabase, old: Int, new: Int) {}
|
|
30
32
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
33
|
+
fun insert(location: LocationData, rideId: String? = null) {
|
|
34
|
+
writableDatabase.insert("locations", null, ContentValues().apply {
|
|
35
|
+
put("id", UUID.randomUUID().toString())
|
|
36
|
+
put("latitude", location.latitude)
|
|
37
|
+
put("longitude", location.longitude)
|
|
38
|
+
put("altitude", location.altitude)
|
|
39
|
+
put("speed", location.speed)
|
|
40
|
+
put("bearing", location.bearing)
|
|
41
|
+
put("accuracy", location.accuracy)
|
|
42
|
+
put("timestamp", location.timestamp.toLong())
|
|
43
|
+
put("ride_id", rideId)
|
|
44
|
+
put("synced", 0)
|
|
45
|
+
})
|
|
46
|
+
}
|
|
45
47
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
48
|
+
fun getUnsyncedBatch(limit: Int): List<Pair<String, LocationData>> {
|
|
49
|
+
val list = mutableListOf<Pair<String, LocationData>>()
|
|
50
|
+
readableDatabase.query(
|
|
51
|
+
"locations", null, "synced = 0",
|
|
52
|
+
null, null, null, "timestamp ASC", "$limit"
|
|
53
|
+
).use {
|
|
54
|
+
while (it.moveToNext()) {
|
|
55
|
+
val id = it.getString(it.getColumnIndexOrThrow("id"))
|
|
56
|
+
val data = LocationData(
|
|
57
|
+
latitude = it.getDouble(it.getColumnIndexOrThrow("latitude")),
|
|
58
|
+
longitude = it.getDouble(it.getColumnIndexOrThrow("longitude")),
|
|
59
|
+
altitude = it.getDouble(it.getColumnIndexOrThrow("altitude")),
|
|
60
|
+
speed = it.getDouble(it.getColumnIndexOrThrow("speed")),
|
|
61
|
+
bearing = it.getDouble(it.getColumnIndexOrThrow("bearing")),
|
|
62
|
+
accuracy = it.getDouble(it.getColumnIndexOrThrow("accuracy")),
|
|
63
|
+
timestamp = it.getLong(it.getColumnIndexOrThrow("timestamp")).toDouble(),
|
|
64
|
+
isMockLocation = false
|
|
65
|
+
)
|
|
66
|
+
list.add(Pair(id, data))
|
|
67
|
+
}
|
|
65
68
|
}
|
|
69
|
+
return list
|
|
70
|
+
}
|
|
66
71
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
fun markSynced(ids: List<String>) {
|
|
73
|
+
val ph = ids.joinToString(",") { "?" }
|
|
74
|
+
writableDatabase.execSQL(
|
|
75
|
+
"UPDATE locations SET synced = 1 WHERE id IN ($ph)",
|
|
76
|
+
ids.toTypedArray()
|
|
77
|
+
)
|
|
78
|
+
}
|
|
73
79
|
|
|
74
|
-
|
|
75
|
-
|
|
80
|
+
fun clearOldSynced() {
|
|
81
|
+
writableDatabase.execSQL(
|
|
82
|
+
"""
|
|
76
83
|
DELETE FROM locations WHERE synced = 1
|
|
77
84
|
AND timestamp < (strftime('%s','now') * 1000 - 86400000)
|
|
78
|
-
"""
|
|
79
|
-
|
|
85
|
+
"""
|
|
86
|
+
)
|
|
87
|
+
}
|
|
80
88
|
}
|
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,66 @@ 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
|
+
|
|
286
349
|
// === Notifications ===
|
|
287
350
|
|
|
288
351
|
override fun showLocalNotification(title: String, body: String) {
|
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)?
|
|
@@ -45,6 +47,7 @@ class LocationEngine: NSObject, CLLocationManagerDelegate {
|
|
|
45
47
|
func start() {
|
|
46
48
|
guard CLLocationManager.authorizationStatus() == .authorizedAlways ||
|
|
47
49
|
CLLocationManager.authorizationStatus() == .authorizedWhenInUse else {
|
|
50
|
+
pendingStartAfterPermission = true
|
|
48
51
|
locationManager.requestAlwaysAuthorization()
|
|
49
52
|
return
|
|
50
53
|
}
|
|
@@ -52,10 +55,21 @@ class LocationEngine: NSObject, CLLocationManagerDelegate {
|
|
|
52
55
|
tracking = true
|
|
53
56
|
}
|
|
54
57
|
|
|
58
|
+
func requestPermission(completion: @escaping (CLAuthorizationStatus) -> Void) {
|
|
59
|
+
let currentStatus = CLLocationManager.authorizationStatus()
|
|
60
|
+
if currentStatus != .notDetermined {
|
|
61
|
+
completion(currentStatus)
|
|
62
|
+
return
|
|
63
|
+
}
|
|
64
|
+
pendingPermissionCompletion = completion
|
|
65
|
+
locationManager.requestAlwaysAuthorization()
|
|
66
|
+
}
|
|
67
|
+
|
|
55
68
|
func stop() {
|
|
56
69
|
locationManager.stopUpdatingLocation()
|
|
57
70
|
tracking = false
|
|
58
71
|
}
|
|
72
|
+
|
|
59
73
|
|
|
60
74
|
var isTracking: Bool { tracking }
|
|
61
75
|
|
|
@@ -80,11 +94,11 @@ class LocationEngine: NSObject, CLLocationManagerDelegate {
|
|
|
80
94
|
}
|
|
81
95
|
// Use a SEPARATE manager for one-shot requests so we never
|
|
82
96
|
// stop the continuous startUpdatingLocation() on locationManager.
|
|
83
|
-
|
|
97
|
+
pendingLocationCompletions.append(completion)
|
|
84
98
|
oneShotManager.requestLocation()
|
|
85
99
|
}
|
|
86
100
|
|
|
87
|
-
private var
|
|
101
|
+
private var pendingLocationCompletions: [(LocationData?) -> Void] = []
|
|
88
102
|
|
|
89
103
|
func locationManager(_ manager: CLLocationManager,
|
|
90
104
|
didUpdateLocations locations: [CLLocation]) {
|
|
@@ -104,9 +118,12 @@ class LocationEngine: NSObject, CLLocationManagerDelegate {
|
|
|
104
118
|
)
|
|
105
119
|
|
|
106
120
|
// Handle pending one-shot request (from oneShotManager)
|
|
107
|
-
if manager === oneShotManager
|
|
108
|
-
|
|
109
|
-
|
|
121
|
+
if manager === oneShotManager {
|
|
122
|
+
let completions = pendingLocationCompletions
|
|
123
|
+
pendingLocationCompletions.removeAll()
|
|
124
|
+
for completion in completions {
|
|
125
|
+
completion(data)
|
|
126
|
+
}
|
|
110
127
|
return
|
|
111
128
|
}
|
|
112
129
|
|
|
@@ -131,9 +148,12 @@ class LocationEngine: NSObject, CLLocationManagerDelegate {
|
|
|
131
148
|
|
|
132
149
|
func locationManager(_ manager: CLLocationManager,
|
|
133
150
|
didFailWithError error: Error) {
|
|
134
|
-
if manager === oneShotManager
|
|
135
|
-
|
|
136
|
-
|
|
151
|
+
if manager === oneShotManager {
|
|
152
|
+
let completions = pendingLocationCompletions
|
|
153
|
+
pendingLocationCompletions.removeAll()
|
|
154
|
+
for completion in completions {
|
|
155
|
+
completion(nil)
|
|
156
|
+
}
|
|
137
157
|
}
|
|
138
158
|
}
|
|
139
159
|
|
|
@@ -169,6 +189,24 @@ class LocationEngine: NSObject, CLLocationManagerDelegate {
|
|
|
169
189
|
|
|
170
190
|
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
|
|
171
191
|
guard manager === locationManager else { return }
|
|
192
|
+
|
|
193
|
+
let authStatus = CLLocationManager.authorizationStatus()
|
|
194
|
+
|
|
195
|
+
// Resolve pending permission request
|
|
196
|
+
if let completion = pendingPermissionCompletion {
|
|
197
|
+
pendingPermissionCompletion = nil
|
|
198
|
+
completion(authStatus)
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Auto-start tracking if permission was granted after start() was called
|
|
202
|
+
if pendingStartAfterPermission {
|
|
203
|
+
pendingStartAfterPermission = false
|
|
204
|
+
if authStatus == .authorizedAlways || authStatus == .authorizedWhenInUse {
|
|
205
|
+
locationManager.startUpdatingLocation()
|
|
206
|
+
tracking = true
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
172
210
|
let enabled = CLLocationManager.locationServicesEnabled()
|
|
173
211
|
let status: LocationProviderStatus = enabled ? .enabled : .disabled
|
|
174
212
|
providerStatusCallback?(status, status)
|
package/ios/NativeDBWriter.swift
CHANGED
|
@@ -85,7 +85,8 @@ class NativeDBWriter {
|
|
|
85
85
|
speed: sqlite3_column_double(stmt, 4),
|
|
86
86
|
bearing: sqlite3_column_double(stmt, 5),
|
|
87
87
|
accuracy: sqlite3_column_double(stmt, 6),
|
|
88
|
-
timestamp: Double(sqlite3_column_int64(stmt, 7))
|
|
88
|
+
timestamp: Double(sqlite3_column_int64(stmt, 7)),
|
|
89
|
+
isMockLocation:true // we need to check here
|
|
89
90
|
)
|
|
90
91
|
results.append((id: id, data: data))
|
|
91
92
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import Foundation
|
|
2
|
+
import CoreLocation
|
|
2
3
|
import NitroModules
|
|
3
4
|
|
|
4
5
|
class NitroLocationTracking: HybridNitroLocationTrackingSpec {
|
|
5
|
-
|
|
6
6
|
private let locationEngine = LocationEngine()
|
|
7
7
|
private let connectionManager = ConnectionManager()
|
|
8
8
|
private let dbWriter = NativeDBWriter()
|
|
@@ -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 permissionPromise: Promise<PermissionStatus>?
|
|
19
20
|
|
|
20
21
|
override init() {
|
|
21
22
|
super.init()
|
|
@@ -43,6 +44,7 @@ class NitroLocationTracking: HybridNitroLocationTrackingSpec {
|
|
|
43
44
|
locationEngine.stop()
|
|
44
45
|
}
|
|
45
46
|
|
|
47
|
+
|
|
46
48
|
func getCurrentLocation() throws -> Promise<LocationData> {
|
|
47
49
|
let promise = Promise<LocationData>()
|
|
48
50
|
locationEngine.getCurrentLocation { data in
|
|
@@ -57,7 +59,7 @@ class NitroLocationTracking: HybridNitroLocationTrackingSpec {
|
|
|
57
59
|
return promise
|
|
58
60
|
}
|
|
59
61
|
|
|
60
|
-
|
|
62
|
+
func isTracking() throws -> Bool {
|
|
61
63
|
return locationEngine.isTracking
|
|
62
64
|
}
|
|
63
65
|
|
|
@@ -197,20 +199,43 @@ class NitroLocationTracking: HybridNitroLocationTrackingSpec {
|
|
|
197
199
|
|
|
198
200
|
switch status {
|
|
199
201
|
case .notDetermined:
|
|
200
|
-
|
|
202
|
+
return .notdetermined
|
|
201
203
|
case .restricted:
|
|
202
204
|
return .restricted
|
|
203
205
|
case .denied:
|
|
204
206
|
return .denied
|
|
205
207
|
case .authorizedWhenInUse:
|
|
206
|
-
return .
|
|
208
|
+
return .wheninuse
|
|
207
209
|
case .authorizedAlways:
|
|
208
210
|
return .always
|
|
209
211
|
@unknown default:
|
|
210
|
-
return .
|
|
212
|
+
return .notdetermined
|
|
211
213
|
}
|
|
212
214
|
}
|
|
213
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
|
+
|
|
214
239
|
// MARK: - Notifications
|
|
215
240
|
|
|
216
241
|
func showLocalNotification(title: String, body: String) throws {
|
|
@@ -96,6 +96,7 @@ export interface NitroLocationTracking extends HybridObject<{
|
|
|
96
96
|
isLocationServicesEnabled(): boolean;
|
|
97
97
|
onProviderStatusChange(callback: ProviderStatusCallback): void;
|
|
98
98
|
getLocationPermissionStatus(): PermissionStatus;
|
|
99
|
+
requestLocationPermission(): Promise<PermissionStatus>;
|
|
99
100
|
showLocalNotification(title: string, body: string): void;
|
|
100
101
|
updateForegroundNotification(title: string, body: string): void;
|
|
101
102
|
destroy(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NitroLocationTracking.nitro.d.ts","sourceRoot":"","sources":["../../../src/NitroLocationTracking.nitro.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAI/D,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,UAAU,GAAG,KAAK,CAAC;AACxD,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,cAAc,GAAG,cAAc,CAAC;AAI5E,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,eAAe,EAAE,aAAa,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,OAAO,CAAC;IACzB,WAAW,EAAE,OAAO,CAAC;IACrB,2BAA2B,EAAE,MAAM,CAAC;IACpC,0BAA0B,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,gBAAgB,GAAG,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAC;AAChE,MAAM,MAAM,uBAAuB,GAAG,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;AACvE,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;AAExD,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,MAAM,CAAC;AAC7C,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;AAEhF,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,YAAY,GAAG,eAAe,CAAC;AACzE,MAAM,MAAM,kBAAkB,GAAG,
|
|
1
|
+
{"version":3,"file":"NitroLocationTracking.nitro.d.ts","sourceRoot":"","sources":["../../../src/NitroLocationTracking.nitro.ts"],"names":[],"mappings":"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"}
|
|
@@ -265,6 +265,22 @@ 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
|
+
}
|
|
268
284
|
void JHybridNitroLocationTrackingSpec::showLocalNotification(const std::string& title, const std::string& body) {
|
|
269
285
|
static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* title */, jni::alias_ref<jni::JString> /* body */)>("showLocalNotification");
|
|
270
286
|
method(_javaPart, jni::make_jstring(title), jni::make_jstring(body));
|
|
@@ -86,6 +86,7 @@ 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;
|
|
89
90
|
void showLocalNotification(const std::string& title, const std::string& body) override;
|
|
90
91
|
void updateForegroundNotification(const std::string& title, const std::string& body) override;
|
|
91
92
|
void destroy() override;
|
|
@@ -205,6 +205,10 @@ 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
|
+
|
|
208
212
|
@DoNotStrip
|
|
209
213
|
@Keep
|
|
210
214
|
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,14 @@ 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
|
+
}
|
|
313
321
|
inline void showLocalNotification(const std::string& title, const std::string& body) override {
|
|
314
322
|
auto __result = _swiftPart.showLocalNotification(title, body);
|
|
315
323
|
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,7 @@ 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>
|
|
47
48
|
func showLocalNotification(title: String, body: String) throws -> Void
|
|
48
49
|
func updateForegroundNotification(title: String, body: String) throws -> Void
|
|
49
50
|
func destroy() throws -> Void
|
|
@@ -524,6 +524,25 @@ 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
|
+
|
|
527
546
|
@inline(__always)
|
|
528
547
|
public final func showLocalNotification(title: std.string, body: std.string) -> bridge.Result_void_ {
|
|
529
548
|
do {
|
|
@@ -45,6 +45,7 @@ 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);
|
|
48
49
|
prototype.registerHybridMethod("showLocalNotification", &HybridNitroLocationTrackingSpec::showLocalNotification);
|
|
49
50
|
prototype.registerHybridMethod("updateForegroundNotification", &HybridNitroLocationTrackingSpec::updateForegroundNotification);
|
|
50
51
|
prototype.registerHybridMethod("destroy", &HybridNitroLocationTrackingSpec::destroy);
|
|
@@ -113,6 +113,7 @@ 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;
|
|
116
117
|
virtual void showLocalNotification(const std::string& title, const std::string& body) = 0;
|
|
117
118
|
virtual void updateForegroundNotification(const std::string& title, const std::string& body) = 0;
|
|
118
119
|
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.
|
|
3
|
+
"version": "0.1.8",
|
|
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",
|
|
@@ -171,4 +171,4 @@
|
|
|
171
171
|
],
|
|
172
172
|
"version": "0.57.2"
|
|
173
173
|
}
|
|
174
|
-
}
|
|
174
|
+
}
|
|
@@ -48,7 +48,7 @@ export interface GeofenceRegion {
|
|
|
48
48
|
id: string;
|
|
49
49
|
latitude: number;
|
|
50
50
|
longitude: number;
|
|
51
|
-
radius: number;
|
|
51
|
+
radius: number; // meters
|
|
52
52
|
notifyOnEntry: boolean;
|
|
53
53
|
notifyOnExit: boolean;
|
|
54
54
|
}
|
|
@@ -57,20 +57,23 @@ export type GeofenceEvent = 'enter' | 'exit';
|
|
|
57
57
|
export type GeofenceCallback = (event: GeofenceEvent, regionId: string) => void;
|
|
58
58
|
|
|
59
59
|
export interface SpeedConfig {
|
|
60
|
-
maxSpeedKmh: number;
|
|
61
|
-
minSpeedKmh: number;
|
|
62
|
-
checkIntervalMs: number;
|
|
60
|
+
maxSpeedKmh: number; // speed limit in km/h
|
|
61
|
+
minSpeedKmh: number; // minimum speed threshold
|
|
62
|
+
checkIntervalMs: number; // how often to evaluate
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
export type SpeedAlertType = 'exceeded' | 'normalized' | 'below_minimum';
|
|
66
|
-
export type SpeedAlertCallback = (
|
|
66
|
+
export type SpeedAlertCallback = (
|
|
67
|
+
alert: SpeedAlertType,
|
|
68
|
+
currentSpeedKmh: number
|
|
69
|
+
) => void;
|
|
67
70
|
|
|
68
71
|
export interface TripStats {
|
|
69
|
-
distanceMeters: number;
|
|
70
|
-
durationMs: number;
|
|
71
|
-
averageSpeedKmh: number;
|
|
72
|
-
maxSpeedKmh: number;
|
|
73
|
-
pointCount: number;
|
|
72
|
+
distanceMeters: number; // total distance traveled
|
|
73
|
+
durationMs: number; // elapsed time since start
|
|
74
|
+
averageSpeedKmh: number; // average speed
|
|
75
|
+
maxSpeedKmh: number; // peak speed recorded
|
|
76
|
+
pointCount: number; // number of location samples
|
|
74
77
|
}
|
|
75
78
|
|
|
76
79
|
export type LocationProviderStatus = 'enabled' | 'disabled';
|
|
@@ -140,6 +143,7 @@ export interface NitroLocationTracking
|
|
|
140
143
|
|
|
141
144
|
// === Permission Status ===
|
|
142
145
|
getLocationPermissionStatus(): PermissionStatus;
|
|
146
|
+
requestLocationPermission(): Promise<PermissionStatus>;
|
|
143
147
|
|
|
144
148
|
// === Notifications ===
|
|
145
149
|
showLocalNotification(title: string, body: string): void;
|