A set of tools for controlling Android devices and reading device state that is
not possible through adb shell alone. The tools run headless via
app_process straight from a single classes.dex — nothing needs to be
installed on the device.
- Clipboard — get, set (incl. base64), and clear the system clipboard
- UI tree dump — dump the on-screen accessibility hierarchy as JSON
- Package list — list installed packages with app name and version
- Screen streaming — H.264 (AVC) or MJPEG, with scale/fps/quality options
All of the above run from the published devicekit.dex with no app install.
Download the latest devicekit.dex from
GitHub releases and
push it to the device:
curl -s -O -J -L https://github.com/mobile-next/devicekit-android/releases/latest/download/devicekit.dex
adb push devicekit.dex /data/local/tmp/Every tool is launched the same way — app_process with the dex on the
classpath:
adb shell CLASSPATH=/data/local/tmp/devicekit.dex app_process / com.mobilenext.devicekit.<Tool> [args]The tools run as the shell user (uid 2000); no root is required.
For tools that emit binary output (the screen streamers) use
adb exec-outinstead ofadb shell, otherwise the stream is corrupted by newline translation.
# Set the clipboard
adb shell CLASSPATH=/data/local/tmp/devicekit.dex app_process / com.mobilenext.devicekit.Clipboard set "Hello World"
# Set from base64 (safest for spaces, emoji, and other UTF-8) — "✌️"
adb shell CLASSPATH=/data/local/tmp/devicekit.dex app_process / com.mobilenext.devicekit.Clipboard set --base64 "4pyM77iP"
# Print the current clipboard text
adb shell CLASSPATH=/data/local/tmp/devicekit.dex app_process / com.mobilenext.devicekit.Clipboard get
# Clear the clipboard
adb shell CLASSPATH=/data/local/tmp/devicekit.dex app_process / com.mobilenext.devicekit.Clipboard clearSince devicekit cannot force a keypress, paste with:
adb shell input keyevent KEYCODE_PASTEPrints the current accessibility hierarchy as JSON to stdout:
adb shell CLASSPATH=/data/local/tmp/devicekit.dex app_process / com.mobilenext.devicekit.UiDumpOptionally wait up to N milliseconds for the UI to go idle first (useful right after a navigation or transition):
adb shell CLASSPATH=/data/local/tmp/devicekit.dex app_process / com.mobilenext.devicekit.UiDump 2000Prints a JSON array of {packageName, appName, version}:
adb shell CLASSPATH=/data/local/tmp/devicekit.dex app_process / com.mobilenext.devicekit.PackageListerWrites a raw H.264 (Annex-B) elementary stream to stdout:
adb exec-out CLASSPATH=/data/local/tmp/devicekit.dex app_process / com.mobilenext.devicekit.AvcServer --scale 0.5 --fps 30 > screen.h264Pipe it straight into a player:
adb exec-out CLASSPATH=/data/local/tmp/devicekit.dex app_process / com.mobilenext.devicekit.AvcServer | ffplay -probesize 32 -sync ext -| Parameter | Type | Default | Description |
|---|---|---|---|
--bitrate |
int (bps) | 10000000 | Target bitrate (min 100000) |
--scale |
float | 1.0 | Output scale, 0.1–2.0 |
--fps |
int | 30 | Frame rate, 1–60 |
Writes a multipart/x-mixed-replace MJPEG stream to stdout:
adb exec-out CLASSPATH=/data/local/tmp/devicekit.dex app_process / com.mobilenext.devicekit.MjpegServer --quality 80 --scale 0.5 --fps 30 > screen.mjpeg| Parameter | Type | Default | Description |
|---|---|---|---|
--quality |
int | 80 | JPEG quality, 1–100 |
--scale |
float | 1.0 | Output scale, 0.1–2.0 |
--fps |
int | 30 | Frame rate, 1–60 |
For repeated UI queries, DeviceKitServer starts once and stays resident,
answering JSON-RPC over a persistent socket instead of paying process startup on
every call. It is instrumentation-based, so it requires the APK to be
installed (build it from source — see below):
# Start the server (leave running or background it)
adb shell am instrument -w com.mobilenext.devicekit/.DeviceKitServerIt listens on localabstract:devicekit. Forward a local port and query it:
adb forward tcp:8080 localabstract:devicekit
curl -s http://localhost:8080 \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"device.dump.ui","params":{"waitUntilIdle":2000}}'
adb forward --remove tcp:8080./gradlew assembleDebugThe dex used by all the app_process tools is inside the built APK:
unzip -o -j app/build/outputs/apk/debug/app-debug.apk classes.dex -d .
adb push classes.dex /data/local/tmp/devicekit.dexTo use the instrumentation-based resident server, install the APK instead:
adb install app/build/outputs/apk/debug/app-debug.apk- Android 10 (API 29) or newer
- Tools run in the
adb shell(uid 2000) context; no root required