adb (Android Debug Bridge) is the command-line bridge between your development machine and a running Android device or emulator — most Android troubleshooting eventually comes back to one of these commands.
Checking what's connected
adb devices # list connected devices/emulators
adb devices -l # with more detail (model, product)A device shows as unauthorized until you accept the "Allow USB debugging?" prompt on the device itself — a common first-time-connection speed bump worth knowing to look for.
Installing and managing apps
adb install app-debug.apk # install an APK
adb install -r app-debug.apk # reinstall, keeping existing data
adb uninstall com.example.myapp # remove an app by package name
adb shell pm list packages # list all installed packages
adb shell pm list packages | grep myapp # find your app's exact package name-r (reinstall) is the one to remember for iterating on a build without wiping the app's local data (login state, cached content) on every install.
Reading logs
adb logcat # stream all device logs
adb logcat -s MyAppTag # filter to a specific log tag
adb logcat *:E # only Error-level and above
adb logcat -c # clear the log bufferlogcat without filters is famously noisy — filtering by tag (-s YourTag) or severity (*:E) is what makes it actually usable for finding a specific issue instead of scrolling past unrelated system noise.
File transfer
adb push local-file.txt /sdcard/ # copy a file TO the device
adb pull /sdcard/screenshot.png ./ # copy a file FROM the deviceUseful for grabbing a file the app wrote to device storage, or pushing test fixtures onto the device without going through the app's own UI.
Screenshots and screen recording
adb shell screencap -p /sdcard/screen.png
adb pull /sdcard/screen.png ./
adb shell screenrecord /sdcard/demo.mp4
# Ctrl+C to stop, then:
adb pull /sdcard/demo.mp4 ./screenrecord is genuinely useful for capturing a bug reproduction to attach to a ticket, without needing a separate screen-recording tool.
Interacting with the device directly
adb shell input tap 500 1000 # simulate a tap at coordinates
adb shell input text "hello" # type text into a focused field
adb shell input keyevent KEYCODE_HOME # simulate a hardware key press
adb reboot # reboot the deviceUseful for scripting a repeatable interaction sequence without manually tapping through the same steps on every test run.
Port forwarding — reaching a local dev server from the device
adb reverse tcp:3000 tcp:3000adb reverse makes localhost:3000 on the device forward to localhost:3000 on your development machine — the standard way an app running on a physical device (or emulator) reaches a local dev server without needing your machine's real network IP address.
Wireless debugging (no cable required)
adb pair 192.168.1.50:41235 # pair using the code shown on-device
adb connect 192.168.1.50:41235 # connect over the same Wi-Fi networkBoth the device and computer need to be on the same network — this is the modern replacement for the older adb tcpip workflow, set up from Developer Options → Wireless debugging on the device.
Inspecting device and app state
adb shell dumpsys battery # battery stats, useful for simulating low-battery states
adb shell dumpsys activity activities # current activity stack
adb shell getprop ro.build.version.release # Android version on this device
adb shell wm size # screen resolutiondumpsys exposes a huge amount of system state most developers never dig into — battery, memory, activity stack, and dozens of other subsystems, each queryable by name. It's verbose, but genuinely the fastest way to answer "what does the system actually think is happening right now" for a specific subsystem.
Clearing app data without uninstalling
adb shell pm clear com.example.myappThis resets an app to a fresh-install state (clears its data, cache, and permissions) without actually uninstalling and reinstalling it — faster for testing a genuine first-run experience repeatedly than a full uninstall/reinstall cycle, and it preserves the APK itself so there's no re-transfer needed.
Scripting a full install-and-launch cycle
Combining a few commands into one script is a common time-saver for repeated manual testing during development:
#!/bin/sh
adb install -r app-debug.apk
adb shell am start -n com.example.myapp/.MainActivity
adb logcat -s MyAppTagam start -n <package>/<activity> launches a specific activity directly, without tapping the app icon manually — combined with install -r and a filtered logcat, this turns "rebuild, reinstall, relaunch, watch logs" into a single command run after every build.
Multiple connected devices
With more than one device or emulator connected, most commands need -s to target a specific one — otherwise adb either picks arbitrarily or errors if it can't decide:
adb devices
# emulator-5554 device
# R58N4058RTM device
adb -s emulator-5554 install app-debug.apk
adb -s R58N4058RTM logcatScripting against multiple devices simultaneously (running the same install/test across every connected device or emulator) is a common real use case for this — looping over adb devices output and running a command with -s per device.
Common mistakes
- Running
adb logcatwith no filter and trying to manually scroll past unrelated system noise to find one app's output — filter by tag or severity from the start instead. - Forgetting
-rwhen reinstalling during iterative development, wiping local app data (and any manually-set-up test state) on every single install. - Confusing
adb push/adb pulldirection — push sends TO the device, pull retrieves FROM it; mixing them up is a common typo that fails clearly but wastes a moment figuring out why. - Assuming a device showing in
adb devicesasunauthorizedis a connection problem rather than a pending on-device permission prompt — check the device screen first before troubleshooting cables or drivers.
Related reading
- Android App Permissions: A User's Guide to Staying Safe — shares tags: android (same category).
- Getting Started with Android Emulator for Testing — shares tags: android.
- iOS Simulator vs. Physical Device Testing: What Actually Differs — shares tags: programming.
- Essential Linux Commands Every Developer Should Know — shares tags: programming.
- Regular Expressions Explained: A Practical Guide for Developers Who Avoid Them — shares tags: programming.