ScreenshotNeo

BlogGuides

Essential ADB Shell Commands for Android

A practical ADB command reference for connecting to Android, managing apps, transferring files, capturing screenshots, and reading logs safely.

By the ScreenshotNeo team1 October 20269 min read

What are the essential ADB shell commands for Android? Start with adb devices to verify the connection, select a target with -s SERIAL when necessary, and use adb shell to run commands on the device. The most useful command groups are package management with pm, activity control with am, file transfer with push/pull, screenshots with screencap, and diagnostics with logcat.

ADB (Android Debug Bridge) is included in Android SDK Platform Tools. It has a workstation client, a background server on the workstation, and a device daemon. It works with physical devices and emulators and exposes a shell on the Android target. See the official ADB documentation.

1. Install Platform Tools and connect Android

Install or update Platform Tools through Android Studio’s SDK Manager, sdkmanager, or the standalone download. Platform Tools updates are designed to work with earlier Android platform versions; keep the installation current when troubleshooting connection problems.

USB debugging

  1. On the device, enable Developer options, then enable USB debugging.
  2. Connect with a USB data cable. Check both the device and computer ports and confirm that the cable supports data transfer.
  3. Run:
adb devices

On Android 4.2.2 (API 17) and later, unlock the device and approve the RSA debugging prompt for your computer. A status of device means ADB is ready; unauthorized means approval is still pending.

Wireless debugging

Phones running Android 11 (API 30) and later support the wireless-debugging workflow documented by Android. Pair the workstation and device from Developer options, keep both on the same network, then connect using the address and pairing code shown by Android. TV and Wear OS have different minimum-version requirements, so follow the device-specific instructions rather than assuming the phone menu exists.

2. Always identify the target

With one target, most commands can omit a selector. With multiple devices or emulators, explicitly choose the serial shown by adb devices. This prevents installing an APK, changing permissions, or collecting logs from the wrong target.

adb devices -l
adb -s SERIAL shell
adb -d shell              # physical USB device
adb -e shell              # emulator

Replace SERIAL with the exact value from adb devices. Treat -d and -e as convenience selectors, not as a substitute for checking the list.

3. Enter and explore the device shell

adb shell
# now commands run on Android
getprop
ls /sdcard
df -h
exit

Run a single device-side command without opening an interactive shell:

adb shell getprop
adb shell ls -la /sdcard
adb shell df -h

Availability and output of general utilities vary by Android build. Use adb shell, cmd -l, device help output, and the contents of /system/bin to discover what a particular target provides.

Quoting across two shells

Your workstation shell parses the outer command, then Android parses the command passed to adb shell. Quote values containing spaces and test them on the target. Platform Tools 23 and later changed argument handling, so scripts that rely on ambiguous quoting can behave differently across old environments.

# The quoted argument is passed as one value
adb shell am broadcast -a com.example.ACTION --es message "hello android"

# Prefer an explicit shell when using operators
adb shell 'ls /sdcard | head -n 20'

4. Inspect and manage packages with pm

pm is Android’s package-manager command. Read the effect of each state-changing operation before running it, especially on a personal device.

adb shell pm list packages
adb shell pm list packages -3                 # commonly third-party packages
adb shell pm path com.example.app             # APK path
adb shell pm dump com.example.app             # package details
adb shell pm clear com.example.app            # deletes the app's data
adb shell pm uninstall com.example.app       # removes the app for the user

Package-list flags and output can vary by Android release. Confirm the package name before using clear, uninstall, disable-user, or other state-changing commands.

Install an APK

adb install path/to/app.apk
adb install -r path/to/app.apk       # replace an existing install, keeping data when possible
adb install -t path/to/test.apk      # allow a test APK

Installation can fail because the APK is incompatible with the device ABI, has a signature conflict, lacks a required test flag, or is blocked by device policy. Read the complete error text before retrying.

Grant and revoke runtime permissions

