====== Android ADB Control ======
Operating an Android device headless from a laptop over adb: reaching its services, restarting a killed app, and driving the UI by script.
===== Connecting =====
adb devices -l # lists attached devices
USB debugging must be on in developer options. After a fresh boot or ''adb kill-server'', the first ''adb'' command restarts the daemon.
===== Reaching Device Services =====
sshd and Caddy only listen on the device. Two paths:
# Wi-Fi, normal path
ssh -p 8022 192.168.1.82
# USB only: adb forward, no network needed
adb forward tcp:18022 tcp:8022
adb forward tcp:18080 tcp:8080
ssh -p 18022 localhost
curl http://localhost:18080/
Gotchas:
* ''nc -z'' through an adb forward gives a false positive: adb accepts the local connection before knowing the device port is dead. Verify with a real probe: ''curl'' for HTTP, the ''SSH-2.0-OpenSSH'' banner for sshd.
* ''ss'' and ''netstat'' are not reliably available. Check listeners on-device via ''/proc/net/tcp'' hex ports: ''adb shell "grep -E ':(1F56|1F90) ' /proc/net/tcp /proc/net/tcp6"''.
===== Restarting a Killed App =====
Swiping Termux out of recents, or a reboot without a subsequent unlock, kills the whole Termux stack. From a shell you cannot broadcast ''BOOT_COMPLETED'' (protected intent) or start the Termux service (needs ''allow-external-apps=true''). What works: launch Termux and type the boot command into it.
adb shell "input keyevent KEYCODE_WAKEUP; wm dismiss-keyguard"
adb shell "input swipe 200 600 200 100" # dismiss swipe lockscreen
adb shell "monkey -p com.termux -c android.intent.category.LAUNCHER 1"
sleep 3
adb shell "dumpsys window | grep mCurrentFocus" # verify Termux has focus
adb shell "input text 'sh%s~/.termux/boot/start-server.sh'; input keyevent 66"
* ''input text'' needs ''%s'' for spaces. Keyevent 66 is ENTER, 4 is BACK.
* Verify with ''ps -A | grep -E 'sshd|caddy''.
* Prevention: never swipe Termux from recents, and whitelist it from doze: ''adb shell "dumpsys deviceidle whitelist +com.termux"''.
===== UI Automation Cookbook =====
adb shell "uiautomator dump /data/local/tmp/ui.xml; cat /data/local/tmp/ui.xml"
# parse bounds="[l,t][r,b]", tap the center
adb shell "input tap X Y"
Quirks:
* ''input tap'' works on buttons but not RecyclerView grid items in the DocumentsUI file picker. Navigate those with ''KEYCODE_TAB'' (walks focusable nodes) and ''KEYCODE_DPAD_*'' once the grid has focus; ''KEYCODE_DPAD_CENTER'' opens.
* The soft keyboard covers dialog buttons and eats taps. Check ''dumpsys input_method | grep mInputShown'' and dismiss it with one BACK.
* Check ''dumpsys power | grep mWakefulness'' before injecting input: the screen sleeps quickly.
* ''input swipe x y x+1 y+1 50'' is a more reliable tap; ''800''ms is a long-press.
* ''monkey -p -c android.intent.category.LAUNCHER 1'' launches any app.
===== Processes =====
adb shell "ps -A -o PID,USER,RSS,NAME | sort -k3 -rn | head -40" # toybox ps, no aux
adb shell "dumpsys activity lru" # LRU states: fg/vis keep, cch killable, pers respawns
adb shell "am force-stop " # kill an app and its process tree
adb shell "grep MemAvailable /proc/meminfo"
===== See Also =====
* [[hosting:hardware:termux_server|Termux Server Stack]]
* [[hosting:hardware:android_phones|Android Phones]]
* [[hosting:start|Hosting Guide]]
* [[start|Return to wiki home]]