I found this script to test Google Campaign Parameters received:
adb shell am broadcast -a com.android.vending.INSTALL_REFERRER -n com.accuweather.android/com.accuweather.android.services.GoogleCampaignTrackingReceiver --es "referrer" "utm_source=test_androidlite_source&utm_medium=test_medium&utm_term=test_term&utm_content=test_content&utm_campaign=test_name"
Found here
Here is how I am receiving it for testing purposes:
public class GoogleCampaignTrackingReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
String referrerString = extras.getString("referrer");
Logger.i(this, "referrer string is %s", referrerString);
}
}
And I am wondering how I get all the parameters, not just the first? Here is the log statement:
03-13 18:40:41.990: I/GoogleCampaignTrackingReceiver(30212): referrer string is utm_source=test_androidlite_source
I'm faced same issue and spend couple hours to find the answer.
In my case, i send broadcast
./adb shell am broadcast -a com.android.vending.INSTALL_REFERRER --es
"referrer"
"traffic=test1&md=1t1&utm_source=test1&utm_medium=android&utm_campaign=test12&utm_term=t3&utm_content=t5
And got only first param
Solution is simple - you need enter the adb shell first
./adb shell
And then send your broadcast
shell#android:/ $ am broadcast -a com.android.vending.INSTALL_REFERRER --es
"referrer"
"traffic=test1&md=1t1&utm_source=test1&utm_medium=android&utm_campaign=test12&utm_term=t3&utm_content=t5
All params will be received correctly.
I hope it will be useful, since i have not find such explanations
Related
I'm starting a sharing activity from ADB shell.
Specifically I am trying to achieve the same as this (working) java-snippet:
File dir = Environment.getExternalStorageDirectory();
File yourFile = new File(dir, "/_tmp/1.jpg");
Uri yourFileUri = Uri.fromFile(yourFile);
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
sendIntent.setType("image/*");
sendIntent.putExtra(Intent.EXTRA_STREAM, yourFileUri);
sendIntent.setPackage("com.snapchat.android");
startActivity(sendIntent);
Here is the commands I am using:
adb shell am start -a android.intent.action.SEND -t image/jpeg --es android.intent.extra.STREAM file:///storage/emulated/0/_tmp/1.jpg com.snapchat.android --grant-read-uri-permission
The issue I am currently facing is that the snapchat app will open and load, flash black for a second but fails to load the image.
I have checked that the path to the image is working by issuing the following commands, and opening the image in the android gallery:
adb shell am start -t image/jpeg -d file:///storage/emulated/0/_tmp/1.jpg
What am I doing wrong?
Edit:
Using the command:
adb shell am start -a android.intent.action.SEND -t image/jpeg --es android.intent.extra.STREAM file:///storage/emulated/0/_tmp/1.jpg com.snapchat.android/com.snapchat.android.LandingPageActivity --grant-read-uri-permission
Gives the same result, however I compared it to the actual call in DDMS, see the difference here:
Log by sharing manually through the phone:
10-19 18:01:54.020: D/HtcShareActivity(21561): onItemClick: position=0 activity=com.snapchat.android/com.snapchat.android.LandingPageActivity
10-19 18:01:54.061: I/ActivityManager(724): START u0 {act=android.intent.action.SEND typ=image/jpeg flg=0x1 cmp=com.snapchat.android/.LandingPageActivity (has clip) (has extras)} from uid 10078 on display 0
Log by using the ADB command:
10-19 18:04:29.096: I/ActivityManager(724): START u0 {act=android.intent.action.SEND typ=image/jpeg flg=0x10000000 cmp=com.snapchat.android/.LandingPageActivity (has extras)} from uid 2000 on display 0
As you can see the (has clip) is not present in the ADB call.
Could it be that --grant-read-uri-permission isn't "working" or at least not giving sufficient permission?
How do I test and ultimately solve this?
You're opening your application with the intent, but, you're not declaring which Activity should handle the intent, which is why you see a flicker and then close - an Activity needs to handle the intent.
You need to declare in your command whats the MainActivity that is supposed to be handling the intent.
For example :
adb shell am start -a android.intent.action.SEND -t image/* --es
android.intent.extra.STREAM file:///storage/emulated/0/_tmp/1.jpg
com.snapchat.android/FULL_PATH_OF_YOUR_ACTIVITY
where FULL_PATH_OF_YOUR_ACTIVITY should be the activity declared as main activity in your manifest.
adb shell am start -a android.intent.action.SEND -t image/* --es
android.intent.extra.STREAM file:///storage/emulated/0/_tmp/1.jpg
com.snapchat.android/com.snapchat.android.sub.MainActivity
Sample manifest :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.snapchat.android">
<application
android:theme="#style/AppTheme">
<activity android:name="com.snapchat.android.sub.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
It turned out I wasn't sending any real image data, I was simply sending a string by using --es, however the a URI was needed, and therefore I should have used --eu.
Updating the following command:
adb shell am start -a android.intent.action.SEND -t image/jpeg --es android.intent.extra.STREAM file:///storage/emulated/0/_tmp/1.jpg com.snapchat.android/com.snapchat.android.LandingPageActivity --grant-read-uri-permission
To:
adb shell am start -a android.intent.action.SEND -t image/jpeg --eu android.intent.extra.STREAM file:///storage/emulated/0/_tmp/1.jpg com.snapchat.android/com.snapchat.android.LandingPageActivity --grant-read-uri-permission
Solved my issue.
It was not due to leaving out declaration of the main activity that #Dus suggested. (Good thought though.)
The command can be simplified all the way down to:
adb shell am start -a android.intent.action.SEND -t image/jpeg --eu android.intent.extra.STREAM file:///storage/emulated/0/_tmp/1.jpg com.snapchat.android
I'm trying to trigger an activity using an intent using adb on the command line:
adb shell am start
-a android.intent.action.VIEW
-c android.intent.category.DEFAULT
-t vnd.google.android.package/vnd.google.android.package_something
-n com.google.android.package/com.google.android.apps.package.SomeActivity
but it throws a security exception:
Starting: Intent { act=android.intent.action.VIEW cat=[android.intent.category.DEFAULT] typ=vnd.google.android.package/vnd.google.android.package_something cmp=com.google.android.package/com.google.android.apps.package.SomeActivity }
java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.VIEW cat=[android.intent.category.DEFAULT] typ=vnd.google.android.package/vnd.google.android.package_something flg=0x10000000 cmp=com.google.android.package/com.google.android.apps.package.SomeActivity } from null (pid=31536, uid=2000) requires com.google.android.package.START_ACTIVITY
at android.os.Parcel.readException(Parcel.java:1620)
at android.os.Parcel.readException(Parcel.java:1573)
at android.app.ActivityManagerProxy.startActivityAsUser(ActivityManagerNative.java:2767)
at com.android.commands.am.Am.runStart(Am.java:885)
at com.android.commands.am.Am.onRun(Am.java:361)
at com.android.internal.os.BaseCommand.run(BaseCommand.java:47)
at com.android.commands.am.Am.main(Am.java:101)
at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:251)
So I tried again with a user who has the missing permission:
adb shell am start
-a android.intent.action.VIEW -c android.intent.category.DEFAULT
-t vnd.google.android.package/vnd.google.android.package_something
-n com.google.android.package/com.google.android.apps.package.SomeActivity
--user 10088
but then it says that the activity doesn't exist:
Starting: Intent { act=android.intent.action.VIEW cat= [android.intent.category.DEFAULT] typ=vnd.google.android.package/vnd.google.android.package_something cmp=com.google.android.package/com.google.android.apps.package.SomeActivity }
Error type 3
Error: Activity class {com.google.android.package/com.google.android.apps.package.SomeActivity} does not exist.
Am I using the user parameter incorrectly? Do I need to include any more information?
You should start activities using the syntax below:
adb shell am start
-n com.google.android.package/.SomeActivity
In your case with user permission:
adb shell am start
-n com.google.android.package/.SomeActivity
--user 10088
I want to debug android's so file. I use start an Activity: am start [-D] [-W] to start activitey.
the applicationg package name is com.dualboot.apps.springzen . the main activity is com.dualboot.apps.springzen.Main$Activity . i use command
'adb shell am start com.dualboot.apps.springzen/com.dualboot.springzen.Main$Actinity'
it's not exist
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.dualboot.apps.springzen/com.dualboot.springzen.Main }
Error type 3
Error: Activity class {com.dualboot.apps.springzen/com.dualboot.springzen.Main} does not exist.
how to start this activity
Since you are calling a component you need to include the component -n option tag.
Use this:
adb shell am start -n com.dualboot.apps.springzen/.MainActivity
if you actually have the $ in your class name (I doubt it) which usually refers to an inner class then you need to use:
adb shell am start -n com.dualboot.apps.springzen/.Main\$Activity
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?
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.
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
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
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.
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
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.
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,
"text"="test msg",
"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.
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"
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
I'm using adb to sync music on an android phone. Essentially, I rm the existing music directory and push replacement music files.
I'd like to be able to use adb to force a rescan, so that the google music player (and other apps) works properly with the new songs and playlists.
According to How can I refresh MediaStore on Android? you can force a rescan by broadcasting an appropriate intent.
adb provides 'shell am broadcast', which would seem to allow me to force a rescan from adb.
Alternatively I could run a rescan app or reboot, but I'd like to trigger the rescan from adb
What adb command should I issue? The music files and playlists are all in /sdcard/music.
The rescan apps use a media mount intent to kick off the media scanner. You can use am broadcast to send the same intent.
The command is:
adb shell am broadcast -a android.intent.action.MEDIA_MOUNTED -d file:///sdcard
The MEDIA_MOUNTED intent is no longer permitted (post KitKat) for non-system apps; try this instead.
It’s not recursive, though, and has to be run on the exact_file_name, so it’s not a good replacement.
adb shell am broadcast \
-a android.intent.action.MEDIA_SCANNER_SCAN_FILE \
-d file:///mnt/sdcard/Music/<exact_file_name>
If you need to rescan recursively, you can use this command (fix paths accordingly):
adb shell "find /mnt/sdcard/Music/ -exec am broadcast \
-a android.intent.action.MEDIA_SCANNER_SCAN_FILE \
-d file://{} \\;"
Or like this (if above won't work for you):
adb shell "find /mnt/sdcard/Music/ | while read f; do \
am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE \
-d \"file://${f}\"; done"
On some Samsung mobiles, you can get a full rescan like this:
am broadcast -a com.samsung.intent.action.MTP_FILE_SCAN -n com.android.providers.media/.MediaScannerReceiver
If you have rooted your phone, you can use this script I’ve written, which has the advantage of keeping track of which files have already been updated:
#!/system/bin/env busybox ash
MUSIC_LIBRARY=/sdcard/MusicLibrary
LAST_UPDATE="$(stat -c %Y "$MUSIC_LIBRARY/.last-update")"
find "$MUSIC_LIBRARY" -type f ! -iname ".last-update" | (
while read f; do
if ! test "$LAST_UPDATE" -ge "$(stat -c %Y "$f")"; then
am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d "file://$f"
touch "$f"
else
echo "Not updated: \`$f'"
fi
done
)
touch "$MUSIC_LIBRARY/.last-update"
Here's a Python script called adb-scan.
It uses adb to ask the Android device to rescan the given files.
Example usage:
$ adb-scan Notifications/\*.mp3
Broadcasting: Intent { act=android.intent.action.MEDIA_SCANNER_SCAN_FILE dat=file:///sdcard/Notifications/cough.mp3 flg=0x400000 }
Broadcast completed: result=0
Broadcasting: Intent { act=android.intent.action.MEDIA_SCANNER_SCAN_FILE dat=file:///sdcard/Notifications/harmonica3.mp3 flg=0x400000 }
Broadcast completed: result=0
Broadcasting: Intent { act=android.intent.action.MEDIA_SCANNER_SCAN_FILE dat=file:///sdcard/Notifications/shhh.mp3 flg=0x400000 }
Broadcast completed: result=0
$
Here's the script:
#!/usr/bin/python3
#
# Ask the Android media scanner to check the given files.
#
import sys
import os
import re
sys.argv.pop(0)
if not sys.argv:
sys.exit('usage: adb-scan files...')
intent = 'android.intent.action.MEDIA_SCANNER_SCAN_FILE'
# Quote certain special characters such as spaces, backslashes and quotes. In
# particular, don't quote '*' because we want that to be expanded on the
# Android device.
def cleanup(arg):
if not arg.startswith('/'):
arg = '/sdcard/' + arg
arg = re.sub("[ \\'\"]", lambda x: '\\' + x.group(0), arg)
return arg
script = '''
for i in {args}; do
[ -e "$i" ] || echo "warning: no such file: $i"
am broadcast -a "{intent}" -d "file://$i"
done
'''.format(args=' '.join(map(cleanup, sys.argv)),
intent=intent)
cmd = ['adb', 'shell', script]
os.execvp(cmd[0], cmd)