Android屏幕截图方式总结

时间:2022-03-01 05:09:05

0、Android屏幕截图方式:

  1. 借助PC端工具截图
  2. 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以上:
 
  1. adb shell screencap -p xxx.png
  • 系统是Android 4.0以上:
 
  1. 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命令截图

 
  1. Process process = null;
  2. try{
  3. process = Runtime.getRuntime().exec("su");
  4. PrintStream outputStream = null;
  5. try {
  6. outputStream = new PrintStream(new BufferedOutputStream(process.getOutputStream(), 8192));
  7. outputStream.println("screencap -p " + filePath);
  8. outputStream.flush();
  9. }catch(Exception e){
  10. Log.e(TAG, e);
  11. } finally {
  12. if (outputStream != null) {
  13. outputStream.close();
  14. }
  15. }
  16. process.waitFor();
  17. }catch(Exception e){
  18. Log.e(TAG, e);
  19. }finally {
  20. if(process != null){
  21. process.destroy();
  22. }
  23. }

通过screnshot命令截图和上面是类似的,另外还可以通过调用Bugly自研的gsnapcap工具来进行截图。

 
  1. chmod 777 /dev/graphics/fb0
  2. 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

直接上代码:

 
  1. public String takeScreenShot(Activity activity){
  2. String filePath = FileUtils.getInstance().getStorePicFile(activity);
  3. View rootView = activity.getWindow().getDecorView();
  4. rootView.setDrawingCacheEnabled(true);
  5. rootView.buildDrawingCache();
  6. Bitmap bitmap = rootView.getDrawingCache();
  7. File imagePath = new File(filePath);
  8. FileOutputStream fos = null;
  9. try {
  10. fos = new FileOutputStream(imagePath);
  11. bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
  12. fos.flush();
  13. } catch (Exception e) {
  14. }finally {
  15. try{
  16. fos.close();
  17. bitmap.recycle();
  18. bitmap = null;
  19. }catch(Exception e){
  20. }
  21. rootView.destroyDrawingCache();
  22. rootView.setDrawingCacheEnabled(false);
  23. }
  24. return filePath;
  25. }

takeScreenShot的参数必须为Activity类或其子类,不能是Context,这段代码是通过获取Activity的根节点view,并将其DrawingCache保存为图片,从而实现对该界面的截图。这个方法只能对APP自身的界面有效,出了APP就没有办法了。