android MediaProjection 截屏

MediaProjection 既可以截屏也可以录屏

发起截屏请求

MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
Intent intent = mediaProjectionManager.createScreenCaptureIntent();
startActivityForResult(intent, 333);

onActivityResult 里面处理

protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 333 && data != null) {
        MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
        MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(Activity.RESULT_OK, data);
        DisplayMetrics outMetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(outMetrics);
        final int screenWidth = outMetrics.widthPixels;
        final int screenHeight = outMetrics.heightPixels;
        ImageReader imageReader = ImageReader.newInstance(
                screenWidth,
                screenHeight,
                PixelFormat.RGBA_8888, 1);
        VirtualDisplay virtualDisplay = mediaProjection.createVirtualDisplay("screen-mirror",
                screenWidth,
                screenHeight,
                outMetrics.densityDpi,
                DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                imageReader.getSurface(), null, null);
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                Image image = imageReader.acquireLatestImage();
                if (image == null) {
                    return;
                }
                Image.Plane[] planes = image.getPlanes();
                ByteBuffer buffer = planes[0].getBuffer();
                int pixelStride = planes[0].getPixelStride();
                int rowStride = planes[0].getRowStride();
                int rowPadding = rowStride - pixelStride * screenWidth;

                Bitmap bitmap = Bitmap.createBitmap(screenWidth + rowPadding / pixelStride,
                        screenHeight, Bitmap.Config.ARGB_8888);
                bitmap.copyPixelsFromBuffer(buffer);
                String fileName = null;
                try {
                    Date currentDate = new Date();
                    SimpleDateFormat date = new SimpleDateFormat("yyyyMMddhhmmss");
                    File dir = getExternalFilesDir(null);
                    fileName = dir.getAbsolutePath() + "/" + date.format(currentDate) + ".png";
                    FileOutputStream fos = new FileOutputStream(fileName);
                    bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                image.close();
                mediaProjection.stop();
                virtualDisplay.release();

                // 使用截图 bitmap
            }
        }, 500);
    }
}

为什么延迟调用 acquireLatestImage ??? 因为截屏需要时间,立马去获取可能获取不到。

用 imageReader.setOnImageAvailableListener() 设置回调也是可以的,但我测试时每次都回调 2 次,所以为了简单就延时获取了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容