16

I'm trying to send JSON data as extra on an Android broadcast which I send via ADB to the device. But it looks like the data which gets to the device is not as expected.

What I execute:

adb shell am broadcast -a com.test.android.ACTION_TEST_FEATURE -n com.test.android/.receivers.TestsReceiver -e "notify" '{"debug": false, "title": "Application update!"}'

What I expect as extra data:

{"debug": false, "title": "Application update!"}

What I get as extra data:

"debug": false

If I send {"debug": false "title": "Application update!"} as extra data then i get {"debug": false "title": "Application update!"} as extra data (noting the missing comma). So I assume it has something to do with Brace Expansion of my bash, but turning it off does not solve the problem and escaping the braces or the comma is not working.

What am I doing wrong?

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
bela.waeckerlig
  • 220
  • 2
  • 11

5 Answers5

27

Your workaround was a huge help!

It indicates that the problem is in quoting through two shells (host plus Android). Shell quoting is a horrible tarpit but there's serious extra weirdness here.

After experimenting with "echo" commands, I found that adb shell's argument must be quoted as a single argument to the local shell and the JSON payload must be quoted as a single argument to the Android shell.

Here's a general solution (and it doesn't require sprinkling \-quoting of ", !, {, and } chars in the JSON text):

adb shell "am broadcast -a com.test.android.ACTION_TEST_FEATURE -n com.test.android/.receivers.TestsReceiver -e notify '"'{"debug": false, "title": "Application update!"}'"'"

Pattern: adb shell "am broadcast ... '"'JSON_TEXT'"'"

The inner pair of ' marks quotes the JSON_TEXT locally while the outer pair quotes it remotely. That outer pair is in turn "-quoted.

Jerry101
  • 12,157
  • 5
  • 44
  • 63
  • BTW if you want to broadcast to a GCM push notification receiver, see http://stackoverflow.com/a/29425669/1682419 . (I spent way too much time today solving these two puzzles. These two SO questions & answers helped enormously.) – Jerry101 Apr 03 '15 at 07:39
  • 2
    Plus one for "Shell quoting is a horrible tarpit." – Carl Manaster Jul 23 '15 at 00:15
  • 1
    You just saved my day. +1 for the Pattern – Shachi Jan 21 '19 at 10:45
6

ok, I just found a solution. I first have to enter the devices shell via adb shell and then execute am broadcast -a com.test.android.ACTION_TEST_FEATURE -n com.test.android/.receivers.TestsReceiver --es "notify" '{"debug": false, "title": "Application update!"}'

bela.waeckerlig
  • 220
  • 2
  • 11
0

This should be the structure of the adb command.

adb shell "am broadcast -a YOUR_BROADCAST_INTENT_ACTION -n YOUR_APP_PACKAGE/.PATH_TO_BROADCAST_RECIEVER_CLASS.BROADCAST_RECEIVER_CLASS -e 'STRING_KEY' 'DATA HERE'"

The above command will ensure delivery of the intent to the receiver even if the string has spaces in it.

adb shell "am broadcast -a wingoku.custom.invoking.event -n com.wingoku.root/.broadcastReceivers.MyReceiver-e 'shellCommand' 'hello world. My name is umer'"
Umer Farooq
  • 7,356
  • 7
  • 42
  • 67
0

When I used examples here I always lost " in final string, so instead of getting "{"a":"b"}" I got "{a:b}". What worked for me is:

adb shell "am broadcast -a myaction -e myextra '''[{\"a\":\"b\"}]'''"

Important were the quotes before am broadcast and after entire command and also each " had to be escaped with \.

Torima
  • 157
  • 2
  • 13
-1

i know this is an old post, but i have some thoughts.

after struggle to pass data through cmd and bash args, or subprocess in program, i found use base64 to encode json dumped data is extremely convenient, just base64 decode and then json loads, no worry about quote, space, tab, anything.

gen
  • 21
  • 1
  • 3