Using the following 3 commands, Can we have single adb shell command to know the current apk file location and version of the apk.
we can use following command to find the all packages and locations of the apks
adb shell pm list packages -f
we can use following command to know the current package name.
adb shell dumpsys window | grep -i mCurrentFocus
we can use following command to know apk version
adb shell dumpsys package my.package | grep versionName
This will be use full for every one to quickly check the current apk details immediately.
Example: If i open com.src.test application from device. i want to know where this apk installed (/system/app/) and version of apk (1.0101) using single adb shell command.
Something like this maybe?
package=$(dumpsys window windows | grep mCurrentFocus | cut -d'/' -f1 | rev | cut -d' ' -f1 | rev) && dumpsys package $package | grep -E "versionName|codePath"
codePath=/data/app/com.src.test
versionName=1.0101
Related
I'm trying to do a pipe operation on my Android device through adb (this is for an automated script).
The operation is to fetch the most recently modified file in a particular directory and then delete it.
Let us say this file is file.txt and it is in /sdcard/Android/data/my.app.package on the Android device.
When I try to do adb shell ls -t /sdcard/Android/data/my.app.package | head -1 | xargs rm -f it throws the error:
rm: file.txt: No such file or directory
This is because it expects the full path.
So then I tried ls -t /sdcard/Android/data/my.app.package | head -1 | xargs ls -d | xargs rm -f but it complains with the same error.
Perhaps I need to pass in the $PWD along with the file name to xargs. How can I do that, or is there a better way to do this?
Edit: I have now tried ls -t sdcard/Android/data/my.app.package | head -1 | xargs -I '{}' ls sdcard/Android/data/my.app.package/'{}' and while a similar command works correctly on the Linux system as expected, it does weird stuff on the Android device. Possibly some missing implementation of xargs on Android stack.
A command like
adb shell foo | bar
runs foo in adb shell, and has your local shell run bar and receive its input from adb shell. If bar should run in adb shell too, you want to pass the entire pipeline to adb shell:
adb shell 'foo | bar'
This part of your question is basically a duplicate of
How to type adb shell commands in one line?
Separately, your ls -t command is flawed in several ways. Generally, don't use ls in scripts; but the trivial fix is to run the command in that directory directly. Then you don't need to add the path back on:
adb shell 'cd /sdcard/Android/data/my.app.package &&
ls -t | head -1 | xargs rm -f'
This still suffers from the various vagaries of parsing ls output; probably a better solution is to use find instead. If you have the facilities of GNU find and related utilities available on the remote device, try
adb shell 'find /sdcard/Android/data/my.app.package -printf "%T# %p\\0" |
sort -r -z -n | head -z -n 1 | sed "s/^[^ ]* //" | xargs -0 rm'
(Adapted from https://stackoverflow.com/a/299911/874188 with quoting fixes to allow the overall command to be run inside single quotes.)
If adb shell does not provide access to GNU userspace tools, perhaps just make sure you have very detailed control over what files can land in your directory so that you can reasonably reliably parse the output from ls; or if you can't guarantee that, try hacking something in e.g. Perl.
It is unfortunate that there is no simple standard way to get the oldest or newest n files from a directory in a robust, machine-readable form.
It would be nice if there was a more succinct way than these arguably complex and slightly advanced tricks with find.
This is the solution that works:
adb shell ls /sdcard/Android/data/my.app.package/`adb shell ls -t /sdcard/Android/data/my.app.package | head -1` | adb shell xargs rm -f
I am using the following command to copy the most recently added file from a connected device into the directory that I want:
adb pull sdcard/Robotium-Screenshots/filename.jpg D:\jenkins\jobs\
But it can copy only the file that I specify.
How can I copy the newest file from sdcard/Robotium-Screenshots/ to D:\jenkins\jobs\ without specifying it by name?
Here is a one-liner which would pull the last modified file from a specified folder:
adb exec-out "cd /sdcard/Robotium-Screenshots; toybox ls -1t *.jpg 2>/dev/null | head -n1 | xargs cat" > D:\jenkins\jobs\latest.jpg
Known limitations:
It relies on ls command to do the sorting based on modification time. Historically Android devices had multiple sources for the coreutils, namely toolbox and toybox multi-binaries. The toolbox version did not support timestamp based sorting. That basically means that this won't work on anything older than Android 6.0.
It uses adb exec-out command to make sure that binary output does not get mangled by the tty. Make sure to update your platform-tools to the latest version.
If you use a bash-like shell, you can do:
adb pull /sdcard/Robotium-Screenshots/`adb shell ls -t /sdcard/Robotium-Screenshots/ | head -1` ~/Downloads
You can get a bash-like shell through cygwin, msys, git for windows (based on msys). If you are on mac or linux, you already have a bash-like shell.
One way to do this would be to grab the file name using the following command:
adb shell ls -lt /sdcard/Robotium-Screenshots | head -n2 | tail -n+2 | awk '{print $8}'
Is it possible to kill ALL the active tasks/apps in the task manager using ADB? This would be equivalent of opening the task manager and killing each task one by one...
I tried using the the following adb shell command but that didn't kill all the task.
adb shell am kill-all
I can't use the adb shell am force-stop <PACKAGE> command because it would require me to know which package/app is running. I want to kill ALL the user apps task that are running. Similarly to using the task manager and killing each task one by one.
According to the command description, kill-all kills all background processes. Are background processes equivalent to "services" and task equivalent to "activities"?
Also, is it possible to clear cache of apps using ADB while keeping the user data? I seems that the adb shell pm clear clears all the user data. I want to only clear the cache.
The reason why I am asking is because I am doing some performance testing on few user apps. To make each test valid, I want to ensure none of the user apps have any task, activities, services, and cache already in the background.
You can use force-stop, it doesn't require root permission.
adb shell am force-stop <PACKAGE>
And you can get the package name from the top running activity/app
adb shell "dumpsys activity | grep top-activity"
After that you need to play a bit with the result, to extract the package, here my java code that does that:
public void parseResult(String line){
int i = line.indexOf(" 0 ");
if(i == -1){
return;
}
line = line.substring(i);
i = line.indexOf(":");
if(i == -1){
return;
}
line = line.substring(i + 1);
i = line.indexOf("/");
return line.substring(0, i);
}
If you want to start clean slate i.e close the app and clear its data too you can do the following
adb shell pm clear com.yourapp.package
For non rooted devices I expanded on Faisal Ameer's Script
adb shell ps | grep -v root | grep -v system | grep -v "android.process." | grep -v radio | grep -v "com.google.process." | grep -v "com.lge." | grep -v shell | grep -v NAME | awk '{print $NF}' | tr '\r' ' ' | xargs adb shell am force-stop
The adb shell am force-stop does not require root permission. Note that the applications still show up in the devices running application drawer but I have verified that the packages processes have been cleared using.
adb shell dumpsys meminfo relevant.package.names
find running apps, ignoring system apps etc and kill, the following command does it all;
adb shell ps|grep -v root|grep -v system|grep -v NAME|grep -v shell|grep -v smartcard|grep -v androidshmservice|grep -v bluetooth|grep -v radio|grep -v nfc|grep -v "com.android."|grep -v "android.process."|grep -v "com.google.android."|grep -v "com.sec.android."|grep -v "com.google.process."|grep -v "com.samsung.android."|grep -v "com.smlds" |awk '{print $2}'| xargs adb shell kill
you can add more exceptions if you find any like this; grep -v "exception"
Trying to log cpu usage (to file) of my app under windows.
First I tried this usning cmd
adb shell top | grep com.myapp > log.log
Which gives "grep is not recognized as an internal or external command, operable program or batch file.". I guess windows doesn't any grep command?
Then I tried the same command usning cygwin terminal. This resulted in an empty logfile. So I ran the same command but without redirecting the output
adb shell top | grep com.myapp
This returned the expected output. I've also tried redirecting stderr with "2>&1". Didn't work.
What am I doing wrong?
I have got the same problem and --line-buffered solved it.
For example
adb shell top | grep --line-buffered com.myapp > log.log
Is there a way to get the launchable activity for a package from using adb? For an unroot phone (i.e. without having the pull the apk from /data/app directory and inspect with appt).
I tried dumpsys, but it does not include information on default launchable activity.
Thanks
You don't need root to pull the apk files from /data/app. Sure, you might not have permissions to list the contents of that directory, but you can find the file locations of APKs with:
adb shell pm list packages -f
Then you can use adb pull:
adb pull <APK path from previous command>
and then aapt to get the information you want:
aapt dump badging <pulledfile.apk>
$ adb shell pm dump PACKAGE_NAME | grep -A 1 MAIN
Since Android 7.0 you can use adb shell cmd package resolve-activity command to get the default activity of an installed app like this:
adb shell "cmd package resolve-activity --brief com.google.android.calculator | tail -n 1"
com.google.android.calculator/com.android.calculator2.Calculator
#!/bin/bash
#file getActivity.sh
package_name=$1
#launch app by package name
adb shell monkey -p ${package_name} -c android.intent.category.LAUNCHER 1;
sleep 1;
#get Activity name
adb shell logcat -d | grep 'START u0' | tail -n 1 | sed 's/.*cmp=\(.*\)} .*/\1/g'
sample:
getActivity.sh com.tencent.mm
com.tencent.mm/.ui.LauncherUI
I didn't find it listed so updating the list.
You need to have the apk installed and running in front on your phone for this solution:
Windows CMD line:
adb shell dumpsys window windows | findstr <any unique string from your pkg Name>
Linux Terminal:
adb shell dumpsys window windows | grep -i <any unique string from your Pkg Name>
OUTPUT for Calculator package would be:
Window #7 Window{39ced4b1 u0 com.android.calculator2/com.android.calculator2.Calculator}:
mOwnerUid=10036 mShowToOwnerOnly=true package=com.android.calculator2 appop=NONE
mToken=AppWindowToken{29a4bed4 token=Token{2f850b1a ActivityRecord{eefe5c5 u0 com.android.calculator2/.Calculator t322}}}
mRootToken=AppWindowToken{29a4bed4 token=Token{2f850b1a ActivityRecord{eefe5c5 u0 com.android.calculator2/.Calculator t322}}}
mAppToken=AppWindowToken{29a4bed4 token=Token{2f850b1a ActivityRecord{eefe5c5 u0 com.android.calculator2/.Calculator t322}}}
WindowStateAnimator{3e160d22 com.android.calculator2/com.android.calculator2.Calculator}:
mSurface=Surface(name=com.android.calculator2/com.android.calculator2.Calculator)
mCurrentFocus=Window{39ced4b1 u0 com.android.calculator2/com.android.calculator2.Calculator}
mFocusedApp=AppWindowToken{29a4bed4 token=Token{2f850b1a ActivityRecord{eefe5c5 u0 com.android.calculator2/.Calculator t322}}}
Main part is, First Line:
Window #7 Window{39ced4b1 u0 com.android.calculator2/com.android.calculator2.Calculator}:
First part of the output is package name:
com.android.calculator2
Second Part of output (which is after /) can be two things, in our case its:
com.android.calculator2.Calculator
<PKg name>.<activity name> =
<com.android.calculator2>.<Calculator>
so .Calculator is our activity
If second part is entirely different from Package name and doesn't seem to contain pkg name which was before / in out output, then entire
second part can be used as main activity.
Here is another way to find out apps package name and launcher activity.
Step1: Start "adb logcat" in command prompt.
Step2: Open the app (either in emulator or real device)
You can also use ddms for logcat logs where just giving search of the app name you will all info but you have to select Info instead of verbose or other options. check this below image.
Launch your app and keep it in foreground.
Run the below command:
adb shell dumpsys window windows | find "mcurrentfocus"
mCurrentFocus doesn't work for me on Android 12 device.
Here is the right step to go:
Connect the device and open the app.
adb shell dumpsys window windows | grep -E mObscuringWindow
mObscuringWindow=Window{bc78a3 u0 com.yds.demo/com.test.activity.AppActivity}
com.test.activity.AppActivity is the activity.