why i can't get adb shell top works? - android

I'm testing an android app by my PC. I try to catch the CPU usage of it.
if I use
adb shell top -m 10 |tee aa.txt
it works fine.
but if i modify it like this
adb shell top -m 10 |grep myAPPname|tee aa.txt
it can not. Why and how to make it work again?

try the command below:
while true; do
adb shell top -m 10 -n 1 | grep kso >> aa
done
-n means only show the current status instead of updating frequently.
However, I suggest you use Android Profiler which is a built-in function in Android Studio to achieve your monitoring work.

Related

How to repair corrupted/obsolote Genymotion emulator via shell

I use a Genymotion android emulator for my automated Xamarin UI tests through the bash commands.
The issue is that the emulator is killed by the test runner app after tests are done. So this causes some kind of corruption on the emulator's virtual device file, I suppose.
When I try to start the emulator next time using the same script, I get the following error from Genymotion:
After clicking the update button, Genymotion dashboard opens. Then I can run the emulator by double clicking. But, I cannot do these steps through the shell.
If I could figure out what Genymotion does to repair the emulator, I would do the same thing in the shell script.
Here is my script to run the GM emulator;
cd $HOME
emulatorId=$(VBoxManage list vms | grep -E -o -i "([0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12})" | shuf -n 1)
open -a /Applications/Genymotion.app/Contents/MacOS/player.app --args --vm-name $emulatorId
sleep 5
adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed) ]]; do sleep 1; done; input keyevent 82'
After this command is executed I run my tests like following;
dotnet test Droid.UI.test.dll
Any solution or workaround for skipping this prompt is highly appreciated,
Thanks!
Your script completely overrides the launchpad; that's the problem. Why not use gmtool? It has been designed especially for this type of use.

Running adb commands on all connected devices

