这里有新鲜出炉的精品教程,程序狗速度看过来!
Android 是一种基于 Linux 的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由 Google 公司和开放手机联盟领导及开发。尚未有统一中文名称,中国大陆地区较多人使用 "安卓" 或 "安致"。
这篇文章主要介绍了 Android 截取手机屏幕两种实现方法的相关资料, 需要的朋友可以参考下
Android 截取手机屏幕两种实现方法
最近在开发的过程中,遇到了一个需要截取屏幕保存为图片的需求,具体为截取 webview 的视图保存图片。
方法 1:首先想到的思路是利用 SDK 提供的 View.getDrawingCache() 方法:
- public void printScreen(View view) {
- String imgPath = "/sdcard/test.png";
- view.setDrawingCacheEnabled(true);
- view.buildDrawingCache();
- Bitmap bitmap = view.getDrawingCache();
- if (bitmap != null) {
- try {
- FileOutputStream out = new FileOutputStream(imgPath);
- bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
- } catch(Exception e) {
- e.printStackTrace();
- }
- }
- }
这个方法在很多情况下都是没有问题的,比如说截取 imageview,TextView,甚至 otherview.getRootView(); 都没问题,但在 WebView 上就会出现 webview 的部分截取完缺少页面里的一些内容的情况,比如说用 webview 打开这个(https://miqt.github.io/jellyfish/)界面,截取的图片就会有问题,具体表现为网页中游动的水母没有显示在截取的图片上。
方法 2:使用 Android 系统提供的服务 Context.MEDIA_PROJECTION_SERVICE,进行截图操作。
Demo 源码: https://github.com/miqt/CapWindow
关键部分代码解析:↓
发送截图请求
- final MediaProjectionManager projectionManager = (MediaProjectionManager)
- getSystemService(Context.MEDIA_PROJECTION_SERVICE);
- Intent intent = projectionManager.createScreenCaptureIntent();
- startActivityForResult(intent, REQUEST_CODE);
接收返回的结果:
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- handleScreenShotIntent(resultCode, data);
- }
- private void handleScreenShotIntent(int resultCode, Intent data) {
- onScreenshotTaskBegan();
- final MediaProjectionManager projectionManager = (MediaProjectionManager)
- getSystemService(Context.MEDIA_PROJECTION_SERVICE);
- final MediaProjection mProjection = projectionManager.getMediaProjection(resultCode, data);
- Point size = Utils.getScreenSize(this);
- final int mWidth = size.x;
- final int mHeight = size.y;
- final ImageReader mImageReader = ImageReader.newInstance(mWidth, mHeight, PixelFormat
- .RGBA_8888, 2);
- final VirtualDisplay display = mProjection.createVirtualDisplay("screen-mirror", mWidth,
- mHeight, DisplayMetrics.DENSITY_MEDIUM,
- DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION, mImageReader.getSurface(),
- null, null);
- mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
- @Override
- public void onImageAvailable(ImageReader mImageReader) {
- Image image = null;
- try {
- image = mImageReader.acquireLatestImage();
- if (image != null) {
- final Image.Plane[] planes = image.getPlanes();
- if (planes.length > 0) {
- final ByteBuffer buffer = planes[0].getBuffer();
- int pixelStride = planes[0].getPixelStride();
- int rowStride = planes[0].getRowStride();
- int rowPadding = rowStride - pixelStride * mWidth;
- // create bitmap
- Bitmap bmp = Bitmap.createBitmap(mWidth + rowPadding / pixelStride,
- mHeight, Bitmap.Config.ARGB_8888);
- bmp.copyPixelsFromBuffer(buffer);
- Bitmap croppedBitmap = Bitmap.createBitmap(bmp, 0, 0, mWidth, mHeight);
- saveBitmap(croppedBitmap);//保存图片
- if (croppedBitmap != null) {
- croppedBitmap.recycle();
- }
- if (bmp != null) {
- bmp.recycle();
- }
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (image != null) {
- image.close();
- }
- if (mImageReader != null) {
- mImageReader.close();
- }
- if (display != null) {
- display.release();
- }
- mImageReader.setOnImageAvailableListener(null, null);
- mProjection.stop();
- onScreenshotTaskOver();
- }
- }
- }, getBackgroundHandler());
- }
这个方法类似使用手机的系统截屏(音量下键 + 电源键),能够完美的吧当前原模原样的屏幕截取下来,并且修改保存方法的话甚至可以屏幕录像,但相比于第一种方法,它的缺点是完全和界面上的 view 没有关系,并且在调用这个服务的时候,会弹出一个权限确认的弹框。另外需要注意,这一方法只能在 Android 5.0 的系统设备上适用。
总结:
总而言之,这两种方法各有利弊,使用的时候要根据自己的实际需求做出选择。
来源: http://www.phperz.com/article/17/0826/337679.html