Skip to content

Fix boot start: run the boost in a foreground service instead of launching the UI#13

Open
dilbery wants to merge 3 commits into
AumGupta:masterfrom
dilbery:feat/boot-foreground-service
Open

Fix boot start: run the boost in a foreground service instead of launching the UI#13
dilbery wants to merge 3 commits into
AumGupta:masterfrom
dilbery:feat/boot-foreground-service

Conversation

@dilbery

@dilbery dilbery commented Jul 18, 2026

Copy link
Copy Markdown

Problem

The boot-start feature added in #12 launches MainActivity directly from the BOOT_COMPLETED broadcast. That has two problems:

  1. It silently does nothing on Android 10+. Activity launches from background broadcast receivers are blocked since Android 10 (background activity start restrictions), so on any modern device the "start on boot" toggle has no effect — no error, just nothing.
  2. The boost dies with the UI. The audio effects (LoudnessEnhancer / DynamicsProcessing) are released in MainActivity.onDestroy(), so as soon as the activity is destroyed (user swipes the app away, or the OS reclaims it) the boost is gone — even though the app asks for a battery-optimization exemption to "run in the background".

Even on devices where the activity launch works (≤ Android 9), booting into the full BoostX UI is intrusive — e.g. on wall-mounted tablets/displays it covers whatever the device is supposed to be showing.

Fix

Move the boost into a foreground service (BoostService) that owns the audio effects:

  • BootReceiver now starts the service (via ContextCompat.startForegroundService) instead of launching the activity. Works on all API levels ≥ minSdk 24, no UI shown. Also handles the HTC variant of the quickboot action.
  • BoostService restores the saved boost + volume on start, holds the effects with a persistent low-priority notification, and is START_STICKY.
  • The service declares foreground type specialUse (API 34+) rather than mediaPlayback, because Android 15 disallows starting mediaPlayback-type foreground services from BOOT_COMPLETED, which would have broken boot-start again on current devices.
  • AudioController is now a singleton shared by the activity and the service, so they don't create two competing sets of global (session 0) effects.
  • MainActivity starts the service whenever boost > 0 or boot-start is enabled, stops it when neither applies, and only releases the effects if the service isn't running.
  • POST_NOTIFICATIONS is requested on API 33+ so the service notification is visible; new strings are provided in English and Dutch.

Second commit: settings are now persisted immediately when changed (previously only in onPause(), so a crash or force-stop lost the boot-start toggle and boost level).

Testing

  • Built with AGP 9.2.1 / compileSdk 35 (assembleDebug clean).
  • End-to-end on a Lenovo StarView (Android 8.1 / API 27): set boost 60% + boot-start, rebooted the device — the service came up on boot as a foreground service with its persistent notification (dumpsys: isForeground=true, createdFromFg=false) and the LoudnessEnhancer attached to global session 0, without the app UI ever opening.

dilbery and others added 3 commits July 18, 2026 14:00
…ves the UI

The previous boot-start implementation launched MainActivity from
BOOT_COMPLETED, which Android 10+ blocks for background processes (the
toggle silently did nothing), and the audio effects were released in
MainActivity.onDestroy(), so the boost died as soon as the activity was
destroyed.

- New BoostService: a foreground service (specialUse type on API 34+,
  which unlike mediaPlayback is still allowed to start from
  BOOT_COMPLETED on Android 15) that restores the saved boost/volume and
  keeps the effects alive with a persistent low-priority notification.
- BootReceiver now starts the service instead of the activity, and also
  handles the HTC quickboot action.
- AudioController is a singleton so the activity and service share the
  same global effect instances instead of fighting over session 0.
- MainActivity starts/stops the service (boost active or boot start
  enabled -> running) and only releases the effects when the service
  is not running.
- Request POST_NOTIFICATIONS on API 33+ so the service notification is
  visible; new strings provided in English and Dutch.
Settings were only saved in onPause(), so a crash or force stop lost
the boost level and the boot-start toggle. Save each preference as soon
as the user changes it; the bulk save in onPause() remains as a
backstop.
The foreground service changes user-visible behaviour (a persistent
notification, boost surviving the UI), so describe what to expect and
why the notification is there.

Also add a troubleshooting note for system equalizers such as LineageOS'
AudioFX: they attach an effect to the music app's session, which makes
AudioFlinger suspend global session 0 effects, silently disabling the
boost while the UI still shows it as applied.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DoGGpGCCn5126qgQYpZN8Y
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant