最近项目中有用到远程截屏并上传截屏文件的需求。
一开始使用的是以下方法进行截屏:
private void screenshot() {
// 获取屏幕
View dView = getWindow().getDecorView();
dView.setDrawingCacheEnabled(true);
dView.buildDrawingCache();
Bitmap bmp = dView.getDrawingCache();
if (bmp != null) {
try {
// 获取内置SD卡路径
String sdCardPath = Environment.getExternalStorageDirectory().getPath();
// 图片文件路径
String filePath = sdCardPath + File.separator + "screenshot.png";
File file = new File(filePath);
FileOutputStream os = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.PNG, 100, os);
os.flush();
os.close();
String msg = DataTransformUtils.bitmapToBase64(bmp);
NetworkRetrofit.getInstance().getService().uploadIcon(phoneSoleNumber, "", 1, 0, msg)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new ObserverResult<UploadIconBean>() {
@Override
protected void onSuccess(UploadIconBean uploadIconBean) {
Log.e("lee", "上传截屏文件成功");
}
});
} catch (Exception e) {
}
}
}
通过上述方法确实能够成功截屏,但是手机进入二级界面时,截到的屏幕还是桌面。
然后发现安卓5.0以后使用MediaProjectionManager类可以进行截屏录屏的功能:
1.申明必须使用到的成员变量:
private MediaProjectionManager mediaProjectionManager;
private WindowManager mWindowManager;
private int mWindowWidth;
private int mWindowHeight;
private int mScreenDensity;
private Intent it;
private Bitmap mBitmap;
private VirtualDisplay mVirtualDisplay;
2.初始化对象:
mediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
it = mediaProjectionManager.createScreenCaptureIntent();
mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
mWindowWidth = mWindowManager.getDefaultDisplay().getWidth();
mWindowHeight = mWindowManager.getDefaultDisplay().getHeight();
mImageReader = ImageReader.newInstance(mWindowWidth, mWindowHeight, 0x1, 2);
DisplayMetrics displayMetrics = new DisplayMetrics();
mWindowManager.getDefaultDisplay().getMetrics(displayMetrics);
mScreenDensity = displayMetrics.densityDpi;
3.判断是否有权限:
启动 startActivityForResult(it, 666);
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data);
if (null != mediaProjection) {
mVirtualDisplay = mediaProjection.createVirtualDisplay("ScreenCapture", mWindowWidth, mWindowHeight, mScreenDensity,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mImageReader.getSurface(), null, null);
startCapture();
}
}
4.开始截屏方法:
private void startCapture() {
Image image = mImageReader.acquireLatestImage();
if (image == null) {
Log.e(TAG, "image is null.");
return;
}
int 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;
mBitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Bitmap.Config.ARGB_8888);
mBitmap.copyPixelsFromBuffer(buffer);
mBitmap = Bitmap.createBitmap(mBitmap, 0, 0, width, height);
image.close();
stopScreenCapture();
saveToFile();
}
5.释放资源:
private void stopScreenCapture() {
if (mVirtualDisplay != null) {
mVirtualDisplay.release();
mVirtualDisplay = null;
}
}
6.保存图片:
private void saveToFile() {
try {
FileOutputStream os = new FileOutputStream( new File(getExternalFilesDir(null), "jietu.jpg"));
mBitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
os.flush();
os.close();
//bitmap就是截屏图片
Toast.makeText(this.getApplicationContext(), "截图成功", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Toast.makeText(this.getApplicationContext(), "截图失败", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
以上就完成了对屏幕的截屏操作,通过这个类也可以进行录屏。