Skip to content

Build1 publisher3 min readPublished

Geofencing beats GPS polling on power, then loses to the OEM battery optimiser

A developer's build log on auto-silencing an Android phone by location shows the real constraint is not logic but wake-ups, and that even event-driven triggers can be suppressed.

The Engineer · Build desk

Drafted by a language model from the sources cited here and checked against its claim ledger before publication. How we use AISend a correction

What happened

  • The author's motivation was an incident in which a phone rang loudly during a Jumu'ah khutbah, causing the owner to scramble to silence it.
  • Android provides AudioManager and NotificationManager, but the author describes them as reactive tools that require manual input.
  • The author tried standard alarm-based triggers but found they lacked the spatial awareness he needed.
  • According to the author, most existing solutions rely on heavy GPS polling, which drains the battery within hours, and they treat location services as a raw stream of coordinate data rather than a state-based trigger.
  • The author adopted GeofencingClient within the Google Play Services location APIs, which pushes the heavy lifting to the OS level and uses a combination of Wi-Fi, cell tower and GPS data, optimised by the system to wake the application only when a transition boundary is crossed.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

A developer publishing on dev.to has written up how he rebuilt an Android app that switches the ringer profile by location, and the useful part is the failure mode: most implementations of this idea die on battery, not on logic, because they treat location as a raw coordinate stream to be polled rather than a state to be notified about [4]. Anyone shipping context-aware phone behaviour is really shipping a negotiation with the operating system's power policy, and that negotiation has terms the API documentation does not cover [13][15].

The origin story is mundane and therefore credible: a ringtone going off during a Jumu'ah khutbah, and the recognition that Android's AudioManager and NotificationManager are reactive tools that need a human to remember to use them [1][2]. Time-based alarms were tried and discarded for lacking spatial awareness [3]. The naive fix is a LocationListener firing every few seconds, which the author says drains the battery within hours [6][4].

The architectural move is to stop asking and start being told. He switched to GeofencingClient in the Google Play Services location APIs, which pushes the work down to the OS, fuses Wi-Fi, cell tower and GPS signals, and wakes the app only when a boundary is crossed [5]. In wake-up terms that is the whole argument: continuous sampling at a few seconds per fix becomes roughly one wake-up per transition [17].

The second-order problem is process death. Registration is made with a PendingIntent, so the trigger is held by the Play Services process rather than the app's, and the OS delivers to a BroadcastReceiver which starts a ForegroundService to toggle AudioManager [8][9]. The ForegroundService exists to satisfy Android's background execution limits [7]. The request sets INITIAL_TRIGGER_ENTER so a device already inside a fence is handled at registration [11]. FLAG_IMMUTABLE is used deliberately, to stop another app rewriting the intent extras and triggering silent mode maliciously [10]. That is a sensible threat model for a feature whose whole job is turning off your alerts.

None of it survives contact with vendor battery optimisation. The author assumed a registered geofence would fire regardless of device state and reports he was wrong: on some manufacturers, aggressive optimisation suppressed the transition until the user woke the screen, which defeats the point of an automatic profile [12][13]. He spent three weeks working out why the exit event never fired while the phone was in his pocket, traced it to WorkManager interaction, and ended up having to push the app to be exempted from battery optimisation [14][15]. So the reliability risk moves from code he controls to policy he does not: the API promises a wake-up on transition, the OEM decides whether you get it [18].

Two things to watch. First, whether an app like this can be shipped without an exemption prompt, because a permission request that asks a user to disable battery optimisation is a conversion cliff and an OEM-by-OEM support problem [15][13]. Second, observability: the author's own retrospective is that he would build a user-visible log of state transitions instead of relying on logcat, having lost days to that gap [16]. For event-driven spatial triggers, an event that silently does not arrive is indistinguishable from a bug in your logic, and that is the cost centre.

Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories