从Android设备获取实时截屏(adb)
前两篇文章已经把如何控制android设备的输入讲了,这一篇就是如何获取输出,通过adb的方式
原理
framebuffer获取流程
AdbClient和AdbServer都是运行在PC上的,AdbDaemon运行在android设备上。那framebuffer倒底是个啥?
帧缓冲(frame buffer)是Linux视频系统的核心概念,因此先了解一下他的功能。
因为视频适配器可能基于不同的硬件体系架构,较高内核层和应用程序的实现可能会因视频卡的不同而不同,这会导致在使用不同视频卡的时需要采用不同的方案。随之而来的低可移植性和冗余的代码需要大量的投入和维护开销。帧缓冲的概念解决了这个问题,它进行了一般化的抽象并规定编程接口,从而开发人员可以以与平台无关的方式编写应用层和较高内核层程序。因此,内核的帧缓冲接口允许应用程序与底层图形硬件的变化无关,如果应用和显示器驱动程序遵循帧缓冲接口,应用程序不用改变就可以在不同类型的视频硬件上运行。 (引用链接)
我来简单的解释一下,其实就是当前时间和之前几个帧的屏幕图像信息(每个像素点的颜色,分辨率等等)。
java实现
我们来看看android系统里面对每一帧图像信息的定义
//ddmlibsrccomandroidddmlibDevice.java
public RawImage getScreenshot()
throws TimeoutException, AdbCommandRejectedException, IOException {
return AdbHelper.getFrameBuffer(AndroidDebugBridge.getSocketAddress(), this);
}
//ddmlibsrccomandroidddmlibAdbHelper.java
/**
* Retrieve the frame buffer from the device.
* @throws TimeoutException in case of timeout on the connection.
* @throws AdbCommandRejectedException if adb rejects the command
* @throws IOException in case of I/O error on the connection.
*/
static RawImage getFrameBuffer(InetSocketAddress adbSockAddr, Device device)
throws TimeoutException, AdbCommandRejectedException, IOException {
RawImage imageParams = new RawImage();
byte[] request = formAdbRequest("framebuffer:"); //$NON-NLS-1$
byte[] nudge = {
0
};
byte[] reply;
SocketChannel adb