adb shell pm grant com.example.app android.permission.CAMERA
adb shell pm revoke com.example.app android.permission.CAMERA

These operations depend on Android version, the permission’s protection level, and whether the permission is declared in the app manifest. They are primarily useful for debugging and automated testing. A grant changes app behavior and user privacy state; a revoke can make an app fail at runtime.

5. Start and stop activities with am

am is the activity manager. It can launch an activity or intent and stop an app process.

adb shell am force-stop com.example.app
adb shell am start -a android.intent.action.VIEW -d "https://example.com"
adb shell am start -n com.example.app/.MainActivity

The activity component must exist and be exported or otherwise launchable under the device’s rules. An intent may resolve to a different app than expected if several handlers are installed. Use adb shell cmd package resolve-activity --brief ... where supported to inspect resolution.

6. Transfer files with push and pull

adb pull /sdcard/Download/example.txt ./example.txt
adb push ./example.txt /sdcard/Download/example.txt
adb pull /sdcard/Download ./download-copy

Use app-specific storage paths and the media directories that your Android version permits. A path may exist on one build and be inaccessible on another because of scoped storage or permissions. For repeatable scripts, check the destination with adb shell ls -ld PATH first.

7. Capture an Android screenshot

Capture directly to the workstation with exec-out; it avoids adding shell text around the binary image.

adb exec-out screencap -p > screen.png

You can also write on the device and retrieve the file:

adb shell screencap -p /sdcard/screen.png
adb pull /sdcard/screen.png ./screen.png
adb shell rm /sdcard/screen.png

If the result is empty or corrupted, verify that the device is awake, that the target selector is correct, and that your workstation shell is not transforming binary output. Use exec-out for streaming image bytes.

8. Read and filter logs with logcat

adb logcat
adb logcat ActivityManager:I MyApp:D *:S
adb logcat '*:W'

A filter expression sets a minimum priority per tag. In the second example, ActivityManager messages at informational level and MyApp messages at debug level are shown, while *:S silences other tags. Quote the wildcard in shells that expand *. Logcat options and buffer behavior vary by Android version; some options require root. The Android logcat reference lists release-specific options.

Useful log workflow

# Clear old messages, reproduce the problem, then save new output
adb logcat -c
adb logcat -v threadtime > run.log
# Press Ctrl-C after reproducing the issue

# Filter an existing stream by tag and priority
adb logcat ActivityManager:I MyApp:D '*:S'

Do not paste production logs into tickets without checking for tokens, personal data, URLs, or account identifiers.

9. A complete repeatable diagnostic sequence

#!/usr/bin/env bash
set -euo pipefail

serial="${1:?usage: $0 SERIAL PACKAGE}"
package="${2:?usage: $0 SERIAL PACKAGE}"

adb -s "$serial" wait-for-device
adb -s "$serial" get-state
adb -s "$serial" shell getprop ro.build.version.release
adb -s "$serial" shell pm path "$package"
adb -s "$serial" shell am force-stop "$package"
adb -s "$serial" shell am start -n "$package/.MainActivity"
adb -s "$serial" exec-out screencap -p > "${package}.png"
adb -s "$serial" logcat -d -v threadtime "$package:D" '*:S' > "${package}.log"

The component name may differ from PACKAGE/.MainActivity; replace it with the activity your app declares.

10. Python and Node.js wrappers

Python

import subprocess
from pathlib import Path

serial = "SERIAL"
package = "com.example.app"

def adb(*args, binary=False):
    result = subprocess.run(
        ["adb", "-s", serial, *args],
        check=True,
        capture_output=True,
    )
    return result.stdout if binary else result.stdout.decode(errors="replace")

print(adb("get-state"))
print(adb("shell", "pm", "path", package))
adb("exec-out", "screencap", "-p", binary=True)
Path("screen.png").write_bytes(adb("exec-out", "screencap", "-p", binary=True))

