Android Stop Emulator from Command Line - android

This question is identical to How to shut down Android emulator via command line.
However, after attempting the suggested solution from the first answer adb emu kill has not proven successful for me.
I am automating unit tests for an android application. My bash script runs on a headless machine. It creates an android device using android create avd and executes emulator with the -no-window attribute. It then compiles the test project, connects to the emulator using adb, installs the project and executes my tests. This all works fine.
Now I need to terminate the emulator process, and just like the referenced post, I am only able to do this using kill -9.
The Google tutorial Managing AVDs from the Command Line only mentions how to stop emulators within a GUI environment.
Any help is appreciated.

May be adb kill-server helps for you?
or
adb -s emulator-5544 emu kill, where emulator-5544 - emulator name.
For Linux users it will be
adb devices | grep emulator | cut -f1 | while read line; do adb -s $line emu kill; done

FOR MAC:
Run:
ps -ax | grep emulator
which gives you a wide result. Something like:
6617 ?? 9:05.54 /Users/nav/Library/Android/sdk/emulator/qemu/darwin-x86_64/qemu-system-x86_64 -netdelay none -netspeed full -avd Nexus_One_API_29
6619 ?? 0:06.10 /Users/nav/Library/Android/sdk/emulator/emulator64-crash-service -pipe com.google.AndroidEmulator.CrashService.6617 -ppid 6617 -data-dir /tmp/android-nav/
6658 ?? 0:07.93 /Users/nav/Library/Android/sdk/emulator/lib64/qt/libexec/QtWebEngineProcess --type=renderer --disable-accelerated-video-decode --disable-gpu-memory-buffer-video-frames --disable-pepper-3d-image-chromium --enable-threaded-compositing --file-url-path-alias=/gen=/Users/nav/Library/Android/sdk/emulator/lib64/qt/libexec/gen --enable-features=AllowContentInitiatedDataUrlNavigations --disable-features=MacV2Sandbox,MojoVideoCapture,SurfaceSynchronization,UseVideoCaptureApiForDevToolsSnapshots --disable-gpu-compositing --service-pipe-token=15570406721898250245 --lang=en-US --webengine-schemes=qrc:sLV --num-raster-threads=4 --enable-main-frame-before-activation --service-request-channel-token=15570406721898250245 --renderer-client-id=2
6659 ?? 0:01.11 /Users/nav/Library/Android/sdk/emulator/lib64/qt/libexec/QtWebEngineProcess --type=renderer --disable-accelerated-video-decode --disable-gpu-memory-buffer-video-frames --disable-pepper-3d-image-chromium --enable-threaded-compositing --file-url-path-alias=/gen=/Users/nav/Library/Android/sdk/emulator/lib64/qt/libexec/gen --enable-features=AllowContentInitiatedDataUrlNavigations --disable-features=MacV2Sandbox,MojoVideoCapture,SurfaceSynchronization,UseVideoCaptureApiForDevToolsSnapshots --disable-gpu-compositing --service-pipe-token=--lang=en-US --webengine-schemes=qrc:sLV --num-raster-threads=4 --enable-main-frame-before-activation --service-request-channel-token= --renderer-client-id=3
10030 ttys000 0:00.00 grep emulator
The first (left) column is the process ID (PID) that you are looking for.
Find the PID in the first (top) row. In the above example, it's 6617.
Kill that process:
kill PID
In my case, the command is:
kill 6617
Usually, killing the first process in enough to stop the emulator, but if that doesn't work, you can:
5.1. try killing other processes as well.
5.2 kill with -9 (force kill):
kill -9 PID

To stop all running emulators we use this command:
adb devices | grep emulator | cut -f1 | while read line; do adb -s $line emu kill; done

if
adb kill-server
doesn't work. Use :
adb emu kill
this will kill all the emulators
If multiple emulators are present then use:
adb -s * emu kill

Sometimes the command
adb -s emulator-5554 emu kill
did not work on my CI servers or desktops, for unknown reason.
I think on Windows it's OK to kill the process of qemu, just like
Taskkill /IM qemu-system-x86_64.exe /F /T

I can close it with:
adb shell reboot -p

The other answer didn't work for me (on Windows 7). But this worked:
telnet localhost 5554
kill

Why not just do
adb reboot bootloader

If you don't want to have to know the serial name of your device for adb -s emulator-5554 emu kill, then you can just use adb -e emu kill to kill a single emulator. This won't kill anything if you have more than one emulator running at once, but it's useful for automation where you start and stop a single emulator for a test.

