You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android平台下如何获取包含Dialog与Toast在内全部界面元素的像素位图?

Full Screen Capture Including Toasts, Dialogs, and All Overlays

Great question! You’re totally right that PixelCopy and Canvas-based screenshot methods only capture your Activity’s DecorView—they completely miss floating elements like Toasts, AlertDialogs, or even system overlays like the status bar. To grab a full, true-to-visual screenshot of everything visible on the screen, the official (and reliable) approach is to use the MediaProjection API, introduced in Android 5.0 (API level 21).

How It Works

The MediaProjection API lets your app request permission to capture the entire screen, including all system and app-level overlays. Here’s a step-by-step breakdown:

  1. Request Screen Capture Permission
    First, you need to ask the user for explicit permission to capture the screen via a system dialog.

    private val REQUEST_CODE_SCREEN_CAPTURE = 100
    
    fun startScreenCaptureFlow() {
        val mediaProjectionManager = getSystemService(MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
        val captureIntent = mediaProjectionManager.createScreenCaptureIntent()
        startActivityForResult(captureIntent, REQUEST_CODE_SCREEN_CAPTURE)
    }
    
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == REQUEST_CODE_SCREEN_CAPTURE && resultCode == RESULT_OK) {
            // Permission granted, proceed to capture the screen
            captureFullScreen(data!!)
        }
    }
    
  2. Capture the Full Screen
    Once permission is granted, create a VirtualDisplay that mirrors the screen, then use an ImageReader to capture frame data and convert it to a Bitmap.

    private fun captureFullScreen(permissionData: Intent) {
        val mediaProjectionManager = getSystemService(MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
        val mediaProjection = mediaProjectionManager.getMediaProjection(RESULT_OK, permissionData)
    
        val displayMetrics = resources.displayMetrics
        val screenWidth = displayMetrics.widthPixels
        val screenHeight = displayMetrics.heightPixels
    
        val imageReader = ImageReader.newInstance(screenWidth, screenHeight, ImageFormat.RGB_565, 1)
    
        val virtualDisplay = mediaProjection.createVirtualDisplay(
            "FullScreenCapture",
            screenWidth,
            screenHeight,
            displayMetrics.densityDpi,
            DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
            imageReader.surface,
            null,
            null
        )
    
        // Wait a short time for the display to stabilize before capturing
        Handler(Looper.getMainLooper()).postDelayed({
            val image = imageReader.acquireLatestImage()
            image?.let {
                val planes = it.planes
                val buffer = planes[0].buffer
                val pixelStride = planes[0].pixelStride
                val rowStride = planes[0].rowStride
                val rowPadding = rowStride - pixelStride * screenWidth
    
                // Generate the full-screen bitmap
                val fullScreenBitmap = Bitmap.createBitmap(
                    screenWidth + rowPadding / pixelStride,
                    screenHeight,
                    Bitmap.Config.RGB_565
                )
                fullScreenBitmap.copyPixelsFromBuffer(buffer)
    
                // Now you have the complete screen bitmap (Toasts, Dialogs included!)
                // Use it as needed: save to file, display in a View, etc.
    
                image.close()
                mediaProjection.stop()
                virtualDisplay.release()
            }
        }, 500)
    }
    

Key Considerations

  • Permission Durability: The MediaProjection permission is temporary—you’ll need to re-request it if the app restarts or the device reboots.
  • Foreground Requirement: On Android 10 (API 29) and later, your app must be running in the foreground (with a visible activity or foreground service) to use this API.
  • Performance: Screen captures are resource-heavy, so avoid frequent captures if possible to prevent lag.
  • Root Workarounds: While rooted devices let you read directly from the system framebuffer, this is highly unportable and not recommended for production apps.

MediaProjection is the only official, non-root way to capture every visible element on the screen—including Toasts, Dialogs, and system UI. It’s the standard approach used by most screen recording and screenshot apps on the Play Store.

内容的提问来源于stack exchange,提问作者jay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 13:32:34