本文共 3541 字,大约阅读时间需要 11 分钟。
PC端截图可用的工具非常之多,从Android SDK提供的adb、ddms工具,到各大第三方助手应用宝、刷机精灵、豌豆荚等等。
工具虽多,但这些它们的实现方式基本都是一样的,通过执行 adb shell screencap -p xxx.png
或 adb shell screenshot xxx.png
来获取屏幕截图。
* screencap和screenshot有什么区别呢?
screencap是从Android 2.3开始提供的一个系统级的截图工具,通过源码可以了解到screencap的实现方式,默认会从底层UI Surface去获取屏幕截图,如果失败则从linux kernel层的display framebuffer(`/dev/graphics/fb0`)去获取屏幕截图。screenshot是从Android 4.0开始提供的另一个截图的工具, 通过源码可以发现screenshot则是直接读取`/dev/graphics/fb0`去获取屏幕的图像数据。
* 什么是/dev/graphics/fb0
?
简单来说是linux kernel 2.x开始提供的,一个屏幕数据缓存的设备,理论上凡是使用linux内核的系统都会有这样一个东东,然后就可以通过读取里面的数据来获取当前屏幕显示的内容。需要详细了解可以自行谷歌一下。
PC端如何截图?
1.下载应用宝PC版等工具
2.安装Android SDK,使用以下命令:adb shell screencap -p xxx.png
adb shell screenshot xxx.png
系统是Android 2.3以下,肿么办?
1.将screenshot工具从Android源码中抠出来,编译为独立的工具。然后再通过screenshot进行截图。
2.使用我们沈大雄vincentshen同学开发的gsnapcap截图工具,已适配各大厂商各种奇葩机型,解决什么红屏花屏不在话下,还支持图像压缩噢。Android手机端截图分两种情况,有root权限和无root权限。
在系统已经root的情况下,可以通过在APP代码中执行`screencap -p xxx.png` 和 `screenshot xxx.png`来进行屏幕截图。原理和上述PC端截图是一样的,只不过在PC端截图,手机无需root权限。如果在APP中执行截图命令,则需要root权限。*任何在adb中可执行的命令,如果想在APP代码中执行,基本上都需要有root权限。例如bugreport、logcat(>=4.1)、screenrecord(>=4.4)等。
通过screncap
命令截图
Process process = null; try{ process = Runtime.getRuntime().exec("su"); PrintStream outputStream = null; try { outputStream = new PrintStream(new BufferedOutputStream(process.getOutputStream(), 8192)); outputStream.println("screencap -p " + filePath); outputStream.flush(); }catch(Exception e){ Log.e(TAG, e); } finally { if (outputStream != null) { outputStream.close(); } } process.waitFor(); }catch(Exception e){ Log.e(TAG, e); }finally { if(process != null){ process.destroy(); } }
通过screnshot
命令截图和上面是类似的,另外还可以通过调用Bugly自研的gsnapcap工具来进行截图。
chmod 777 /dev/graphics/fb0 gsnapcap xxx.png /dev/graphics/fb0 1
最后一个参数为图像分辨率,1为屏幕原始分辨率。
无root权限又分两种:
系统自带截图有两种情况:
机型不同,系统自带的截图方式也不同,但基本上都是以上两种。
APP内截图又分两种:(-_-!我真的不是黑安卓,太多情况了。)
SurfaceView和GLSurfaceView有什么不同,简单来说普通应用使用SurfaceView截图即可。游戏一般都是通过OpenGL实现的,那么则需要使用GLSurfaceView的方式进行截图。
直接上代码:
public String takeScreenShot(Activity activity){ String filePath = FileUtils.getInstance().getStorePicFile(activity); View rootView = activity.getWindow().getDecorView(); rootView.setDrawingCacheEnabled(true); rootView.buildDrawingCache(); Bitmap bitmap = rootView.getDrawingCache(); File imagePath = new File(filePath); FileOutputStream fos = null; try { fos = new FileOutputStream(imagePath); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos); fos.flush(); } catch (Exception e) { }finally { try{ fos.close(); bitmap.recycle(); bitmap = null; }catch(Exception e){ } rootView.destroyDrawingCache(); rootView.setDrawingCacheEnabled(false); } return filePath; }
takeScreenShot的参数必须为Activity类或其子类,不能是Context,这段代码是通过获取Activity的根节点view,并将其DrawingCache保存为图片,从而实现对该界面的截图。这个方法只能对APP自身的界面有效,出了APP就没有办法了。
转载地址:http://ppdqi.baihongyu.com/