Physical button screenshots work fine when you are holding the phone, but they are useless for automated testing, capturing a locked-out edge case, or grabbing a screen state at an exact scripted moment. screencap handles all of that from the command line and, unlike screen recording, needs no time-limit handling since it captures a single instant.
The traditional approach captures the image on-device, then pulls it to the PC:
adb shell screencap -p /sdcard/screen.png
adb pull /sdcard/screen.png .
The -p flag matters: without it, screencap writes raw, uncompressed pixel data rather than a standard PNG, which most image viewers cannot open directly. Forgetting -p is the single most common reason a captured "screenshot" turns out to be an unreadable file.
Piping the output avoids writing anything to the device's storage at all:
adb exec-out screencap -p > screen.png
exec-out streams the command's stdout directly over the ADB connection instead of through a shell session, which avoids the line-ending translation that occasionally corrupts binary output when using plain adb shell with redirection. This is the more reliable one-liner and the one worth memorizing over the two-step version for routine use.
For test automation or a before/after comparison, a simple loop with a timestamped filename avoids overwriting previous captures:
for i in 1 2 3 4 5; do
adb exec-out screencap -p > "screen_$(date +%s).png"
sleep 2
done
This is useful for capturing a UI animation frame-by-frame at known intervals, or for logging screen state at fixed checkpoints during a longer automated test run driven by input tap and input swipe commands.
If more than one device or emulator is connected, adb refuses to guess which one you mean and returns an "more than one device/emulator" error. Specify the target explicitly with -s and the serial number from adb devices:
adb -s R58N123ABCD exec-out screencap -p > screen.png
Apps that set FLAG_SECURE on their window — banking apps, DRM-protected video players, some password managers — block screenshots at the platform level, and screencap respects that flag the same way the hardware button combination does. The captured PNG will show solid black where the protected content would be. This is not a bug in the command; it is the same protection mechanism the OS enforces for the on-device screenshot shortcut, and there is no ADB flag that bypasses it without root and a system-level policy change.
The captured image is always at the device's native rendering resolution, not a scaled-down preview. On a high-density flagship display this can produce files several megabytes in size for a single screenshot; if you are capturing dozens in a script and file size matters, compress afterward on the PC rather than trying to downscale through screencap itself, which has no resize option.
Third-party screenshot utilities from the Play Store typically request storage or accessibility permissions and often add their own edit overlay before saving. For scripted or repeated capture where you just need the raw pixels, screencap through ADB has zero permission overhead beyond the USB debugging authorization already required for any ADB session.
screencap itself has no built-in cropping option — it always captures the full display buffer. If you only need a portion of the screen, the simplest approach is to capture the full image as usual and crop it afterward on the PC with any image tool, rather than trying to solve the problem on-device. Some automated test frameworks work around this by combining a full screencap with known UI element coordinates pulled from uiautomator dump, then cropping programmatically to just the region around a specific element for a visual diff.
screencap only outputs PNG (or the raw uncompressed format without -p); there is no JPEG option. PNG's lossless compression is the right choice for UI screenshots since it preserves sharp text edges and flat color regions without the blocky artifacts JPEG introduces around text, but it does mean a screenshot of a photo-heavy screen produces a noticeably larger file than the same content saved as JPEG would. If storage space for a large batch of captures becomes a problem, convert the PNGs to JPEG or WebP afterward on the PC rather than looking for a device-side flag that does not exist.
screencap grabs whatever is actually being rendered to the display at the moment the command runs, including system UI elements like the status bar and navigation bar, not just the foreground app's content area. This differs from some app-level screenshot APIs that only capture a single activity's view hierarchy. If a notification shade or a system dialog is open when the command runs, it appears in the capture exactly as a manual screenshot would show it, which is generally what you want when documenting a real bug report rather than a curated app-only view.