1. 程式人生 > >android surfaceview截圖 系統截圖

android surfaceview截圖 系統截圖

使用普通截圖方式擷取surfaceview的人都會遇到surfaceview區域黑屏,也就是擷取不到圖片。然後各種百度google,有的說換用textureview,也有些別的方法。大概試了都沒能成功,textureview是有對應方法。不過現在需要截圖的是surfaceview。
Android在5.0系統之前,是沒有開放視訊錄製的介面的,5.0之後Google開放了視訊錄製的介面,相關類是MediaProjection和MediaProjectionManager。
首先來說MediaProjectionManager,它是一個系統級的服務,類似WindowManager,AlarmManager等,你可以通過getSystemService方法來獲取

MediaProjectionManager mMediaProjectionManager = (MediaProjectionManager)
                getSystemService(Context.MEDIA_PROJECTION_SERVICE);

需要開始截圖需要呼叫MediaProjectionManager 的createScreenCaptureIntent返回的是一個intent,使用startactivity啟動會彈出一個截圖授權框:

startActivityForResult(
                    mMediaProjectionManager.createScreenCaptureIntent()
, REQUEST_MEDIA_PROJECTION)
;
截圖成功後再onactivityResult回撥,擷取螢幕顯示
 @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_MEDIA_PROJECTION) {
            if (resultCode != Activity.RESULT_OK) {
                Toast.makeText
(this, "使用者取消了", Toast.LENGTH_SHORT).show(); return; } final ImageReader mImageReader = ImageReader.newInstance(ScreenUtils.getScreenWidth(this), ScreenUtils.getScreenHeight(this), 0x1, 2); mMediaProjection = mMediaProjectionManager.getMediaProjection(resultCode, data); mVirtualDisplay = mMediaProjection.createVirtualDisplay("ScreenCapture", ScreenUtils.getScreenWidth(this), ScreenUtils.getScreenHeight(this), getResources().getDisplayMetrics().densityDpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mImageReader.getSurface(), null, null); mImageName = System.currentTimeMillis() + ".png"; new Handler().postDelayed(new Runnable() { @Override public void run() { Image image = null; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) { image = mImageReader.acquireLatestImage(); } if (image == null) { return; } int width = 0; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) { width = image.getWidth(); int height = image.getHeight(); final Image.Plane[] planes = image.getPlanes(); final ByteBuffer buffer = planes[0].getBuffer(); int pixelStride = planes[0].getPixelStride(); int rowStride = planes[0].getRowStride(); int rowPadding = rowStride - pixelStride * width; Bitmap mBitmap; mBitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Bitmap.Config.ARGB_8888); mBitmap.copyPixelsFromBuffer(buffer); mBitmap = Bitmap.createBitmap(mBitmap, 0, 0, width, height); image.close(); if (mBitmap != null) { //拿到mitmap final Bitmap finalMBitmap = mBitmap; } } } }, 300); } }

由於剛開始錄製直接擷取圖片可能會出現黑屏之類問題 ,所以這裡延遲了300毫秒。通過這樣,就可以獲取到截圖,包括surfaceview或者其他介面。