0、Android屏幕截图方式:
- 借助PC端工具截图
- Android手机端截图
1、借助PC端工具截图
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,使用以下命令:
- 系统是Android 2.3以上:
adb shell screencap -p xxx.png
- 系统是Android 4.0以上:
adb shell screenshot xxx.png
-
系统是Android 2.3以下,肿么办?
1.将screenshot工具从Android源码中抠出来,编译为独立的工具。然后再通过screenshot进行截图。
2.使用我们沈大雄vincentshen同学开发的gsnapcap截图工具,已适配各大厂商各种奇葩机型,解决什么红屏花屏不在话下,还支持图像压缩噢。
2、Android手机端截图
Android手机端截图分两种情况,有root权限和无root权限。
2.1 有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为屏幕原始分辨率。
2.2 无root权限
无root权限又分两种:
- 系统自带截图
- APP内截图
2.2.1 系统自带截图
系统自带截图有两种情况:
- 同时按住 电源键 和 音量下键 两秒钟
- 同时按住 电源键 和 Home键 两秒钟
机型不同,系统自带的截图方式也不同,但基本上都是以上两种。
2.2.2 APP内截图
APP内截图又分两种:(-_-!我真的不是黑安卓,太多情况了。)
- SurfaceView
- GLSurfaceView
SurfaceView和GLSurfaceView有什么不同,简单来说普通应用使用SurfaceView截图即可。游戏一般都是通过OpenGL实现的,那么则需要使用GLSurfaceView的方式进行截图。
2.2.2.1 SurfaceView
直接上代码:
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就没有办法了。