Is there a way of running adb commands on all connected devices? To uninstall an app from all connected devices with "adb uninstall com.example.android".
The commands I am interested in is mainly install and uninstall.
I was thinking about writing a bash script for this, but I feel like someone should have done it already :)
Create a bash file and name it e.g. adb+:
#!/bin/bash
adb devices | while read -r line
do
if [ ! "$line" = "" ] && [ "$(echo "$line" | awk '{print $2}')" = "device" ]
then
device=$(echo "$line" | awk '{print $1}')
echo "$device" "$#" ...
adb -s "$device" "$#"
fi
done
Usage: ./adb+ <command>
Building on #Oli's answer, this will also let the command(s) run in parallel, using xargs. Just add this to your .bashrc file:
function adball()
{
adb devices | egrep '\t(device|emulator)' | cut -f 1 | xargs -t -J% -n1 -P5 \
adb -s % "$#"
}
and apply it by opening a new shell terminal, . ~/.bashrc, or source ~/.bashrc.
If you only want to run on devices (or only on emulators), you can change the (device|emulator) grep by removing the one you don't want. This command as written above will run on all attached devices and emulators.
the -J% argument specifies that you want xargs to replace the first occurrence of % in the utility with the value from the left side of the pipe (stdin).
NOTE: this is for BSD (Darwin / Mac OS X) xargs. For GNU/Linux xargs, the option is -I%.
-t will cause xargs to print the command it is about to run immediately before running it.
-n1 means xargs should only use at most 1 argument in each invocation of the command (as opposed to some utilities which can take multiple arguments, like rm for example).
-P5 allows up to 5 parallel processes to run simultaneously. If you want instead to run the commands sequentially, simply remove the entire -P5 argument. This also allows you to have two variations of the command (adball and adbseq, for example) -- one that runs in parallel, the other sequentially.
To prove that it is parallel, you can run a shell command that includes a sleep in it, for example:
$ adball shell "getprop ro.serialno ; date ; sleep 1 ; date ; getprop ro.serialno"
You can use this to run any adb command you want (yes, even adball logcat will work! but it might look a little strange because both logs will be streaming to your console in parallel, so you won't be able to distinguish which device a given log line is coming from).
The benefit of this approach over #dtmilano's & approach is that xargs will continue to block the shell as long as at least one of the parallel processes is still running: that means you can break out of both commands by simply using ^C, just like you're used to doing. With dtmilano's approach, if you were to run adb+ logcat, then both logcat processes would be backgrounded, and so you would have to manually kill the logcat process yourself using ps and kill or pkill. Using xargs makes it look and feel just like a regular blocking command line, and if you only have one device, then it will work exactly like adb.
This is an improved version of the script from 強大な. The original version was not matching some devices.
DEVICES=`adb devices | grep -v devices | grep device | cut -f 1`
for device in $DEVICES; do
echo "$device $# ..."
adb -s $device $#
done
To add in the ~/.bashrc or ~/.zshrc:
alias adb-all="adb devices | awk 'NR>1{print \$1}' | parallel -rkj0 --tagstring 'on {}: ' adb -s {}"
Examples:
$ adb-all shell date
$ adb-all shell getprop net.hostname
$ adb-all sideload /path/to/rom.zip
$ adb-all install /path/filename.apk
$ adb-all push /usr/local/bin/frida-server-arm64 /data/local/tmp/frida-server
Explanation: awk extracts the device id/host (first column: print $1) of every lines except the first one (NR>1) to remove the "List of devices attached" header line), then gnu parallel runs adb -s <HOSTNAME> <whatever-is-passed-to-the-alias> on whatever non-empty line (-r) in the order specified (-k, to avoid random order / fastest response order) and prepend each line with on <DEVICE>:\t for clarity, all in parallel (-j0, possible to set another number to define how many adb should be ran in parallel instead of unlimited).
:)
This is the highest result on Google, so for all Windows users coming here let me add this solution by User zingh (slightly modified to accept arbitrary commands, rather than "only" install
Batch file (adball.bat):
FOR /F "skip=1" %%x IN ('adb devices') DO start adb -s %%x %*
Call as:
adball uninstall com.mypackage
(%* takes all input parameters, my line above makes it so that all commands are passed to adb as they are, so that you can type multiple words, flags etc.)
Note: you can even use this directly from the Android Studio "run all" popup, if you install the Powershell-plugin. You can add adball to your path, then double-tap ctrl and run
powershell adball uninstall com.mypackage
adb wrapper supports selecting multiple targets for adb commands and parallel execution.
From its README:
# Installation
./install.sh ~/apps/android-sdk-linux
# Execute adb commands on all connected devices.
adb set-target all
# Execute adb commands on given devices.
adb set-target emulator-5554 C59KGT14263422
# Use GNU parallel for parallel install.
adb set-parallel true
(Disclaimer: I have written half of it)

CPU usage per application in android

I am new for android programming.How can we get CPU usage per application in android?
your help will be more helpful
Use adb Commands:
adb shell top -m 10
Source:
Technique for indentifying android app CPU usage
Linux:
adb shell top -m 10 | grep packagename
Windows:
adb shell top -m 10 | FINDSTR packagename
Go to Settings -> Developer Tools -> Show CPU Usage
Then run the app
EDIT: This has to be done in the app. If you are reading this in 2019, use CPU Profiler
two approaches:
adb shell "top -n 1"
adb shell dumpsys cpuinfo
Using the new Android Studio 3.0 profiler you can achieve a higher information about the CPU usage and CPU inspection of your APP.
there are a few ways.
the first one is to open the CPU usage in the Jelly Bean developer options.
the second option is to run the adb shell top -m 10 function in your windows Android SDK folder or ./adb shell top -m 10 in your Mac/Linux.
This let's you monitor in a more top-esque manner
watch -n 0.5 adb shell top -n 1
0.5 is the polling interval
You can use app to access these kinds of information. Such as Simple System Monitor, Simple System Monitor.

How to start an application using Android ADB tools

How do I send an intent using Android's ADB tools?
adb shell
am start -n com.package.name/com.package.name.ActivityName
Or you can use this directly:
adb shell am start -n com.package.name/com.package.name.ActivityName
You can also specify actions to be filter by your intent-filters:
am start -a com.example.ACTION_NAME -n com.package.name/com.package.name.ActivityName
It's possible to run an application specifying the package name only using the monkey tool by follow this pattern:
adb shell monkey -p your.app.package.name -c android.intent.category.LAUNCHER 1
The command is used to run the app using the monkey tool which generates random input for the application. The last part of the command is an integer which specifies the number of generated random input for the app. In this case the number is 1, which in fact is used to launch the app (icon click).
Or, you could use this:
adb shell am start -n com.package.name/.ActivityName
Linux and Mac users can also create a script to run an APK file with something like the following:
Create a file named "adb-run.sh" with these three lines:
pkg=$(aapt dump badging $1|awk -F" " '/package/ {print $2}'|awk -F"'" '/name=/ {print $2}')
act=$(aapt dump badging $1|awk -F" " '/launchable-activity/ {print $2}'|awk -F"'" '/name=/ {print $2}')
adb shell am start -n $pkg/$act
Then "chmod +x adb-run.sh" to make it executable.
Now you can simply:
adb-run.sh myapp.apk
The benefit here is that you don't need to know the package name or launchable activity name. Similarly, you can create "adb-uninstall.sh myapp.apk"
Note: This requires that you have Android Asset Packaging Tool (aapt) in your path. You can find it under the new build tools folder in the SDK.
Step 1: First get all the package names of the apps installed in your device, by using:
adb shell pm list packages
Step 2: You will get all the package names. Copy the one you want to start using ADB.
Step 3: Add your desired package name in the below command.
adb shell monkey -p 'your package name' -v 500
For example,
adb shell monkey -p com.estrongs.android.pop -v 500
to start the Es explorer.
The shortest command yet is the following:
adb shell monkey -p your.app.package.name 1
This will launch the default activity for the package that is in the launcher.
Thanks to Androiderson for the tip.
Also, I want to mention one more thing.
When you start an application from adb shell am, it automatically adds FLAG_ACTIVITY_NEW_TASK flag which makes behavior change. See the code.
For example, if you launch a Play Store activity from adb shell am, pressing the 'Back' button (hardware back button) wouldn't take you back to your app. Instead, it would take you to the previous Play Store activity if there was some (if there was not a Play store task, then it would take you back to your app). FLAG_ACTIVITY_NEW_TASK documentation says:
if a task is already running for the activity you are now starting, then a new activity will not be started; instead, the current task will simply be brought to the front of the screen with the state it was last in
This caused me to spend a few hours to find out what went wrong.
So, keep in mind that adb shell am add FLAG_ACTIVITY_NEW_TASK flag.
We can as well start an application by knowing the application type and feeding it with data:
adb shell am start -d "file:///sdcard/sample.3gp" -t "video/3gp" -a android.intent.action.VIEW
This command displays available *video players to play a sample.3gp file.
You can find your app package name by the below command:
adb shell pm list packages
The above command returns a package list of all apps. Example:
org.linphone.debug
.
.
com.android.email
Now I want to start app linphone by using the below command and this worked for me:
adb shell am start org.linphone.debug
Open file ~/.bash_profile, and add these Bash functions to the end of the file
function androidinstall(){
adb install -r ./bin/$1.apk
}
function androidrun(){
ant clean debug
adb shell am start -n $1/$1.$2
}
Then open the Android project folder:
androidinstall app-debug && androidrun com.example.app MainActivity
monkey --pct-syskeys 0 for development boards
This argument is needed for development boards without keys/display:
adb shell monkey --pct-syskeys 0 -p com.cirosantilli.android_cheat.textviewbold 1
Without it, the app won't open, and you will get an error message like:
SYS_KEYS has no physical keys but with factor 2.0%
It was tested on HiKey960, Android O AOSP.
Learned from: this GitHub issue
Also asked at: How to use the monkey command with an Android system that doesn't have physical keys?
Use:
adb shell am start -n '<appPackageName>/.<appActitivityName>
Example:
adb shell am start -n 'com.android.settings/.wifi.WifiStatusTest'
You can use the APK-INFO application to know the list of app activities with respect to each app package.
adb shell am start -n com.app.package.name/com.java.package.name.ActivityName
Example
adb shell am start -n com.google.android.googlequicksearchbox/com.google.android.search.core.google.GoogleSearch
If the Java package is the same, then it can be shortened:
adb shell am start -n com.example.package/.subpackage.ActivityName
Use:
adb shell am start -n '<appPackageName>/<appActitivityName>'
To get <appPackageName> run :
adb shell pm list packages
To get <appActitivityName> lunch app and run
adb shell dumpsys window | grep -E 'mCurrentFocus'
Try this, for opening an Android photo app and with the specific image file to open as a parameter.
adb shell am start -n com.google.android.apps.photos/.home.HomeActivity -d file:///mnt/user/0/primary/Pictures/Screenshots/Screenshot.png
It will work on latest version of Android. No pop up will come to select an application to open as you are giving the specific app to which you want to open your image with.
When you try to open a Flutter app, you can use this command:
adb shell am start -n com.package.name/io.flutter.embedding.android.FlutterActivity
Replace com.package.name with your package name. You find your package in your app/build.gradle at applicationId.

How I can simulate "tail" command for file on the Android file system?

I have file on SD-CARD and my app using it as log file.
Is it possible through the adb to watch file with all changes in real time?
Like with tail -f /sdcard/myfile.log command.
This seems to work great for me:
adb shell "while true; do cat; sleep 1; done < /sdcard/myfile.log"
You can install busybox and then:
adb shell
tail -f /path/of/your/file
But remember that you should have root access to install busybox. If you are using the emulator check this one:
How to get root access on Android emulator?
You can do this with logcat. You can add a view that will only show log entries from your app and it will be continuously updated.
There is a great app for this: Terminal IDE. It contains many linux commands, and it does not need root access. You can install it from GooglePlay. Is is free of charge (and open source, GPLv2).
One of its best features is that it can be used through telnet. Start it on your phone, and type telnetd command. It will start a telnet daemon, which listens on port 8080 by default.
After that you can connect it from your PC, with the following command: (use cygwin on windows)
telnet 192.168.1.8 8080
You should use your phone's IP address instead of the above one. After a successful connection you will have an arbitrary sized terminal on your PC, which is capable to run tail -f command on your phone. And many others, such as bash and all of its builtin commands.
Building upon Jesse's answer, to do similar with a file within an app's private storage area:
adb shell "while true; do run-as com.yourdomain.yourapp cat /data/data/com.yourdomain.yourapp/app_flutter/yourfile.txt; sleep 5; done" | egrep -o 'sometext.{0,50}'
(This example is for a flutter app on Android, but is similar minus the app_flutter directory.)
do run-as changes the user under which the command is run to the application. By default adb shell user shouldn't have access to any files under an application's private storage area.
| egrep -o 'sometext.{0,50}' the cat command sends the file contents to STDOUT. egrep is taking the contents & searching for -o (only) sometext + 50 characters" using regex (hence egrep instead of grep).
Last Line Only
Replace cat with tail -n 1.
Add --line-buffered to egrep
adb shell "while true; do run-as com.yourdomain.yourapp tail -n 1 /data/data/com.yourdomain.yourapp/app_flutter/yourfile.txt; sleep 5; done" | egrep --line-buffered -o 'sometext.{0,50}'

Categories

Resources