@tokamakdev/plugin-location 0.1.0-beta.104 → 0.1.0-beta.107
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 +7 -4
- package/android/LocationEvents.kt +9 -3
- package/android/LocationPlugin.kt +8 -4
- package/apple/LocationEvents.swift +10 -4
- package/package.json +2 -2
- package/src/types.ts +5 -2
package/README.md
CHANGED
|
@@ -127,9 +127,11 @@ event:
|
|
|
127
127
|
| `onLocationError` | `{ name, message, id? }` when a background service fails, with the region's `id` when it concerns one. |
|
|
128
128
|
|
|
129
129
|
`positions` holds the positions that arrived while the Worker handled the
|
|
130
|
-
previous update, oldest first, so a slow Worker never builds a queue.
|
|
131
|
-
|
|
132
|
-
|
|
130
|
+
previous update, oldest first, so a slow Worker never builds a queue. Each is
|
|
131
|
+
newer than those delivered before it, so a position that both updates and
|
|
132
|
+
significant changes report arrives once. Apple's `stationary`, from iOS 18
|
|
133
|
+
and macOS 15, is true on the last update before updates pause while the
|
|
134
|
+
device is still.
|
|
133
135
|
|
|
134
136
|
The plugin's `onLocationUpdate`, `onRegionTransition`, `onVisit` and
|
|
135
137
|
`onLocationError` methods receive the same events while the listening page or
|
|
@@ -175,7 +177,8 @@ plugin keeps them across launches and restarts.
|
|
|
175
177
|
macOS 27). It tunes when updates pause and how coordinates follow roads.
|
|
176
178
|
- Updates pause while the device is still and resume when it moves.
|
|
177
179
|
- If iOS ends the app while updates run, it launches the app for the next
|
|
178
|
-
update, and the plugin resumes them
|
|
180
|
+
update, and the plugin resumes them until `stopUpdates()`. With Always
|
|
181
|
+
permission, swiping the app away does not stop them either.
|
|
179
182
|
- Off screen, updates need Always permission, or the `background-updates`
|
|
180
183
|
build setting, whose background activity session shows the pill.
|
|
181
184
|
`startUpdates` rejects with `NeedsUIError` off screen on iOS.
|
|
@@ -23,6 +23,9 @@ internal class LocationEvents(private val host: TokamakHost) {
|
|
|
23
23
|
private val finishes = mutableListOf<() -> Unit>()
|
|
24
24
|
private var updating = false
|
|
25
25
|
|
|
26
|
+
/** The time of the newest position delivered, as requests that run together receive the same positions. */
|
|
27
|
+
private var latest = Long.MIN_VALUE
|
|
28
|
+
|
|
26
29
|
/** Adds a page's or Worker's listener of [method], returning its removal, or null for another method. */
|
|
27
30
|
fun listen(method: String, reply: TokamakPluginReply): (() -> Unit)? {
|
|
28
31
|
if (method !in LISTENERS) return null
|
|
@@ -32,11 +35,14 @@ internal class LocationEvents(private val host: TokamakHost) {
|
|
|
32
35
|
}
|
|
33
36
|
|
|
34
37
|
/**
|
|
35
|
-
* Delivers [received] positions, then calls [finish]. Positions
|
|
36
|
-
* handles an update reach it together as the next.
|
|
38
|
+
* Delivers the [received] positions newer than those delivered, then calls [finish]. Positions
|
|
39
|
+
* that arrive while the Worker handles an update reach it together as the next.
|
|
37
40
|
*/
|
|
38
41
|
fun update(received: List<JSONObject>, finish: () -> Unit) {
|
|
39
|
-
|
|
42
|
+
val newer = received.filter { it.getLong("timestamp") > latest }
|
|
43
|
+
if (newer.isEmpty()) return finish()
|
|
44
|
+
latest = newer.maxOf { it.getLong("timestamp") }
|
|
45
|
+
positions += newer
|
|
40
46
|
finishes += finish
|
|
41
47
|
if (!updating) sendUpdate()
|
|
42
48
|
}
|
|
@@ -53,6 +53,9 @@ class TokamakLocationPlugin(
|
|
|
53
53
|
private val regions = LocationRegions(context)
|
|
54
54
|
private val events = LocationEvents(host)
|
|
55
55
|
|
|
56
|
+
/** Whether the provider was on when last reported, as each request reports its changes. */
|
|
57
|
+
private var providerEnabled = true
|
|
58
|
+
|
|
56
59
|
/** Whether the app's manifest declares the foreground service, as the `background-updates` build setting does. */
|
|
57
60
|
private val declaresService: Boolean by lazy {
|
|
58
61
|
runCatching { context.packageManager.getServiceInfo(ComponentName(context, TokamakLocationService::class.java), 0) }
|
|
@@ -259,12 +262,13 @@ class TokamakLocationPlugin(
|
|
|
259
262
|
internal fun receive(intent: Intent, finish: () -> Unit) {
|
|
260
263
|
if (intent.action == LocationRegions.REGION_ACTION) return transition(intent, finish)
|
|
261
264
|
if (intent.hasExtra(LocationManager.KEY_PROVIDER_ENABLED)) {
|
|
262
|
-
|
|
265
|
+
val enabled = intent.getBooleanExtra(LocationManager.KEY_PROVIDER_ENABLED, true)
|
|
266
|
+
val turnedOff = providerEnabled && !enabled
|
|
267
|
+
providerEnabled = enabled
|
|
268
|
+
if (!turnedOff) return finish()
|
|
263
269
|
return events.fail(TokamakPluginError("NotReadableError", "The location provider was turned off"), finish)
|
|
264
270
|
}
|
|
265
|
-
|
|
266
|
-
if (received.isEmpty()) return finish()
|
|
267
|
-
events.update(received, finish)
|
|
271
|
+
events.update(locations(intent).map(::position), finish)
|
|
268
272
|
}
|
|
269
273
|
|
|
270
274
|
/** Delivers a region's entry or exit, when the region reports it. */
|
|
@@ -19,6 +19,9 @@ final class TokamakLocationEvents {
|
|
|
19
19
|
private var positions: [[String: Any]] = []
|
|
20
20
|
private var stationary: Bool?
|
|
21
21
|
private var updating = false
|
|
22
|
+
/// The time of the newest position delivered, as services that run together
|
|
23
|
+
/// report the same positions.
|
|
24
|
+
private var latest = Date.distantPast
|
|
22
25
|
/// The messages of the problems last reported, by region id, or nil for
|
|
23
26
|
/// updates.
|
|
24
27
|
private var problems: [String?: Set<String>] = [:]
|
|
@@ -37,11 +40,14 @@ final class TokamakLocationEvents {
|
|
|
37
40
|
}
|
|
38
41
|
}
|
|
39
42
|
|
|
40
|
-
/// Delivers `location
|
|
41
|
-
///
|
|
42
|
-
/// reach it together as the next.
|
|
43
|
+
/// Delivers `location` when it is newer than the positions delivered, with
|
|
44
|
+
/// Apple's `stationary` flag when the system reports it. Positions that
|
|
45
|
+
/// arrive while the Worker handles an update reach it together as the next.
|
|
43
46
|
func update(_ location: CLLocation?, stationary: Bool? = nil) {
|
|
44
|
-
|
|
47
|
+
if let location, location.timestamp > latest {
|
|
48
|
+
latest = location.timestamp
|
|
49
|
+
positions.append(Self.position(location))
|
|
50
|
+
}
|
|
45
51
|
if let stationary {
|
|
46
52
|
self.stationary = stationary
|
|
47
53
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tokamakdev/plugin-location",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.107",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/mantty/tokamak.git",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"./events": "./events/index.ts"
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
|
-
"@tokamakdev/plugin": "0.1.0-beta.
|
|
15
|
+
"@tokamakdev/plugin": "0.1.0-beta.107"
|
|
16
16
|
},
|
|
17
17
|
"files": [
|
|
18
18
|
"android",
|
package/src/types.ts
CHANGED
|
@@ -112,11 +112,14 @@ export interface ServiceNotification {
|
|
|
112
112
|
|
|
113
113
|
/** Positions from continuous updates or significant changes. */
|
|
114
114
|
export interface LocationUpdate {
|
|
115
|
-
/**
|
|
115
|
+
/**
|
|
116
|
+
* Oldest first: those that arrived while the Worker handled the previous update come together. Each
|
|
117
|
+
* is newer than those delivered before it, so one that several services report arrives once.
|
|
118
|
+
*/
|
|
116
119
|
readonly positions: readonly Position[];
|
|
117
120
|
/**
|
|
118
121
|
* Apple only, from iOS 18 and macOS 15: true on the last update before updates pause while the
|
|
119
|
-
* device is still. `positions` is empty when the update has no position.
|
|
122
|
+
* device is still. `positions` is empty when the update has no new position.
|
|
120
123
|
*/
|
|
121
124
|
readonly stationary?: boolean;
|
|
122
125
|
}
|