Android下调用系统截屏的心得

根据公司的软件需求,需要实现一个在所有信道下批注以及自定义截图的功能,那么则需要获取到屏幕的截图,并设置到画布上,这样才能在后续进行保存。前期以为只要简单的设置Activity透明即可,但后续在保存时发现保存的图片一直是黑色的。

那么只能寻找其他方案,因为公司的安卓电视主板用的是5.0以上的操作系统,就考虑用MediaProject相关的Api接口来做,然而此时遇到了另一个问题,在Android信道下可以截屏并且获取到相关的屏幕数据,从而进行保存。但当信道切换到PC信道或者其他TV信道时,截屏生成的图片永远是黑色的,也就是MediaProject这个方案仅适用在安卓下。于是只能考虑方案三了...

方案三:调用系统截屏的方式,一般的设备比如手机等,都是同时按下电源键+音量上键一段时间即可截屏。而如要在代码中调用该接口,程序调用步骤如下:

1、在AndroidMenifest.xml中添加 android:sharedUserId="android.uid.system" 属性
2、需要给程序添加系统签名,这需要用到两个文件,platform.x509.pem,platform.pk8;
签名可通过命令行的方式实现
a. java -jar signapk.jar platform.x509.pem platform.pk8 before_sign.apk after_sign.apk

3、调用systemui包下TakeScreenshotService服务


Android下调用系统截屏的心得_第1张图片
1526980779051.jpg

此时可以顺利的调用系统的截图功能,然而有个弊端,就是系统截屏的操作有个动画过程,而且无法获取到存储的路径,无法实现无缝跳转到批注以及自定义截图功能。此时需要优化,因为我们只需要获取到屏幕的图像数据即可做我们想要的操作,不希望获取数据的过程有其他附加操作,比如截屏动画、截屏自动存储。此时需要查看TakeScreenshotService中的源码:


Android下调用系统截屏的心得_第2张图片
1526981329172.jpg

从源码中看到截图过程先创建了一个GlobalScreenshot类,然后再调用了takeScreenshot方法,那么我们继续查看GlobalScreenshot相关的源码:



可以看到,截屏其实只要调用SurfaceControl中的screenshot方法就可以获取到屏幕的图像数据了,其中的参数即屏幕的宽高值。但SurfaceControl是隐藏类,无法直接被我们导入使用的,此时就需要用到java的反射机制,通过反射去调用该隐藏类的截图方法:

此时,我们就可以将bitmap数据传递到我们需要的地方进行使用了,同时我们规避了原有的动画以及自动存储的操作,可以自己对截图内容进行改动和存储了。

以上是自己总结的一些截屏心得,因为程序使用的环境是在自己公司的设备上,所以调用的原生的截屏功能。其实现在市场上大部分移动设备等都在5.0以上了,所以用MediaProject就能解决截图的问题了。

最后,谢谢你的阅读,如果喜欢请给个赞,有什么建议或者指点欢迎各位提出!!!

你可能感兴趣的:(Android下调用系统截屏的心得)