GpsContextAdapter class

Receives location updates from the host app's existing GPS pipeline and exposes a coarse MovementContext stream. Morph never requests location permission itself — the dev pipes their own Position updates in via onLocationUpdate.

Threshold mapping — speeds are in km/h. Hysteresis bands prevent oscillation at the boundaries: each mode has an entry threshold (the speed it takes to flip into the mode) higher than its exit threshold (the speed it takes to flip out). A user steady at 7 km/h won't flicker between walking and cycling on every fix.

• stationary entry: < 1.5 exit: ≥ 2.5 • walking entry: ≥ 2.5 exit: ≥ 8 (up) or < 1.5 (down) • cycling entry: ≥ 8 exit: ≥ 27 (up) or < 6 (down) • vehicle entry: ≥ 27 exit: < 23

Accuracy gate. Updates with accuracy > 50m don't drive classification on their own — they trigger the tunnel-mode path described below.

Tunnel mode. When a series of updates arrive with degraded accuracy (or no updates arrive at all), the adapter keeps emitting the last good context for tunnelGracePeriod. Past that, it falls back to MovementContext.unknown. Going through a tunnel or under a bridge no longer pops the UI back to a default state.

Accelerometer fallback. When the adapter is start()ed it also subscribes to the accelerometer. If GPS reports stationary but the accelerometer detects sustained train-like vibration for _vibrationConfirmWindow, the emitted context is upgraded to vehicle. Useful in metros, trains, and underground parking where GPS is unreliable for minutes at a time.

Constructors

GpsContextAdapter()

Properties

currentContext MovementContext
no setter
hashCode int
The hash code for this object.
no setterinherited
isHoldingThroughTunnel bool
True when the most recent emit was driven by the tunnelGracePeriod held over a degraded-accuracy update.
no setter
runtimeType Type
A representation of the runtime type of the object.
no setterinherited
stream Stream<MovementContext>
no setter

Methods

noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
onLocationUpdate({required double speedKmh, required double accuracy}) → void
Pipe an update from your existing GPS subscription. The dev does:
start() → void
Subscribes to the accelerometer for the train-detection fallback. Idempotent — calling twice is a no-op.
stop() → void
toString() String
A string representation of this object.
inherited

Operators

operator ==(Object other) bool
The equality operator.
inherited

Constants

tunnelGracePeriod → const Duration
How long after the last good fix the adapter keeps reporting the previous context before falling back to MovementContext.unknown. Tuned for typical urban tunnels (~10–20s) plus a margin.