adb Basics
Use Android Debug Bridge to install builds, reset apps, read logcat, capture crash stack traces, open deep links and fake device conditions, all from your terminal.
A tester on a shopping app filed this bug: “App sometimes crashes when opening links.” The developer tried a few links, nothing crashed, and the ticket came back marked Cannot reproduce. Two weeks later a marketing newsletter went out to 400,000 people, and the app crashed for every single one who tapped the sale link.
A second tester picked the ticket up. Ten minutes later they had the exact link, a one-line command that crashed the app every time, the device and app version, and four lines of log ending in DeepLinkParser.kt:27. The fix took twenty minutes.
The difference wasn’t luck. The second tester used adb.
Why it matters
adbadbAndroid Debug Bridge: a command-line tool for installing apps, reading logs and controlling Android devices.Open in glossary → (Android Debug Bridge) is the command-line tool that lets your computer talk to an Android phone, tablet or emulatorEmulatorSoftware that imitates a real device's hardware and OS on your computer, like the Android Emulator.Open in glossary →. For a manual tester it’s a superpower:
- Faster setup: install builds, wipe app data and set up device conditions in seconds, the same way every time.
- Better bug reports: grab the crashCrashWhen an app suddenly closes or stops working because of an unhandled error.Open in glossary → stack trace, screenshots and screen recordings straight to your computer.
- Tests you can’t do by tapping: open any deep linkDeep linkA link that opens a specific screen inside an app instead of just its home screen.Open in glossary →, fake a 5% battery, bump the font size, type long test strings.
- More credibility: a bug report with the exact cause line from logcatLogcatAndroid's system log, read with adb logcat, where apps write errors and crash details.Open in glossary → rarely comes back as “cannot reproduce”.
You don’t need to be a developer. You need about fifteen commands, and you’ll learn them on this page.
What is adb?
adb has three parts. You only ever type the first one:
Your computer
adb client: the adb command you type in the terminal
adb server: runs in the background (port 5037) and keeps track of connected devices
Phone or emulator
adbd: a small service on the device that runs your commands
adb shell … runs a command on the device, for example pm, am, input, dumpsys
A useful mental model: commands like adb install and adb logcat are adb features. Commands after adb shell are Android’s own tools, running on the phone: pm (package manager), am (activity manager), input, settings, dumpsys.
Setting it up
- Install the platform tools. adb is part of Android’s SDK Platform-Tools. If you have Android Studio, it’s already installed in the SDK folder’s
platform-toolsdirectory (paths below). Without Android Studio, download SDK Platform-Tools from developer.android.com, or on a Mac runbrew install --cask android-platform-tools. - Add it to your PATH, so
adbworks in any folder. On macOS with zsh, add theexportline below to~/.zshrcand open a new terminal. Check withadb version. - Turn on Developer options on the phone. Go to Settings › About phone and tap Build number seven times until it says “You are now a developer”. On Samsung it’s under About phone › Software information.
- Turn on USB debugging. Open Settings › System › Developer options (on Samsung, Developer options appear at the bottom of Settings) and switch on USB debugging.
- Connect and allow. Plug in a USB cable. The phone asks “Allow USB debugging?” and shows your computer’s key fingerprint. Tick Always allow from this computer and tap Allow.
- Check the connection. Run
adb devices. Emulators started from Android Studio show up automatically, no setup needed.
# Where Android Studio puts adb
# macOS: ~/Library/Android/sdk/platform-tools
# Windows: %LOCALAPPDATA%\Android\Sdk\platform-tools
# Linux: ~/Android/Sdk/platform-tools
# macOS (zsh): add this line to ~/.zshrc
export PATH="$PATH:$HOME/Library/Android/sdk/platform-tools"
$ adb devices
List of devices attached
38121FDJH00ABC device
emulator-5554 device
State in adb devices | Meaning | What to do |
|---|---|---|
device | Connected and ready | Start testing |
unauthorized | The phone hasn’t accepted this computer yet | Unlock the phone and tap Allow on the prompt. No prompt? Developer options › Revoke USB debugging authorizations, then reconnect |
offline | Connected but not responding | Reconnect the cable, or run adb kill-server and then adb devices |
| (nothing listed) | adb can’t see the phone | Try another cable (some only charge), check USB debugging is on, set USB mode to file transfer |
The commands testers use most
Throughout this lesson the example app is ShopEasy, package name com.shopeasy.app. Every Android app has a unique package name like this; find yours with adb shell pm list packages | grep shop.
Install, update, reset
adb install shopeasy.apk # install an APK
adb install -r shopeasy.apk # reinstall/update and keep app data
adb uninstall com.shopeasy.app # remove the app and its data
adb shell pm clear com.shopeasy.app # wipe app data: like a fresh install, without reinstalling
-r means “replace the existing app”. Recent Android versions replace by default, but -r makes your intent clear and is what you’ll see in most guides. Installing a new version over an old one with its data intact is exactly what users experience from the Play Store, so it’s the heart of upgrade testingUpgrade testingChecking that updating from an older app version keeps the user's data and settings working.Open in glossary →.
pm clear is the tester’s reset button: it signs the user out, clears caches and settings, and shows onboarding again. Use it before every “first launch” test.
| Error | What it means |
|---|---|
INSTALL_FAILED_VERSION_DOWNGRADE | You’re installing an older version over a newer one. Uninstall first (or use -d on debuggable builds) |
INSTALL_FAILED_UPDATE_INCOMPATIBLE | The installed app was signed with a different key (e.g. a Play Store build vs a debug build). Uninstall first |
INSTALL_FAILED_INSUFFICIENT_STORAGE | The device is full |
Read the logs with logcat
Android writes everything that happens into a system log. adb logcat streams it to your terminal until you press Ctrl+C. It’s a lot, so you’ll almost always filter it.
A logcat line looks like this:
10-13 14:02:11.482 4821 4821 E AndroidRuntime: FATAL EXCEPTION: main
└─ date & time ──┘ PID TID │ └── tag ─────┘ └── message ──────────┘
└ level
| Level | Name | Use |
|---|---|---|
V / D | Verbose / Debug | Developer detail, usually noise for testers |
I | Info | Normal events: activity started, request finished |
W | Warning | Something odd but not fatal |
E | Error | Something failed. Crashes are logged here |
F | Fatal | Native crashes and fatal system problems |
adb logcat -c # clear the log before you reproduce a bug
adb logcat '*:E' # only errors and worse, from all tags
adb logcat --pid=$(adb shell pidof -s com.shopeasy.app) # only the running app's lines
adb logcat | grep -i shopeasy # lines that mention the app
adb logcat -b crash # only the crash buffer
adb logcat -d > log.txt # dump the current log to a file and stop
Find a crash stack trace
When an Android app crashes, it writes a block that starts with FATAL EXCEPTION. Find it like this:
adb logcat -c
# ...reproduce the crash on the phone...
adb logcat -d | grep -A 20 "FATAL EXCEPTION"
Here’s how to read the result:
E AndroidRuntime: FATAL EXCEPTION: main ← a crash happened on the main thread
E AndroidRuntime: Process: com.shopeasy.app, PID: 4821 ← which app
E AndroidRuntime: java.lang.RuntimeException: Unable to start activity ... ← wrapper
E AndroidRuntime: at android.app.ActivityThread... ← framework code (skip)
E AndroidRuntime: Caused by: java.lang.NumberFormatException: For input string: "summer-sale" ← root cause
E AndroidRuntime: at java.lang.Integer.parseInt(Integer.java:747) ← Java's code
E AndroidRuntime: at com.shopeasy.app.product.DeepLinkParser.productId(DeepLinkParser.kt:27) ← the app's code!
- Find
FATAL EXCEPTION. It marks the start of the crash. - Jump to the last
Caused by:. That’s the root cause: the exception type and its message. - Find the first line below it from the app’s own package (
com.shopeasy.app…). That file and line number is where developers will start. - Copy from
FATAL EXCEPTIONthrough that line into the bug report. Attach the full log as a file if needed.
Screenshots and screen recordings
adb exec-out screencap -p > screen.png # screenshot straight to your computer
adb shell screenrecord /sdcard/bug.mp4 # record; press Ctrl+C to stop (max 3 minutes)
adb pull /sdcard/bug.mp4 # copy the video to your computer
exec-out sends the raw image bytes back unchanged, so redirecting them with > gives you a valid PNG. screenrecord records video without sound.
Open deep links
adb shell am start -a android.intent.action.VIEW -d "shopeasy://product/42"
adb shell am start -a android.intent.action.VIEW -d "https://shop.example.com/product/42" com.shopeasy.app
am start asks Android to open a link, exactly as if the user had tapped it in an email. Adding the package name at the end forces it to open in that app. This is the fastest way to test deep links, including the nasty ones: unknown IDs, missing parameters, letters where numbers are expected.
Type and press keys
adb shell input text "running%sshoes" # types "running shoes" into the focused field (%s = space)
adb shell input keyevent KEYCODE_ENTER # also KEYCODE_BACK, KEYCODE_HOME (or 66, 4, 3)
adb shell am force-stop com.shopeasy.app # kill the app, e.g. to test a cold start
input text is great for long or tricky test dataTest dataThe input values, accounts and records you use while testing.Open in glossary →: a 200-character name, an email with a plus sign, a coupon code you need to type twenty times.
Fake device conditions
adb shell dumpsys battery unplug # pretend the charger is unplugged
adb shell dumpsys battery set level 5 # pretend the battery is at 5%
adb shell dumpsys battery reset # back to the real battery state
adb shell settings put system font_scale 1.3 # bigger text (1.0 is the default)
adb shell settings put system font_scale 1.0 # back to normal
adb shell cmd uimode night yes # dark theme on (no = off)
font_scale mimics the user’s font size setting. Android 14 and newer allow up to 2.0 (200%), and the large sizes are where truncationTruncationText that gets cut off because it doesn't fit its space.Open in glossary → bugs live. It changes the setting for the whole phone, so set it back afterwards.
Try it: the adb playground
Time to type. The terminal below is fake, so nothing can break, but the commands and outputs follow real adb. Try installing, clearing data, opening a deep link, faking 5% battery, bumping the font size, and reading logcat. Then try shopeasy://product/summer-sale instead of 42, and look at logcat again.
adb playground
A safe fake terminal. Every command changes the phone on the right.
Tip: ↑ / ↓ recall earlier commands. Type clear to empty the screen.
Hi, Ana
2Popular this week
Cheat sheet · click to paste into the terminal
Devices
Install & reset
Open & control
Logs
Evidence
Device conditions
Wireless & network
Wireless debugging
No cable? Since Android 11 you can use adb over Wi-Fi. The phone and computer must be on the same network.
- On the phone, open Developer options › Wireless debugging and switch it on.
- Tap Pair device with pairing code. The phone shows an IP address with a port and a six-digit code.
- On your computer run
adb pair 192.168.1.23:37199(use the address shown) and enter the code. - Recent adb versions often connect automatically after pairing. If not, go back to the Wireless debugging screen and note the IP address & Port. It’s a different port from the pairing one. Run
adb connect 192.168.1.23:41235. - Check with
adb devices. The phone now appears with its IP address.
Android Studio can do the same with a QR code: Device Manager › Pair Devices Using Wi-Fi. On Android 10 and older, connect once by USB, run adb tcpip 5555, unplug, then adb connect <phone-ip>:5555.
What to test with adb
Fresh state and upgrades
- First launch:
pm clear, then open the app. Onboarding, permission prompts and empty states should all appear. - Upgrade: install the old version, create data (log in, fill the cart), then
adb install -rthe new version. Nothing should be lost. - Reinstall:
uninstalltheninstall. The app must not crash on missing data.
Entry points
- Deep links with valid, unknown, deleted and malformed IDs, missing parameters, and while logged out.
- Cold start vs warm start:
am force-stop, then open the deep link.
Device conditions
- Low battery (5%, unplugged): does the app reduce background work? Does it still function?
- Large fonts (1.3, 1.5, 2.0): no clipped buttons, no text running off the screen.
- Dark theme switched while the app is open.
Evidence
- Clear logcat, reproduce, and save the crash block for every crash or freeze.
- Record a video of anything that’s hard to describe.
Bugs adb helps you find
| # | Bug | What you see | Typical severity |
|---|---|---|---|
| 1 | Crash on unexpected deep link input | Letters, an unknown ID or a missing parameter in a link closes the app | High |
| 2 | Crash on first launch after clearing data | App assumes a saved token exists; after pm clear it crashes instead of showing login | High |
| 3 | Data lost on upgrade | After install -r the user is logged out or the cart is empty | High |
| 4 | Layout breaks at large font scale | At font_scale 1.3 buttons are clipped or the Pay button moves off-screen | Medium |
| 5 | No low-battery handling | At 5% the app keeps heavy background syncing or video autoplay | Low–Medium |
| 6 | Hidden errors | No visible problem, but logcat shows repeated E lines, e.g. failing API calls on every screen | Medium |
| 7 | Deep link ignores login state | A link opens an account page without asking the logged-out user to sign in | High |
Practice: investigate the crash
A real support ticket just came in. Use the terminal to reproduce the crash, find the FATAL EXCEPTION, click the exact cause line, and decide what evidence goes into the bug report.
Investigate the crash
Reproduce it, read the log, and build the evidence for a bug report.
Support ticket SUP-2291
"I tapped the Summer Sale link in your newsletter and the app closed. Tried 3 times." The newsletter link is shopeasy://product/summer-sale.
- 1. Reproduce the crash
- 2. Find the FATAL EXCEPTION
- 3. Pinpoint the cause line
- 4. Assemble the evidence
Step 1 · Reproduce the crash
Clear the old log first, so the crash is easy to find. Then open the newsletter link on the phone. Click a command to paste it, then press Enter.
Hi, Ana
2Popular this week
Example test cases
TC-ADB-001First launch after clearing app data shows onboardingpositivehigh
Preconditions
- ShopEasy installed, user logged in
- Device connected, adb devices shows "device"
Steps
- Run adb shell pm clear com.shopeasy.app
- Open ShopEasy from the launcher
Expected result
The onboarding screen with Log in / Create account is shown. No crash, no previous user data.
TC-ADB-002Upgrade keeps the session and cartpositivehigh
Preconditions
- ShopEasy 2.3.0 installed
- User logged in with 2 items in the cart
Steps
- Run adb install -r shopeasy-2.4.1.apk
- Open ShopEasy
Expected result
The user is still logged in and the cart shows the same 2 items.
TC-ADB-003Product deep link opens the product pagepositivehigh
Steps
- Run adb shell am start -a android.intent.action.VIEW -d "shopeasy://product/42"
Expected result
ShopEasy opens on the "Trail Runner X" product page.
TC-ADB-004Deep link with a non-numeric product ID is handlednegativehigh
Steps
- Run adb logcat -c
- Run adb shell am start -a android.intent.action.VIEW -d "shopeasy://product/summer-sale"
- Run adb logcat -d | grep "FATAL EXCEPTION"
Expected result
The app shows a friendly "Product not found" screen (or the sale page). No FATAL EXCEPTION in logcat.
TC-ADB-005Checkout is usable at 130% font scaleedgemedium
Steps
- Run adb shell settings put system font_scale 1.3
- Open the cart and go to checkout
- Scroll to the bottom
Test data
Reset afterwards: adb shell settings put system font_scale 1.0
Expected result
All labels are readable and the Pay button is fully visible and tappable.
TC-ADB-006Low battery reduces background workedgelow
Steps
- Run adb shell dumpsys battery unplug
- Run adb shell dumpsys battery set level 5
- Browse the home feed for 1 minute
Test data
Reset afterwards: adb shell dumpsys battery reset
Expected result
The app keeps working; image prefetching / autoplay is paused as specified.
Tip: click a test case to expand it.
Checklist
adb testing checklist
0 of 11 checked
Check your understanding
Quick quiz
0/5 answered · 0 correct
1.Which command resets an app to a fresh-install state without reinstalling it?
2.adb devices shows your phone as "unauthorized". What do you do?
3.In a crash stack trace, which line should you point developers to first?
4.You run adb logcat --pid=$(adb shell pidof -s com.shopeasy.app) after the app crashed and get an error. Why?
5.You set the battery to 5% with dumpsys but the app shows no low-battery behavior. What is the most likely reason?
Key takeaways
- adb connects your computer to Android devices and emulators over USB or Wi-Fi. Set it up once: platform-tools, Developer options, USB debugging, allow the computer.
- Install and reset fast:
install,install -r,uninstall,shell pm clear. - logcat is your evidence: clear it, reproduce, filter with
'*:E',--pidorgrep, and find FATAL EXCEPTION, the last Caused by and the first line of app code. - Fake conditions: deep links with
am start, typing withinput, battery withdumpsys battery, text size withfont_scale. Always reset afterwards. - Put the adb command and the stack trace excerpt in your bug report, and “cannot reproduce” becomes rare.
Finished this page?Nice work, this page is complete!
Mark it as done to track your progress. It's saved in this browser, no account needed.
Its review cards are now in Bites ⚡