====== 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]]