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

Android has no single screenshot endpoint for every use case. Use MediaProjection when you need the device display or a user-selected app window, and PixelCopy when you need a still image of your own app’s Window or SurfaceView. Both approaches have different permissions, capture scopes, and lifecycle requirements. If by “screenshot API” you mean capturing a website from an Android app or service, that is a different job: ScreenshotNeo captures a URL, not the Android device’s screen.

Choose the Android capture API for the job

Start with the pixels you need. A screenshot of one of your app’s views is not the same as a screenshot of the whole device. Android’s MediaProjection APIs, introduced in Android 5 (API 21), provide user-approved display capture as a media stream. PixelCopy, available from API 24, asynchronously copies pixels from a Window, Surface, or SurfaceView into a Bitmap.

Need Use Capture result Consent and availability
Capture the device display or a user-selected app window MediaProjection A stream of frames delivered to an output surface; you can take a still from a frame or record/process frames. Requires explicit user approval for each new projection session. Available from API 21.
Capture a still of your own Activity window or rendered SurfaceView PixelCopy An asynchronous copy into a supplied Bitmap. No MediaProjection consent flow. Available from API 24; the source must be ready and have rendered content.
Capture a small view hierarchy that does not depend on hardware-only rendering Software Canvas with View.draw() A drawn view snapshot. May omit hardware-only rendering features; not the modern general-purpose screen-capture API.

Android’s View reference recommends PixelCopy for UI screenshots used in feedback reports or unit testing. The old View drawing-cache APIs are deprecated from API 28, so do not start a new screenshot implementation around them.

Capture the device or selected app with MediaProjection

Use this path for screen sharing, recording, OCR across screens, streaming, or another task that genuinely needs display pixels outside your own view hierarchy. Android’s system consent flow is part of the design, not an optional permission to work around. On Android 14 (API 34), the user can choose to share a single app window; that capture excludes system bars, notifications, and other system UI.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Samsung Galaxy A17 5G Smart Phone 128GB US 1 Yr Manufacturer Warranty Black
  • YOUR CONTENT, SUPER SMOOTH: The ultra-clear 6.7" FHD+ Super AMOLED display of Galaxy A17 5G helps bring your content to life, whether you're scrolling through recipes or video chatting with loved ones.¹
  • LIVE FAST. CHARGE FASTER: Focus more on the moment and less on your battery percentage with Galaxy A17 5G. Super Fast Charging powers up your battery so you can get back to life sooner.²
  • MEMORIES MADE PICTURE PERFECT: Capture every angle in stunning clarity, from wide family photos to close-ups of friends, with the triple-lens camera on Galaxy A17 5G.
  • NEED MORE STORAGE? WE HAVE YOU COVERED: With an improved 2TB of expandable storage, Galaxy A17 5G makes it easy to keep cherished photos, videos and important files readily accessible whenever you need them.³
  • BUILT TO LAST: With an improved IP54 rating, Galaxy A17 5G is even more durable than before.⁴ It’s built to resist splashes and dust and comes with a stronger yet slimmer Gorilla Glass Victus front and Glass Fiber Reinforced Polymer back.

Declare the foreground service for apps targeting Android 14 or later

For apps targeting API 34 or later, declare both the general foreground-service permission and the media-projection-specific permission, and mark the service with the mediaProjection type. This is the manifest shape:

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />

<application ...>
    <service
        android:name=".ScreenCaptureService"
        android:exported="false"
        android:foregroundServiceType="mediaProjection" />
</application>

The service also needs to enter foreground state with an appropriate notification when it starts. The manifest declarations alone do not start a foreground service or grant capture consent.

Request consent, then create exactly one projection session

Obtain MediaProjectionManager from Context.MEDIA_PROJECTION_SERVICE, launch its screen-capture consent intent, and wait for the activity result. The following Kotlin shows the core Activity-side handoff using the Activity Result API:

