Watch observability
Use getActiveWatches() to inspect the Modern API watches that currently own
native position or heading subscriptions:
getActiveWatches() is a synchronous, point-in-time snapshot. It does not
request permission, start a provider, retain callbacks, or subscribe to future
changes. Entries are sorted by token and contain:
token: the value accepted byunwatch().kind:positionforwatchPosition()orheadingforwatchHeading().
The snapshot covers the Modern API root import. It does not include Compat API
watches, one-shot position or heading requests, or Background Location.
Android watches that finish because of maxUpdates disappear from the next
snapshot automatically. Web snapshots include active browser position watches;
unsupported web heading requests are not reported as active.
Cleanup semantics
unwatch(token)removes a matching position or heading watch. Repeating it, or passing an unknown token, is safe and has no effect.stopObserving()removes every Modern API position and heading watch, including development-tool and browser watches. It does not cancel one-shot position requests or Background Location. On iOS it also leaves one-shot heading requests running. On Android, the current native heading manager discards pending one-shot heading requests and their timeouts without invoking a callback; avoid callingstopObserving()whilegetHeading()is pending.useWatchPosition()owns its token and callsunwatch()during React effect cleanup. Low-levelwatchPosition()callers own cleanup themselves.- On Android, adding or removing a position watch restarts the one shared native
position request when another watch remains. On iOS, it reconfigures the
shared
CLLocationManager; it restarts only when the selected Core Location mode changes.
Current native merge policy
Multiple position watches share native resources. Options are merged to serve the most demanding active consumers; this is observable behavior, not a new Watch Manager policy.
Android
Active position watches share one Fused Location or platform request. The native request uses:
- the most demanding accuracy;
- the smallest
interval,fastestInterval,distanceFilter,maxUpdateAge, andmaxUpdateDelayvalues; waitForAccurateLocationwhen any watch requests it;- coarse granularity when any watch explicitly requires coarse, otherwise fine when any watch explicitly requires fine, otherwise permission granularity.
maxUpdates remains per subscription. Reaching the limit removes only that
watch, then stops or restarts the shared request as needed. Heading watches use
the Android sensor manager separately and apply each subscription's
headingFilter independently.
iOS
Position watches and pending one-shot position requests share one
CLLocationManager. The manager uses:
- the most precise requested accuracy and smallest distance filter;
- the highest-ranked activity type used by the current implementation;
- automatic pausing only when every explicit preference allows it;
- the background indicator or significant-change mode when any consumer asks for it.
Changing significant-change mode stops and restarts Core Location. Other position option changes reconfigure the existing manager. Heading watches share the same manager's heading sensor separately and use the smallest active heading filter.
Web
Each position watch maps to its own navigator.geolocation.watchPosition()
call. Browser watches are not merged. The package applies each watch's
distanceFilter in JavaScript.
