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 次,所以为了简单就延时获取了。
网友评论