74

I've got BroadcastReceiver class:

public class IntentReceiver extends BroadcastReceiver {

    final String tag = "Intent Intercepter";

    @Override
    public void onReceive(Context context, Intent intent) {
        try {
            String data = intent.getStringExtra("sms_body");
            Log.i(tag, data);
            Toast.makeText(context, data.subSequence(0, data.length()), Toast.LENGTH_LONG).show();
        } catch (Exception e) {
            Toast.makeText(context, "Intercepted", Toast.LENGTH_LONG).show();
        }
    }
}

And also in manifest:

<receiver android:name="com.whereismywifeserver.IntentReceiver" android:enabled="true">
    <intent-filter android:priority="999">
        <action android:name="com.whereismywifeserver.intent.TEST"/>
    </intent-filter>
</receiver>

But when I try to send intent from adb, I receive error:

$ adb shell am start 
-a com.whereismywifeserver.intent.TEST
--es sms_body "test from adb" 
-c android.intent.category.HOME 
-n com.whereismywifeserver/.IntentReceiver
Starting: Intent { act=com.whereismywifeserver.intent.TEST t=[android.intent.category.HOME] cmp=com.whereismywifeserver/.IntentReceiver (has extras) }
Error type 3
Error: Activity class {com.whereismywifeserver/com.whereismywifeserver.IntentReceiver} does not exist.

When I create intent in code, everything works fine. So how can I send intent from adb?

tir38
  • 9,810
  • 10
  • 64
  • 107
user2106655
  • 1,121
  • 1
  • 9
  • 10

9 Answers9

111

You need not specify receiver. You can use adb instead.

adb shell am broadcast -a com.whereismywifeserver.intent.TEST 
--es sms_body "test from adb"

For more arguments such as integer extras, see the documentation.

tir38
  • 9,810
  • 10
  • 64
  • 107
Zohra Khan
  • 5,182
  • 4
  • 25
  • 34
  • 4
    For some reason broadcast can't reach receiver if string extra (`test from adb` in above example) contain whitespaces. Otherwise it works. – user2137020 Jan 23 '18 at 09:58
  • 1
    I have the same issue as @user2137020 – Xi Wei Apr 27 '18 at 07:16
  • 7
    It turns out, you do need `-n com.whereismywifeserver/.IntentReceiver` if you want the string extra. – Xi Wei Apr 27 '18 at 07:22
  • Is there a way to send broadcast like this with flags ? – iammrmehul Feb 07 '19 at 05:03
  • 1
    @iammrmehul - Docs says to use -f with flags, but I'm not sure how that looks... https://developer.android.com/studio/command-line/adb#IntentSpec – SteveS Dec 24 '19 at 02:20
  • @user2137020 - You need to escape the quotes, so they get transferred from the system shell to adb shell. The following works: ```adb shell am broadcast -a com.whereismywifeserver.intent.TEST --es sms_body \"test from adb\"``` – olik79 May 28 '20 at 07:32
  • Is there a way to target one emulator (if multiple connected) with this command? e.g. `adb shell -e emulator-5556 am broadcast android.intent.action.BOOT_COMPLETE` ? FYI this command doesn't work. Gives an `error: more than one device/emulator` – Michael T Oct 09 '20 at 08:56
41

The true way to send a broadcast from ADB command is :

adb shell am broadcast -a com.whereismywifeserver.intent.TEST --es sms_body "test from adb"

And, -a means ACTION, --es means to send a String extra.


PS. There are other data type you can send by specifying different params like:

[-e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE> ...]
[--esn <EXTRA_KEY> ...]
[--ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE> ...]
[--ei <EXTRA_KEY> <EXTRA_INT_VALUE> ...]
[--el <EXTRA_KEY> <EXTRA_LONG_VALUE> ...]
[--ef <EXTRA_KEY> <EXTRA_FLOAT_VALUE> ...]
[--eu <EXTRA_KEY> <EXTRA_URI_VALUE> ...]
[--ecn <EXTRA_KEY> <EXTRA_COMPONENT_NAME_VALUE>]
[--eia <EXTRA_KEY> <EXTRA_INT_VALUE>[,<EXTRA_INT_VALUE...]]
    (mutiple extras passed as Integer[])
[--eial <EXTRA_KEY> <EXTRA_INT_VALUE>[,<EXTRA_INT_VALUE...]]
    (mutiple extras passed as List<Integer>)
[--ela <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]]
    (mutiple extras passed as Long[])
[--elal <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]]
    (mutiple extras passed as List<Long>)
[--efa <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]]
    (mutiple extras passed as Float[])
[--efal <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]]
    (mutiple extras passed as List<Float>)
[--esa <EXTRA_KEY> <EXTRA_STRING_VALUE>[,<EXTRA_STRING_VALUE...]]
    (mutiple extras passed as String[]; to embed a comma into a string,
     escape it using "\,")
[--esal <EXTRA_KEY> <EXTRA_STRING_VALUE>[,<EXTRA_STRING_VALUE...]]
    (mutiple extras passed as List<String>; to embed a comma into a string,
     escape it using "\,")
[-f <FLAG>]

For example, you can send an int value by:

--ei int_key 0
CalvinChe
  • 975
  • 8
  • 8
34

I've found that the command was wrong, correct command contains "broadcast" instead of "start":

adb shell am broadcast -a com.whereismywifeserver.intent.TEST --es sms_body "test from adb" -n com.whereismywifeserver/.IntentReceiver
user2106655
  • 1,121
  • 1
  • 9
  • 10
7

As many already noticed, the problem manifests itself only if the extra string contains whitespaces.

The root cause is that OP's host OS/shell (i.e. Windows/cmd.exe) mangles the entered command - the " characters get lost, --es sms_body "test from adb" becomes --es sms_body test from adb. Which results in sms_body string extra getting assigned the value of test and the rest of the string becoming <URI>|<PACKAGE>|<COMPONENT> specifier.

To avoid all that you could use:

adb shell "am broadcast -a com.whereismywifeserver.intent.TEST --es sms_body 'test from adb' -n com.whereismywifeserver/.IntentReceiver"

or just start the interactive adb shell session first and run the am broadcast command from inside of it.

Alex P.
  • 30,437
  • 17
  • 118
  • 169
7

Another thing to keep in mind: Android 8 limits the receivers that can be registered via manifest (e.g., statically)

https://developer.android.com/guide/components/broadcast-exceptions

Yang
  • 483
  • 1
  • 5
  • 9
7

Using Android 8 and above with added implicit receivers restrictions, you should add a package name of your app at the end of a terminal command:

adb shell am broadcast -a my.app.package.TEST my.app.package

In case if you have a suffix in debug mode for your package, use my.app.package.debug instead.

ultraon
  • 2,220
  • 2
  • 28
  • 27
6

Noting down my situation here may be useful to somebody,

I have to send a custom intent with multiple intent extras to a broadcast receiver in Android P,

The details are,

Receiver name: com.hardian.testservice.TestBroadcastReceiver

Intent action = "com.hardian.testservice.ADD_DATA"

intent extras are,

  1. "text"="test msg",
  2. "source"= 1,

Run the following in command line.

adb shell "am broadcast -a com.hardian.testservice.ADD_DATA --es text 'test msg' --es source 1 -n com.hardian.testservice/.TestBroadcastReceiver"

Hope this helps.

Hardian
  • 1,922
  • 22
  • 23
4

I had the same problem and found out that you have to escape spaces in the extra:

adb shell am broadcast -a com.whereismywifeserver.intent.TEST --es sms_body "test\ from\ adb"

So instead of "test from adb" it should be "test\ from\ adb"

melbic
  • 11,988
  • 5
  • 33
  • 37
2

I am not sure whether anyone faced issues with getting the whole string "test from adb". Using the escape character in front of the space worked for me.

adb shell am broadcast -a com.whereismywifeserver.intent.TEST --es sms_body "test\ from\ adb" -n com.whereismywifeserver/.IntentReceiver
sadat
  • 4,004
  • 2
  • 29
  • 49