What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

The right Java screenshot API depends on what you need to capture. For a UI test of the whole device, use AndroidX UiDevice or instrumentation’s UiAutomation. For one app window in a UI test, Android 14 (API 34) adds UiAutomation.takeScreenshot(Window). For a screenshot feature inside an ordinary app, use MediaProjection and obtain the user’s consent through Android’s system flow. These approaches have different access, lifecycle and failure-handling requirements; they are not interchangeable.

Choose the screenshot method by context and scope

First decide who initiates capture and what area the result should contain. A test harness can capture across app boundaries; a normal app feature must use the user-approved screen-capture flow. If you only need to validate one view, prefer a targeted view or Compose-node capture when the testing setup supports it, rather than making the entire display a visual assertion artifact.

Need Java approach Important constraint
Whole device during a UI test AndroidX UiDevice.takeScreenshot(...) or UiAutomation.takeScreenshot() Run it from instrumentation/UI automation code; check for a null bitmap or unsuccessful file save.
One window during a UI test UiAutomation.takeScreenshot(Window) Added in API 34; a window that has not completed layout or lacks a valid surface may produce no bitmap.
Capture feature used by an app’s user MediaProjectionManager, then MediaProjection and a VirtualDisplay Requires system-mediated user consent and lifecycle cleanup; foreground-service rules depend on target SDK.
Visual validation of a single view or Compose node Use a targeted capture supported by the project’s test tooling A whole-screen capture is mainly a debugging aid and can include unrelated UI.

Android’s Instrumentation reference says: “A typical test case should be using either the UiAutomation or Instrumentation APIs.” It notes that using both is possible, but the test author needs to understand their limitations. Instrumentation.getUiAutomation() supplies a UiAutomation instance, whose APIs can work across application boundaries.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Capture a whole-device screenshot in a UI test

Use AndroidX UiDevice when you want a bitmap or PNG file

UiDevice offers convenient screenshot methods that return a Bitmap or save a PNG to a supplied File. Its file method returns true on success and false otherwise; the bitmap method can return null. The API adjusts for display rotation. The file method uses original scale and 90% quality by default. Its overload accepts scale and quality, with quality documented from 0 to 100. The API reference describes the destination as a File; choose a location appropriate to your test environment rather than assuming a particular durable storage location or app permission model. See the UiDevice API reference for the version used by your project.

Example instrumentation test, assuming the AndroidX UI Automator dependency is already included and the test runs under instrumentation:

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import android.graphics.Bitmap;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.uiautomator.UiDevice;
import java.io.File;
import org.junit.Test;

public class ScreenshotTest {
    @Test
    public void captureDeviceScreenshot() {
        UiDevice device = UiDevice.getInstance(
                InstrumentationRegistry.getInstrumentation());

        File output = new File(
                InstrumentationRegistry.getInstrumentation()
                        .getTargetContext().getCacheDir(),
                "device-shot.png");

        boolean saved = device.takeScreenshot(output);
        assertTrue("Screenshot could not be saved", saved);

        Bitmap bitmap = device.takeScreenshot();
        assertNotNull("Screenshot bitmap was null", bitmap);
        bitmap.recycle();
    }
}

This example checks both output forms; in a real test, save only what you need. A cache-directory file is useful as test output only if your runner or test workflow collects it before the cache is cleared. The API’s boolean indicates that the screenshot was created successfully, not that your build system has archived the file.

Use UiAutomation for direct instrumentation access

UiAutomation.takeScreenshot() has been available since API 18 and returns a Bitmap or null. Obtain the automation instance from the active instrumentation rather than treating it as a normal production-app API.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import android.app.Instrumentation;
import android.app.UiAutomation;
import android.graphics.Bitmap;
import androidx.test.platform.app.InstrumentationRegistry;

Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
UiAutomation automation = instrumentation.getUiAutomation();
Bitmap screenshot = automation.takeScreenshot();
if (screenshot == null) {
    throw new AssertionError("UiAutomation did not return a screenshot");
}
try {
    // Use or encode the bitmap as required by the test.
} finally {
    screenshot.recycle();
}

The example is a fragment for an instrumentation test, not an Activity method. Keep screenshot work and any bitmap processing bounded so that large captures do not linger in memory. The return value is the first failure signal to handle; do not pass a possible null onward to image comparison or file encoding.

Capture one window in a UI test on API 34 or later

Android 14 (API 34) added the UiAutomation.takeScreenshot(Window) overload. It is useful when the test needs a particular window rather than the whole display. It can return null if the window has not completed layout, does not have a valid SurfaceControl, or SurfaceFlinger reports an error. See the UiAutomation API reference.

import android.app.UiAutomation;
import android.graphics.Bitmap;
import android.view.Window;

// Run in an instrumentation/UI automation test on API 34 or later.
UiAutomation automation = instrumentation.getUiAutomation();
Window window = activity.getWindow();
Bitmap screenshot = automation.takeScreenshot(window);
if (screenshot == null) {
    throw new AssertionError(
            "Window screenshot unavailable; verify layout and window surface");
}
try {
    // Compare, save, or inspect the bitmap.
} finally {
    screenshot.recycle();
}

Use the window overload only when the test’s device/API environment supports it. If a screenshot is intermittently null, wait for the target window to finish layout and become visible before capture; retrying immediately without checking readiness can simply repeat the same failure. Avoid silently falling back to a full-device image if that would make the test validate a different scope.

Capture screen content from a regular app with MediaProjection

