最近做一个Android开发的项目用到了录屏的功能,开始查阅了一些资料和博客,基本上都是在讨论ROOT的。直到后来在github上看到一个比较新的代码,才恍然发现,Android 5.0时候开放了一个新的接口---android.media.projection,一下子让这个问题变得简单了。所以说查阅资料也该注意实时性,现在很多技术推陈出新速度很快,一些新的包,接口,方法会让问题更好更快的解决。不过自己还是决定总结了下之前的一些想法,也算是一个学习吧。
首先说下之前的几种方法。一般最开始的 Android 截屏程序,都是来源于 Linux 的截屏方法,android 使用的 Linux 内核,那么 Linux 下的截屏方法也就最先被 android 采用。Linux 使用了 framebuffer 管理显示输出,传统的办法就是读取 framebuffer 的数据,然后得到整个屏幕的数据。此方法在 Android3.0 版本之前是也唯一可行的方法。 然而 linux 采用了严格的权限控制 设备文件,framebuffer 也是其控制之一,在 Android 中只有 root, 和 graphic 组用户才有权限读取,所以要采用读取 framebuffer 的方式实现截屏,应用必须获得 root 权限。
后来呢,大家都知道ROOT权限是件比较麻烦的事,给自己软件加上ROOT权限对于客户来说也是一件挺有风险的事,于是后来常用的一种方法就是自定义view利用bitmap获取view的形式获取当前屏幕,核心代码是:
import android.media.projection.MediaProjection; import android.media.projection.MediaProjectionManager;2.实例化MediaProjectionManager
mMediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);3.利用MediaProjectionManager类实例的功能函数createScreenCaptureIntent()生成intent,为接下来的的抓取屏幕做准备
Intent captureIntent = mMediaProjectionManager.createScreenCaptureIntent(); startActivityForResult(captureIntent, REQUEST_CODE);4.在onActivityResult()中获取返回值
protected void onActivityResult(int requestCode, int resultCode, Intent data) { MediaProjection mediaProjection = mMediaProjectionManager.getMediaProjection(resultCode, data); if (mediaProjection == null) { Log.e("@@", "media projection is null"); return; }5.实例化VirtualDisplay,这个类的主要作用是用来获取屏幕信息并保存在里。
private VirtualDisplay mVirtualDisplay;
mVirtualDisplay = mMediaProjection.createVirtualDisplay(TAG + "-display", mWidth, mHeight, mDpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC, mSurface, null, null);6.保存图片。目前的图片信息保留在mSurface里,建立一个Image获取信息保存在BufferByte里再保存在一个bitmap里即可。