Connect to an Android Emulator running on Linux from Windows
Once upon a time I needed to connect to an Android emulator running on a Linux box from a Windows virtual machine. Yes, it was very strange. In case you every find yourself in a similar situation, here’s one way to do it.
On the Linux side
- On the Linux box, install Android Studio, including the Platform SDK tools
- Use the AVD Manager to install and run an android emulator
- Kill the existing adb server:
~/Android/Sdk/platform-tools/adb kill-server
- See which port the emulator is listening on (Usually 5555):
lsof -iTCP -sTCP:LISTEN -P | grep 'emulator\|qemu'
- Create a named pipe named
/tmp/emupipe
(Could be called anything):
cd /tmp
mkfifo emupipe
- Use Netcat to shuttle TCP traffic from an external port to localhost:5555
nc -kl 15555 0<emupipe | nc 127.0.0.1 5555 > emupipe
On the Windows side
- On the Windowds side, add
C:\Program Files (x86)\Android\android-sdk\platform-tools
to your PATH so that you have easy access toadb
- Connect adb to the remote emulator:
adb connect <IP>:15555
The IP address could be an address of a remote server, the VM host, etc. In this case, Windows was inside a qemu VM, which lets us connect to the host using 10.0.2.2. So the adb command looked like:
adb connect 10.0.2.2:15555
Tear down the connection
When you’re done emulating, all you have to do is kill the nc
command.
Automate starting the emulator and setting up the backpipe
Getting up and running involves a lot of steps, so here’s a zsh script that starts the android emulator and sets up that netcat traffic forwarding.
#!/usr/bin/env zsh
zmodload zsh/zutil
zparseopts -D -E -F -- -cold=cold || exit 1
optColdBoot='-no-snapshot-load'
if [ -z $cold ]; then
optColdBoot=''
fi
autoload colors; colors
#-----
echo "$fg[green]\n# Searching for AVDs$reset_color"
avds=$(~/Android/Sdk/emulator/emulator -list-avds)
echo "$fg[yellow]👇 Found:"
echo "$fg[blue]$avds$reset_color"
avd=$(echo $avds | head -1)
echo "$fg[green]\n# Starting '$avd'$reset_color"
~/Android/Sdk/emulator/emulator @$avd -netdelay none -netspeed full -gpu host -cores 8 -memory 3072 $optColdBoot &
waitSeconds=45
if [ -z $cold ]; then
waitSeconds=10
fi
# Countdown
while [ $waitSeconds -gt 0 ]; do
echo -ne "Countdown: $waitSeconds\033[0K\r"
sleep 1
: $((waitSeconds--))
done
#-----
pipe="/tmp/emupipe"
echo "$fg[green]\n# Creating named pipe '$pipe'$reset_color"
echo "$fg[yellow]--Removing any existing$reset_color"
rm -f $pipe
echo "$fg[yellow]--Creating new pipe$reset_color"
mkfifo $pipe
#----
listenPort=15555
forwardPort=5555
echo "$fg[green]\n# Forwarding port $fg[magenta]$listenPort$fg[green] to $fg[magenta]$forwardPort$reset_color"
ip=$(ip -4 a show eno1 | grep -Po 'inet \K[0-9.]+')
echo "$fg[yellow]--$fg[gray]From the VM run $fg[cyan]adb connect $ip:$listenPort'$reset_color"
echo "$fg[green]\nListening...(keep terminal open)$reset_color"
nc -kl $listenPort 0<$pipe | nc 127.0.0.1 $forwardPort > $pipe