An app feature that captures screen content uses MediaProjectionManager, not the UI-test screenshot methods. The system consent flow asks the user to allow capture. After a successful activity result, pass its result code and data to getMediaProjection(...), then direct the projection to a Surface through a VirtualDisplay. The API has been available since API 21. The Android references also document a MediaProjectionConfig overload added in API 34; choose capture scope and overload based on the project’s API and current platform requirements.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Lifecycle outline

  1. Obtain MediaProjectionManager and launch the intent returned by createScreenCaptureIntent() to display Android’s consent UI.
  2. If the user declines or the result is otherwise unsuccessful, stop the flow and update the app UI; do not attempt to create a projection from an absent result.
  3. On success, call getMediaProjection(resultCode, data) using the returned result values.
  4. Create the output Surface for the capture pipeline and register a MediaProjection.Callback before creating the virtual display.
  5. Call createVirtualDisplay(...) with that surface as the destination, then process frames according to the app’s intended feature.
  6. When onStop() runs, release the VirtualDisplay, the Surface, and related resources, and update the UI to show that capture has ended.

The callback is essential to orderly shutdown. Android can stop a projection if the user stops it through system UI, the screen locks, or another projection session starts. Do not assume a projection remains active for the lifetime of an Activity.

Consent and target-SDK requirements

Current MediaProjection requirements include a media-projection foreground service for apps targeting Android Q (API 29) or later. The API reference also describes ordering and permission requirements for apps targeting Android U (API 34) or later. These rules are version-sensitive: check the current MediaProjectionManager reference and MediaProjection reference against the app’s target SDK, manifest and intended capture lifecycle before shipping. Do not copy a manifest or service recipe for a different target SDK without confirming its requirements.

This is an architectural outline rather than a drop-in capture implementation: actual Java code must also choose a frame/output strategy, manage the surface dimensions and format, and handle consent denial and service lifecycle for the app’s target SDK. The official API references above define the consent, projection and stopping behavior to implement.

Prefer targeted captures for isolated visual checks

A full-device screenshot is often the wrong artifact for validating one component: status/navigation UI, transient banners or unrelated screen content can make comparisons unstable. Capture the view or Compose node under test when the project’s tooling supports that scope. AndroidX describes DeviceCapture as a debugging-oriented whole-screen helper and experimental, not as a general replacement for focused assertions. Consult the DeviceCapture reference for its current status and usage context.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Troubleshoot failed or unusable captures

  • UiDevice.takeScreenshot(File) returns false: treat the save as failed. Check that the test can write to the chosen destination and that the test runner can collect the file; use a different test-appropriate output location if needed.
  • takeScreenshot() returns null: handle it before bitmap operations. For UiAutomation, confirm capture is running through instrumentation/UI automation. For a window capture, verify API 34+ and that the window is laid out and has a valid surface.
  • Window capture fails while whole-device capture works: the methods capture different scopes. Inspect window readiness and surface availability rather than assuming the API should return the whole display.
  • MediaProjection consent is declined: no projection is available. Return to a clear non-capturing app state and let the user initiate consent again if appropriate.
  • Projection stops unexpectedly: handle onStop() as a normal lifecycle event. Release display and surface resources, stop dependent processing, and reflect the ended state in the UI.
  • Foreground-service or permission failure: compare the manifest, service startup order and permissions with the official requirements for the app’s target SDK, especially for Android Q+ and Android U+ targets.
  • Visual test changes for unrelated UI: narrow the capture to the view or Compose node under test where possible, or stabilize the full-screen test setup so unrelated content is controlled.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Performance, reliability and cost considerations

For tests, capture only when the image is needed and release bitmap memory after comparison or encoding. Saving a PNG produces an artifact but adds file I/O; a returned bitmap avoids that file step when the test can consume it directly. Device rotation is handled by the documented UiDevice screenshot methods, but your test should still assert the expected dimensions or orientation if those matter to the result.

Reliability depends on waiting for the correct capture boundary: the app/window must be ready for test screenshots, while a MediaProjection capture must remain authorized and active. Whole-device artifacts can vary with system UI and device state; narrower visual checks reduce unrelated sources of difference. The cited Android API references specify return values and lifecycle behavior, but do not establish a universal capture-time or performance figure, so benchmark on the devices and test environment that matter to your project.

Or skip the browser setup

If the thing you need is a screenshot of a website rather than an Android device or app window, ScreenshotNeo is a website screenshot API and MCP server for developers. It is not a substitute for Android instrumentation or MediaProjection. A single GET request can return PNG, JPEG, WebP or PDF; the API also supports full-page capture, selectors, device presets, waits, custom CSS and JavaScript, and other capture options. See the ScreenshotNeo documentation for request parameters and output details.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

ScreenshotNeo accepts cookie/consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups and chat widgets before capture; each step can be turned off. Bot checks/CAPTCHAs, blank pages, timeouts, failed loads and cache hits cost nothing, and responses identify the page verdict and billing status in headers. Its MCP server provides take_screenshot, get_page_info and capture_pdf for Claude, Cursor and other MCP clients. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Sign up for ScreenshotNeo’s free plan to get 1,000 screenshots a month with no card.

Frequently Asked Questions

Can a normal Android app call UiAutomation.takeScreenshot() to capture another app?

The screenshot methods discussed here belong in instrumentation/UI automation, not as a general production-app capture API. A user-facing app capture feature should use MediaProjection and its consent flow.

Which method should I use to save a screenshot in a Java UI test?

Use UiDevice.takeScreenshot(File) when a PNG file artifact is needed; use its bitmap-returning method or UiAutomation.takeScreenshot() when the test can consume a Bitmap directly. Check the documented return value in either case.

Does MediaProjection capture start without asking the user?

No. The app launches Android’s screen-capture consent flow and can proceed only after a successful result.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.