Rank #2
Tracfone Motorola Moto G 2025, 64GB, Saphire Blue (Locked to
  • Carrier: This phone is locked to Tracfone, which means this device can only be used on the Tracfone wireless network. Tracfone plan required, activating is easy, just 3 steps.
  • DISPLAY: Immersive viewing on a 6.7-inch super-bright 120Hz display with powerful stereo speakers and Bass Boost for cinematic entertainment.
  • CAMERA SYSTEM: Advanced 50MP Quad Pixel camera captures sharp, detailed photos and videos in any lighting condition
  • PERFORMANCE: Lightning-fast 5G connectivity paired with a powerful processor and RAM Boost for smooth multitasking.
  • BATTERY LIFE: Long-lasting 5000mAh battery with TurboPower charging technology delivers hours of power in minutes.
private val captureRequest = registerForActivityResult(
    ActivityResultContracts.StartActivityForResult()
) { result ->
    if (result.resultCode == Activity.RESULT_OK && result.data != null) {
        val serviceIntent = Intent(this, ScreenCaptureService::class.java).apply {
            action = ScreenCaptureService.ACTION_START
            putExtra(ScreenCaptureService.EXTRA_RESULT_CODE, result.resultCode)
            putExtra(ScreenCaptureService.EXTRA_RESULT_DATA, result.data)
        }
        ContextCompat.startForegroundService(this, serviceIntent)
    }
}

private fun requestCapture() {
    val manager = getSystemService(Context.MEDIA_PROJECTION_SERVICE)
        as MediaProjectionManager
    captureRequest.launch(manager.createScreenCaptureIntent())
}

Use the result code and returned intent in the service to call getMediaProjection() once for that session. On Android 14 and later, treat the consent result and projection token as single-use for creating a VirtualDisplay. If the user stops the projection or you need a new session, request consent again; do not reuse the old result to create another VirtualDisplay.

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

Connect an ImageReader and account for row stride

For a still image or frame processing, create an ImageReader in RGBA_8888 and pass its surface to createVirtualDisplay(). Choose display dimensions and density from the current display configuration; WindowManager.getMaximumWindowMetrics() and WindowMetrics.getBounds() provide display bounds for this purpose. A selected app window can have different dimensions from the full display.

val imageReader = ImageReader.newInstance(
    width,
    height,
    PixelFormat.RGBA_8888,
    2 // A small queue; promptly close frames you acquire.
)

val projection = projectionManager.getMediaProjection(resultCode, resultData)
projection.registerCallback(object : MediaProjection.Callback() {
    override fun onStop() {
        virtualDisplay?.release()
        imageReader.close()
        projectionRef = null
    }
}, handler)

val virtualDisplay = projection.createVirtualDisplay(
    "Screenshot",
    width,
    height,
    densityDpi,
    DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
    imageReader.surface,
    null,
    handler
)

imageReader.setOnImageAvailableListener({ reader ->
    val image = reader.acquireLatestImage() ?: return@setOnImageAvailableListener
    try {
        val plane = image.planes[0]
        val pixelStride = plane.pixelStride
        val rowStride = plane.rowStride
        val rowPadding = rowStride - pixelStride * width
        val paddedWidth = width + rowPadding / pixelStride
        val padded = Bitmap.createBitmap(
            paddedWidth, height, Bitmap.Config.ARGB_8888
        )
        plane.buffer.rewind()
        padded.copyPixelsFromBuffer(plane.buffer)
        val bitmap = Bitmap.createBitmap(padded, 0, 0, width, height)
        padded.recycle()
        // Save, display, or process bitmap here.
    } finally {
        image.close()
    }
}, handler)

This is the capture core, not a complete service class: your service must establish its foreground notification, retain and release its projection/display/reader references, and handle its own bitmap output destination. The padded row width matters because a plane’s rowStride can exceed width × pixelStride. Copying it as though every row were tightly packed can produce skewed pixels or buffer errors. Acquire the newest available image for still capture, and close each acquired Image promptly so the reader’s limited image queue does not fill.

Rank #3
Samsung Galaxy A17 5G Smart Phone 128GB, US 1 Yr Manufacturer Warranty Blue
  • YOUR CONTENT, SUPER SMOOTH: The ultra-clear 6.7" FHD+ Super AMOLED display of Galaxy A17 5G helps bring your content to life, whether you're scrolling through recipes or video chatting with loved ones.¹
  • LIVE FAST. CHARGE FASTER: Focus more on the moment and less on your battery percentage with Galaxy A17 5G. Super Fast Charging powers up your battery so you can get back to life sooner.²
  • MEMORIES MADE PICTURE PERFECT: Capture every angle in stunning clarity, from wide family photos to close-ups of friends, with the triple-lens camera on Galaxy A17 5G.
  • NEED MORE STORAGE? WE HAVE YOU COVERED: With an improved 2TB of expandable storage, Galaxy A17 5G makes it easy to keep cherished photos, videos and important files readily accessible whenever you need them.³
  • BUILT TO LAST: With an improved IP54 rating, Galaxy A17 5G is even more durable than before.⁴ It’s built to resist splashes and dust and comes with a stronger yet slimmer Gorilla Glass Victus front and Glass Fiber Reinforced Polymer back.

Handle stop, resize, and visibility changes

Register a MediaProjection.Callback before creating the VirtualDisplay. When onStop() fires, release the VirtualDisplay, close the ImageReader, and discard the projection reference. The system can stop capture when the user ends it, the screen locks, another projection starts, or the process dies; cleanup is necessary in every case.

For Android 14 app-window sharing, also handle onCapturedContentResize() and onCapturedContentVisibilityChanged(). Resize both the VirtualDisplay and its output surface when the selected window changes dimensions, or the output can be letterboxed. The visibility callback lets you hide or show a preview when the shared app is fully covered.

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

Capture your own window or SurfaceView with PixelCopy

For a feedback attachment or UI test that needs one still from your app, PixelCopy is usually the narrower, simpler fit. The callback is asynchronous: supply a destination Bitmap, request a copy, and check the result code before using the bitmap.

Rank #4
Samsung Galaxy S26 Ultra, Unlocked Android Smartphone, 512GB, Black
  • PRIVACY DISPLAY: Automatically hide your screen from those beside you. The built-in privacy display can be preset¹ to turn on when receiving notifications, typing passwords, or using specific apps
  • TYPE IT IN. TRANSFORM IT FAST: Enhance any shot in seconds on your smartphone by using Photo Assist² with Galaxy AI.³ Add objects, restore details, or apply new styles by simply typing or tapping
  • NIGHTS, CAPTURED CLEARLY: From gigs to city lights, record and capture moments after dark with clarity using Nightography so your photos and videos stay crisp and clear on your Samsung Galaxy
  • MAKE IT. EDIT IT. SHARE IT: Turn everyday moments into something personal with creative tools built right into your mobile phone, whether it’s a special contact photo, custom wallpaper, an invitation or more⁴
  • HELP THAT KEEPS UP: Stay in the moment while Now Nudge with Galaxy AI helps you respond faster and stay organized with smart suggestions⁵ that appear exactly when you need them on your phone

Copy an Activity window

Wait until the window has a non-null DecorView and has drawn at least once so it has an acquired backing surface. For example, initiate the request after the view is laid out or after a draw callback rather than immediately during Activity creation.

val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
PixelCopy.request(window, bitmap, { result ->
    if (result == PixelCopy.SUCCESS) {
        // Use or save bitmap.
    } else {
        // Handle the error; do not treat bitmap as a valid screenshot.
    }
}, Handler(Looper.getMainLooper()))

Copy a SurfaceView or only a region

For a rendered SurfaceView, use the SurfaceView overload and make the request after its surface has produced content. PixelCopy can also take a source rectangle when you need only part of the window or surface. The selected source is scaled to the destination bitmap and converted to that bitmap’s configuration, so allocate dimensions and memory for the output you actually need.

Troubleshoot failed or incorrect captures

  • MediaProjection consent was canceled: Do not call getMediaProjection() without a successful activity result. Let the user retry by launching the consent intent again.
  • Android 14 rejects a reused projection result: Request fresh consent for a new session and create only one VirtualDisplay from that session’s token.
  • The app fails to start projection on Android 14: For an app targeting API 34 or later, check both foreground-service permissions, the service’s mediaProjection type, and that it enters foreground state as required.
  • Capture is letterboxed or has the wrong dimensions: A selected app window can differ in size from the full display. Use current metrics and update the VirtualDisplay and output surface from onCapturedContentResize().
  • The ImageReader callback stops producing usable frames: Ensure each acquired Image is closed in a finally block and that your app is not holding multiple frames open.
  • PixelCopy returns ERROR_SOURCE_INVALID: The source is not available as a valid copy source. For a Window, verify its DecorView and backing surface exist before requesting the copy.
  • PixelCopy returns ERROR_SOURCE_NO_DATA: The source has not supplied content yet. Wait for at least one draw or for the SurfaceView to render, then request again.
  • PixelCopy returns ERROR_DESTINATION_INVALID: Check that the destination bitmap is valid and correctly created before passing it to PixelCopy.
  • PixelCopy returns ERROR_TIMEOUT or ERROR_UNKNOWN: The copy did not complete successfully. Do not assume the destination is a valid capture; retry only when the source and destination are ready, and handle repeated failure in the calling flow.
  • Capture stops unexpectedly: Treat onStop() as a normal lifecycle event. Release the display and reader there and require a new consent flow for another projection session.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If your goal is to capture a website from Android code—not the Android display—ScreenshotNeo takes a URL through one GET request. It is a website screenshot API, not a replacement for MediaProjection or PixelCopy. Here is a cURL request; the Android client can make the equivalent HTTPS request from its own app or backend. See the ScreenshotNeo API documentation for options.

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.
Best Value
Tracfone Moto g Play 2024 Prepaid Phone with a 1-Yr Plan Included
  • Carrier: This phone is locked to Tracfone, which means this device can only be used on the Tracfone wireless network. Activating is easy, just 3 steps.
  • ACTIVATION Promotion: Includes 1500 min, 1500 texts & 1500 MB Data + add more as you need it
  • CAMERA SYSTEM: 50MP Quad Pixel camera. Capture sharper, more vibrant photos day or night with 4x the light sensitivity.
  • PERFORMANCE: Blazing-fast Qualcomm performance. Get the speed you need for great entertainment with a Snapdragon 680 processor and 4GB of RAM.
  • 64GB built-in storage. Get plenty of room for photos, movies, songs, and apps. Made for US
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 and consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each of those steps can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers identify the page verdict and billing status. Its MCP server offers take_screenshot, get_page_info, and capture_pdf for AI agents using Claude, Cursor, or another MCP client. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. These are website captures, not captures of private Android screen content. Learn more at ScreenshotNeo, or sign up for 1,000 free screenshots a month with no card.

Performance, reliability, and cost considerations

Neither Android API requires buying a screenshot service for local capture. With MediaProjection, the work and resource lifetime belong to your app: keep the number of queued frames small, close images quickly, and release the virtual display and reader on stop. PixelCopy is asynchronous and returns into a bitmap you allocate, so its memory use depends on the destination dimensions and bitmap configuration. Do not retain large bitmaps longer than needed. There are no performance benchmarks here that support a universal claim that one API is faster; the right choice is primarily dictated by capture scope and output model.

If your workflow actually involves remote website URLs, use a website screenshot service rather than opening a browser on-device and attempting to screenshot its UI. ScreenshotNeo bills only clean captures; rejected or failed page outcomes listed above and cache hits are not billed. Its plans include Free (1,000 per month), Starter ($5 for 3,000), Growth ($15 for 15,000), Pro ($39 for 60,000), Scale ($99 for 250,000), and Business ($249 for 1,000,000); yearly billing gives two months free, and every feature is available on every plan. Those service prices apply to URL captures, not Android display capture.

Decision checklist

  • Use MediaProjection if you need the whole device display or a user-selected app window, or need repeated frames.
  • Use PixelCopy if you need a still Bitmap from your own Window or SurfaceView.
  • Use a software Canvas draw only for a limited view snapshot where hardware-only rendering is not essential.
  • Use a website screenshot API only when the input is a URL; it does not take over Android’s protected user-consent screen-capture flow.

Frequently Asked Questions

Can I use MediaProjection to capture just one app on every Android version?

No. User-selectable app-window sharing is an Android 14 (API 34) capability; behavior and available capture scope depend on Android version.

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

Does ScreenshotNeo capture an Android phone’s display?

No. ScreenshotNeo takes a website URL and returns a website screenshot or PDF. For the device display, use Android’s MediaProjection consent flow.

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.