Broadcast Receivers
A receiver is a .wh file with no markup in src/receivers/. Whitehall
writes the BroadcastReceiver and its manifest entry.
A receiver
// src/receivers/+BootReceiver.wh
val on = ["BOOT_COMPLETED"]
val exported = true
fun onReceive() {
$dispatch(Startup.bringUpDaemon, constraints: ["network"])
} Options
Options are top-level vals, the way a SvelteKit route file declares export const prerender. The set is closed, so a misspelled option is a build
error rather than a receiver that silently never fires.
| Option | Meaning |
|---|---|
on | Intent actions to listen for. Required. |
exported | Whether the system and other apps can reach it. Defaults to false. |
permission | A permission the sender must hold. Uses the $permission names. |
A bare action is qualified for you — "BOOT_COMPLETED" becomes android.intent.action.BOOT_COMPLETED. Anything containing a dot is left alone, so
your own actions work as written:
val on = ["com.example.app.REPLY"] onReceive may not block
A receiver has ten seconds in the foreground and sixty in the background before Android reports an ANR. Whitehall owns this function body, so rather than let you write something that cannot finish, it refuses to compile it:
error: `BootReceiver.onReceive` may not block
= `Thread.sleep` sleeps on the broadcast thread
= a broadcast receiver has 60s before Android reports an ANR
= help: hand off and return -- `$dispatch(SomeWork)` Refused: Thread.sleep, runBlocking, $await, $fetch, a suspend fun declared in the same file, and a suspend onReceive.
Exported, and why it is checked
A system broadcast comes from outside your app, so a receiver that is not exported never fires — silently, with nothing at build or install time to tell you. Listening for a system action without exporting is an error rather than a default:
error: receiver `BootReceiver` listens for `android.intent.action.BOOT_COMPLETED`
but is not exported
= the system sends that broadcast, so an unexported receiver never fires
= help: add `val exported = true` Your own actions need no export, since the sender is the app itself.
Services
Services have no .wh equivalent yet. Write the Kotlin and drop it in src/android/, which is copied into the app's own package — see Project Structure.
See Also
- $dispatch / $periodic — where the work actually goes
- $permission — the permission names
permissionaccepts - $notify — a common thing to do on a broadcast