Geofencing Under Uncertainty
A first-principles look at the three challenges of on-device geofencing: sensor noise, state stability, and the energy budget.
On this page
Geofencing is the problem of deciding when a user enters or leaves a geographic boundary using only the phone’s GPS. At first glance it sounds simple: compare distance to radius and you’re done. But GPS doesn’t give you the truth. It gives you a number with error bars, and that changes everything.
The Three Challenges
On-device geofencing has three distinct problems to solve. Each is independent of the others, and each has a clean, derived solution.
1. Measurement uncertainty. The reported coordinate is not the true position. Accuracy varies with sky visibility, satellite geometry, and multipath, from ±5 meters in the open to ±30 meters between buildings. A hard decision boundary against a noisy input produces an unstable output: the state flickers on every new reading.
2. State stability. Even with a softened boundary, a single jump can cause a false crossing. Physical movement near a boundary is continuous, but GPS readings are discrete and jittery. The system needs to distinguish between a genuine crossing and measurement noise.
3. The energy budget. Continuous GPS polling drains the battery in hours. But polling too infrequently means missing crossings entirely. The polling rate cannot be a fixed number; it must adapt to what the user is doing.
Handling Measurement Uncertainty
Every GPS fix comes with an estimated error radius. A fix with 8-meter accuracy means the true position is likely within an 8-meter circle of the reported coordinate.
This error estimate is useful information. Instead of comparing distance against a fixed radius, compare against an effective radius that grows with the uncertainty:
1effective_radius = physical_radius + (accuracy × 0.5)The factor 0.5 is a conservative heuristic, not a derived confidence bound. Android’s accuracy field is an opaque estimate from the chipset vendor; its statistical meaning varies by manufacturer. Half the uncertainty radius was a safe starting point that performed well during testing. A minimum floor of 5 meters prevents the boundary from collapsing when GPS reports an artificially perfect lock.
The result is a decision boundary that adapts automatically: tight when the signal is clean, looser when it’s not. The same coordinate that triggers “inside” on a clear day might not trigger it in a canyon, because the system knows the measurement is less reliable.
Achieving State Stability
The adaptive boundary catches most GPS drift, but it can’t eliminate the problem entirely. A sudden GPS jump (common when the phone switches satellite constellations or loses lock momentarily) can briefly push the coordinate across the boundary and back.
The fix is a temporal constraint: after any state transition, ignore further transitions for a short window. This is a standard debounce pattern, common wherever sensor readings drive state changes. A 30-second window was sufficient to suppress double-triggers during testing at pedestrian speeds: a practical choice, not a derived optimum.
Two rules now protect the state: a spatial rule that adapts the boundary to measurement quality, and a temporal rule that rejects transient crossings. Together they form a simple but effective state machine: no Kalman filter, no smoothing, just two derived constraints from the physics of GPS.
Managing the Energy Budget
GPS polling is the dominant battery drain in any location-aware app. The naive approach, poll at a fixed interval, fails symmetrically: a short interval drains the battery, a long interval misses events.
The solution is to tie the polling interval to the rate at which the situation can change. The quantity to estimate is: given the user’s current distance to the nearest boundary and their current speed, how long until they reach it?
1time_to_boundary = distance_to_nearest_edge / velocityThe polling interval is set to a fraction of this time, with a safety factor. When the user is far from any boundary and standing still, the interval stretches to minutes; the system knows nothing will change soon. When they are close to a boundary and moving, the interval drops to seconds.
GPS speed estimates have their own noise. When the sensor doesn’t return reliable speed data, the system falls back to the distance between the last two fixes divided by elapsed time: a coarse approximation, but adequate for this purpose.
When velocity is near zero, the adaptive interval stretches to its maximum, and the passive listener at 30-second intervals acts as the safety net. It catches coarse position changes (the user starting to move) before the next active poll.
Three power profiles set the upper and lower bounds for the interval, giving the user control over the battery trade-off, but the core logic, velocity-gated sampling, is the same regardless of profile.
The Pattern
The three challenges are independent, and the solutions are independent too. An adaptive boundary that accounts for measurement error. A debounce timer that rejects transient noise. A polling interval derived from the physics of motion. Each addresses a distinct failure mode of the naive geofence.
None of these techniques are novel or proprietary. They are the logical consequence of stating each problem clearly and asking what the minimum fix looks like. The result is a geofencing system that runs entirely on-device because once you solve the three challenges, there is nothing left to send to a server.
Caveats
The constants in this system, the 0.5× accuracy factor, the 5-meter floor, the 30-second debounce, were chosen empirically during testing on consumer Android devices, not derived from a formal uncertainty model. False-positive and false-negative rates are unknown. The system is designed for reliable everyday use, not certified detection accuracy. These numbers would likely need adjustment for different use cases: faster movement, larger fences, or stricter reliability requirements.