Node.js

import { execFile } from "node:child_process";
import { promisify } from "node:util";
import { writeFile } from "node:fs/promises";

const run = promisify(execFile);
const serial = "SERIAL";
const adb = (...args) => run("adb", ["-s", serial, ...args], { encoding: "buffer" });

const state = await adb("get-state");
console.log(state.stdout.toString());
const shot = await adb("exec-out", "screencap", "-p");
await writeFile("screen.png", shot.stdout);

Keep the serial and package values configurable. Check exit codes and capture stderr so a disconnected device fails clearly instead of producing a misleading empty file.

11. Troubleshooting

Symptom Likely cause Fix
adb: command not found Platform Tools are missing or not on PATH. Install Platform Tools and add its directory to PATH, or invoke the binary by absolute path.
unauthorized The device has not approved the computer’s RSA key. Unlock the device, accept the prompt, then run adb devices again. Revoke USB debugging authorizations in Developer options if the prompt is stuck.
No device listed USB debugging, cable, driver, network pairing, or server issue. Try a known data cable and port, check Developer options, verify wireless pairing and same network, then restart ADB with adb kill-server followed by adb devices.
more than one device/emulator ADB cannot choose a default target. Use -s SERIAL, -d, or -e.
INSTALL_FAILED_... Signature, ABI, version, storage, policy, or test-install mismatch. Read the exact suffix, uninstall conflicting debug builds when appropriate, verify ABI and signing, free storage, or add -t for a test APK.
Security exception for pm grant Permission is not declared, not grantable, or restricted on this Android version. Check the manifest and permission protection level; use the app’s runtime request flow when required.
Screenshot is blank or malformed Device is locked, wrong target selected, or binary output passed through a text shell. Wake and unlock the target, use -s SERIAL, and use adb exec-out screencap -p > screen.png.
Logs are too noisy or missing Filter expression, cleared buffers, OS differences, or privilege restrictions. Use tag/priority filters, confirm the app tag, run adb logcat -b all where supported, and check the logcat reference for device-specific options.

12. Safety, performance, reliability, and cost

  • Safety: Treat uninstall, clear-data, disable, permission, property, and install-location commands as state changes. Confirm the target serial and package before running them. Android notes that changing install location is intended for debugging and can break apps.
  • Reliability: Wait for device state, use explicit serials, quote arguments, check exit codes, and collect stderr. Restart a hung server with adb kill-server; the next ADB command starts it again.
  • Performance: Avoid repeatedly opening interactive shells in automation. Batch related operations, use exec-out for binary streams, and filter logs at the source when collecting long runs.
  • Wireless trade-offs: Wireless debugging removes the cable but adds pairing, same-network, and network-stability requirements. USB is usually simpler when a reliable data cable is available.
  • Cost: ADB and Platform Tools do not charge per command. Your costs are the development computer, device or emulator resources, storage, and optional hardware such as a compatible USB data cable.

Or skip the browser setup

ADB captures an Android device screen. For website screenshots, ScreenshotNeo provides a one-request API that returns PNG, JPEG, WebP, or PDF. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing status.

See the ScreenshotNeo API documentation for all options. A minimal request:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' }); const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo also has an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. One thousand screenshots per month are free with no card; paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.

FAQ

Should I use adb shell or adb exec-out?

Use adb shell for text commands executed on Android. Use exec-out when streaming binary output such as a PNG directly to the workstation.

How do I know which device a command affected?

Run adb devices -l first and pass the selected serial with -s SERIAL on every command in scripts.

Can ADB bypass Android security restrictions?

No. Device policy, app permissions, exported-component rules, OS version, and root status still apply. Some diagnostic options are root-only.

Why does a command work on one Android version but not another?

ADB transport is broadly compatible, but device-side utilities, flags, permissions, storage rules, and logcat options change across releases and manufacturer builds. Check help output and the Android documentation for the target version.