am broadcast
changes the deviceSends a broadcast intent, which is how SystemUI demo mode and other platform receivers are driven from a shell.
- Command
- adb shell am broadcast
- Commands
- Activities and intents (am)
- Risk
- changes the device
Syntax
am broadcast -a <action> [-e <key> <value>] […]Flags and arguments
| Token | Meaning |
|---|---|
| -a <action> | The broadcast action. |
| -e <key> <value> | One string extra. Repeatable. |
Examples
settings put global sysui_demo_allowed 1Open the gate first. SystemUI ignores every demo broadcast while this setting is off, which it is on a fresh phone.
am broadcast -a com.android.systemui.demo -e command enterEnter demo mode. This has to come before any other demo command.
am broadcast -a com.android.systemui.demo -e command notifications -e visible falseHide your own notification icons — the part that matters for a screenshot.
am broadcast -a com.android.systemui.demo -e command exitGive the status bar back to reality.
Reading the output
Sample output
Broadcasting: Intent { act=com.android.systemui.demo (has extras) }
Broadcast completed: result=0`Broadcast completed: result=0` means the intent was delivered. It does **not** mean anything acted on it: a receiver is free to ignore the broadcast, which is exactly what SystemUI does while the demo gate is closed or when an OEM has removed the receiver. Confirm by looking at the phone, not at this line.
Output fields
| Field | Meaning |
|---|---|
| Broadcasting: Intent { … } | The intent as the platform parsed it. |
| Broadcast completed: result=0 | Delivered. Not proof that anything responded. |
| Permission Denial | The shell user may not send that broadcast on this build. |
What access it needs
Nothing beyond an authorised `adb` connection — no root, no `adb root`, no `su`, and no developer-options switch past USB debugging itself. `am` is a five-line shell script (AOSP `cmds/am/am.sh`) that hands everything except `instrument` to `cmd activity "$@"`, so the intent is sent with the identity of the `shell` user. What that identity cannot do is send a **protected** broadcast: `ActivityManagerService` counts only `ROOT_UID`, `SYSTEM_UID`, `PHONE_UID`, `BLUETOOTH_UID`, `NFC_UID`, `SE_UID` and `NETWORK_STACK_UID` as system callers, shell is none of them, and any action some package declared with `<protected-broadcast>` is refused before delivery. `com.android.systemui.demo` is not on that list, which is the only reason demo mode works from a cable at all — and the demo gate is a separate thing from the permission, a Global setting you write with `settings put`, not a capability you are granted. Two more things about the identity are worth knowing before you script this. The call blocks: without `--async`, `runSendBroadcast` waits on an untimed `wait()` inside its result receiver, so a receiver that never completes leaves the shell hanging rather than returning an error. And the interesting lines are split across both streams — the refusal below arrives on stderr while a subcommand typo arrives on stdout — so collect with `2>&1` and read the first line before believing a clean-looking run.
Failure messages, decoded
| Message | Meaning |
|---|---|
| Permission Denial: not allowed to send broadcast android.intent.action.BOOT_COMPLETED from pid=4821, uid=2000 | A `SecurityException` thrown by `ActivityManagerService` before any receiver saw the intent, because the action appears in some package's `<protected-broadcast>` list and the shell user is not a system caller. There is no flag that lifts this — not `--receiver-permission`, not `--user`, not root on a debuggable build. `dumpsys package protected-broadcasts` prints the whole list, so check there before assuming you mistyped the action. |
| Exception occurred while executing 'broadcast': | `BasicShellCommandHandler.exec` caught a `Throwable` and wrote a blank line, this banner and the stack trace to stderr. The line after it names the cause. `java.lang.IllegalArgumentException: Unknown option: --async` means the release does not know the flag — `--async` is absent from `ActivityManagerShellCommand` at tag android-11.0.0_r1 and present from android-12.0.0_r1 onward. `No intent supplied` means the `-a` action was left out entirely. |
| Unknown command: brodcast | `handleDefaultCommands` did not recognise the subcommand. Two traps in one line: it is printed on **stdout**, not stderr, so a script that only watches stderr records a clean run; and the return value is -1 while nothing at all was sent. Anything you were about to conclude from the phone's screen is about the previous state. |
| cmd: Can't find service: activity | `cmd` could not find the `activity` service to hand the subcommand to, so the broadcast was never enqueued. Expected while the device is still booting, before `system_server` has published it — wait for boot to finish and send it again rather than treating the device as broken. |
What it changes, and the way back
A broadcast itself changes nothing permanent, but what receives it can. SystemUI demo mode is the example worth naming: it freezes the status bar at a fake clock and a fake battery, and the phone stays that way until something sends the `exit` command — leaving a user convinced their phone is broken. Always keep the exit command to hand.
Version and vendor notes
- Demo mode is gated by `global sysui_demo_allowed`, and it is 0 by default. Probe the setting rather than firing broadcasts into the void.
- `enter` must be the first demo command; the others are ignored without it.
We have a UI for this
Android ADB Toolbox runs this command over USB and parses what comes back — a Chromium browser, no SDK, nothing uploaded.
Related commands
Commands that turn up in the same session as am broadcast.
| Command | What it does |
|---|---|
| am start | Starts an activity by component or by intent — the fastest way to test whether a deep link resolves. |
| settings put | Writes a value into the settings provider — the mechanism behind most developer-options tricks. |
| screencap | Takes a screenshot, either to a file on the phone or to standard output as PNG. |
More Activities and intents (am) commands
| Command | What it does |
|---|---|
| am force-stop | Kills every process and service belonging to one app. |
Checked against AOSP, toybox and kernel sources while writing the parsers behind our Web ADB tools. Where a behaviour genuinely varies by Android version or manufacturer, this page says so instead of giving a number that would be wrong on half the phones out there.