adb kill-server will kill all emulators and restart the server clean.

None of the solutions worked for me. I had to go the telnet way including authentication:
AUTH=$(cat "$HOME/.emulator_console_auth_token")
expect << EOF
spawn telnet localhost 5554
expect "OK"
send "auth $AUTH\r"
expect "OK"
send "kill\r"
expect "OK"
send "exit\r"
EOF
The full script can be obtained with a free license from https://github.com/kullo/android-emulator-tools
Update: looks like this still does not reliably close the console and ADB ports (e.g. 5554,5555)

I use this one-liner, broken into several lines for readability:
adb devices |
perl -nle 'print $1 if /emulator-(\d+).device$/' |
xargs -t -l1 -i bash -c "
( echo auth $(cat $HOME/.emulator_console_auth_token) ;
echo kill ;
yes ) |
telnet localhost {}"

To automate this, you can use any script or app that can send a string to a socket. I personally like nc (netcat) under cygwin. As I said before, I use it like this:
$ echo kill | nc -w 2 localhost 5554
(that means to send "kill" string to the port 5554 on localhost, and terminate netcat after 2 seconds.)

This scrips can help you to kill All emulators at once:
Filter emulators (because you can have a mixing on physical and emus)
Kill all emus by ADB id
Disadvantage of this solution: if your emu just "stuck" you can't kill it with adb command and it required process kill. But that's very rare case.
while [ "`adb devices | grep -Eoh \"emulator-\d{0,4}\" | wc -l | tr -d ' '`" != "0" ]; do
echo "Connected emulators:"
adb devices | grep -Eoh "emulator-\d{0,4}"
for emulator in $(adb devices | grep -Eoh "emulator-\d{0,4}")
do
echo "Killing the emulator: $emulator"
adb -s "$emulator" emu kill | true
done
sleep 10;
done
echo "All emus has been killed"

List of devices attached
emulator-5584 host
emulator-5580 host
emulator-5576 host
emulator-5572 host
emulator-5568 host
emulator-5564 host
emulator-5560 host
C:\Users\Administrator>adb -s emulator-5584 emu kill
error: could not connect to TCP port 5584: cannot connect to 127.0.0.1:5584: No connection could be made because the target machine actively refused it. (10061)
NOTE: gui of emulator is not running but still it's showing
SOLUTION:
adb kill-server
start emulator using:
emulator.exe -netdelay none -netspeed full -avd Nexus_5X_API_19

On Linux when the process became unresponsive the only way I could terminate the emulator was using the command:
kill -9 `pidof adb`
which finds the process ID of adb and sends a kill -9 signal to it.

to get your devices name try to run this on Android Studio terminal
adb devices
after you get devices name, kill app with this comment
adb -s emulator-5554 emu kill
where
emulator-5554
is your device name

On Windows 10, with Android Studio 2021.1.1 patch 3, the adb -s emulator-5554 emu kill command does not work, adb being not recognized.
But here's the solution using the Tool/Device Manager. Simply select the active emulator and click on x to stop it.

Related

Is there any command for installing an app in Genymotion?

Hey guise I want to install an app on several devices in Genymotion by using terminal in ubuntu. Each time I do this:
adb install package.app
It gives me the below error:
error: more than one device/emulator
- waiting for device -
error: more than one device/emulator
I also read about
adb -s udid uninstall package.app
but this is not the solve I want. I don't want to use udid and also I don't know which device has my app from before?
Any suggestions?!
adb help is not extremely clear on what to do:
-d - directs command to the only connected USB device...
-e - directs command to the only running emulator...
-s <serial number> ...
-p <product name or path> ...
The flag you decide to use has to come before the actual adb command:
adb -e install path/to/app.apk
You cannot pass adb commands when there are more than one device connected and running at the same time ; this is a limitation with adb.
Wow finally!
I found this command as my answer:
adb devices | awk 'NR>1{print $1}' | xargs -n1 -I% adb -s % install app.apk
Thanks to sivze

Wait for Android emulator to be running before next shell command?

