使用普通截图方式截取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或者其他界面。