I started an Android emulator using the following shell command:
emulator -avd TEST_AVD
The emulator starts just fine, but the shell script never finishes executing. It just hangs there even after the emulator has completed startup. I have tried with a number of other arguments that I could find, but nothing could quite do what I want it to. How do I know, or stop the shell command, when the emulator is ready to go?
I am setting up our Jenkins CI to use a Jenkinsfile to start the emulator, and then run a series of gradle commands. In short, I'd like to do this:
sh "emulator -avd TEST_AVD"
sh "./gradlew clean test spoon"
However, I don't want to run the gradle tasks until the emulator has finished startup, and I can't figure out how to do that in the terminal.
If you want to do something after you start the emulator you should start it in the background
emulator -avd TEST_AVD &
adb wait-for-device
# other stuff here
adb can wait for a device over a transport to be in a particular state
adb wait-for[-<transport>]-<state>
- wait for device to be in the given state:
device, recovery, sideload, or bootloader
Transport is: usb, local or any [default=any]
To wait until device (or emulator) boots, you can do something like this (as was already answered by Пионерка):
adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed) ]]; do sleep 1; done;'
Basically:
Wait for device/emulator to be in adb device state
Open shell & sleep in 1 second intervals until the sys.boot_completed property becomes true
If anybody would be interested what Android Studio does, when running emulator, the answer is this class:
If device is online, then it is ready. No need to go to further steps.
Checks system property adb shell getprop dev.bootcomplete until it is equal to 1
For API 23+ devices runs command to unlock screen: adb shell wm dismiss-keyguard
Waits 1 second.

How can I tell when avd is completely launched?

I'm running a jenkins job that starts an avd device and uses calabash-android to run tests against it.
emulator -avd phone
How can I tell when this device is completely started so that I know I can start the tests without getting a device connection error?
I tried
adb wait-for-device
but that won't work because according to the adb docs
"Note that this command does not cause adb to wait until the entire system is fully booted. For that reason, you should not prepend it to other commands that require a fully booted system."
Right now I have a hard sleep, what would be a better way to script this?
Thank you.
I presume you are launching your tests via adb. If so, adb supports wait-for-device to block until the device is available (online).
adb wait-for-device
Okay, figured it out. The command I was looking for was
adb shell getprop sys.boot_completed
The full script for using the avd tool with jenkins looks like this (note: the output is all pumped into a textfile so that it doesn't tie up the script, there's probably a better way to handle this part of it)
Launch the sim
$ANDROID_HOME/tools/emulator -avd phone -gpu on -memory 2500 1>~/test.txt 2>&1 &
Wait for the sim to finish launching
A=$($ANDROID_HOME/platform-tools/adb shell getprop sys.boot_completed | tr -d '\r')
while [ "$A" != "1" ]; do
sleep 2
A=$($ANDROID_HOME/platform-tools/adb shell getprop sys.boot_completed | tr -d '\r')
done
Unlock sim
$ANDROID_HOME/platform-tools/adb shell input keyevent 82 1>~/test.txt 2>&1 &

Running specific commands in monkey not working

I read this page
http://hariniachala.blogspot.com/2011/09/android-application-ui-testing-with.html
and when I executed this code
./adb -d shell monkey -p package_name --port 1080 &
./adb -d forward tcp:1080 tcp:1080
telnet localhost 1080
I faced the following problem
C:\Users\subhi\Desktop>adb -d shell monkey -p package_name --port 1080
error: device not found
what is the simplest method to do that ?
probably the reason why ADB is not finding a device is that you are forcing the search for a physical one (-d option). If you want to interact with an emulated device you should use -e or even no option (ADB should resolve it automatically).
Summing up, if I understood your problem, my suggestion is to launch an AVD, wait until boot and use:
adb shell monkey -p <app.package.name> --port <X> &
adb forward tcp:<X> tcp:<X>
telnet localhost <X>
where
<X>
is the port number you want to use.

How to use android monkey

I am a little confused on how to actually use monkey, i thought you were supposed to power on your emulator and go into terminal editor and type:
$ adb shell monkey -p insert.my.package.name.here -v 500
since that did not work (error, adb: permission denied)
i tried monkey -p insert.blah.blah -v 500 and this comes up that it has been killed, what am I doing wrong?
It's probably trying to talk to a device over your USB port.
You probably just need to add an -e in there to tell adb to connect to the emulator:
$ adb shell monkey -p insert.my.package.name.here -v 500
(Or -s serialnum if you have more than one emulator running.)
See Directing commands in the ADB docs.
It's well explained here:
https://android.googlesource.com/platform/development/+/master/cmds/monkey/README.NETWORK.txt
it's a tool for testing apps, and the port indicates which porto to connect (binds to localhost) to issue remote commands

Categories

Resources