android中实现截屏的三种思路

APP截屏功能三种实现思路:

1. 基于Android SDK的截屏方法

<span style="font-size:14px;font-weight: normal;">SimpleDateFormat sdf = new SimpleDateFormat(
                  "yyyy-MM-dd_HH-mm-ss",Locale.US);
       Stringfname = "/sdcard/" + sdf.format(new Date()) + ".png";
       Viewview = v.getRootView();
       view.setDrawingCacheEnabled(true);
       view.buildDrawingCache();
       Bitmapbitmap = view.getDrawingCache();
       if(bitmap != null) {
           System.out.println("bitmapgot!");
           try{
              FileOutputStreamout = new FileOutputStream(fname);
              bitmap.compress(Bitmap.CompressFormat.PNG,100, out);
              System.out.println("file" + fname + "output done.");
           }catch (Exception e) {
              e.printStackTrace();
       }
    } else {
       System.out.println("bitmapis NULL!");
}</span>

方法:通过getDrawingCache()获取到当前view的bitmap视图。如果会返回null,则说明没有开启view的绘画缓存功能,通过setDrawingCacheEnabled(true)开启.得到位图对象,然后压缩成指定格式的图片即可。

这种截屏方式有以下缺点

1.      只能截取当前应用view的视图,无法将状态栏的视图截取下来

2.      只能获取当前应用的view,也就是只能截取自身app呈现的视图。在取证中,由于是对其他app进行取证,因此截取的不是本应用的视图,所以无法获取到所要截取app的view对象,无法完成截屏。

 

2. 基于Android ddmlib进行截屏

这种方式是基于pc端DDMS截屏功能实现的,需要用到tools包下的ddmlib.jar。

1.   使用AndroidDebugBridge类获取已经连接的设备,并建立连接;

2.   获得设备类,里面有一个getScreenShot()方法,获取到RawImage对象

3.   将RawImage对象进行格式转换,得到截屏图片。

方法缺点:必须是手机连接到DDMS时才能使用,也就是手机断开与DDMS连接时,将无法获取设备类,也就无法完成截屏功能,该方法不灵活。无法再app应用中使用。

3. 读取framebuffer数据,进行截屏

framebuff:帧缓冲(framebuffer)是Linux为显示设备提供的一个接口,把显存抽象后的一种设备,他允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作。

Linux FrameBuffer 本质上只是提供了对图形设备的硬件抽象,在开发者看来,FrameBuffer 是一块显示缓存,往显示缓存中写入特定格式的数据就意味着向屏幕输出内容。我们通过不停的向frame buffer中写入数据, 显示控制器就自动的从frame buffer中取数据并显示出来。全部的图形都共享内存中同一个帧缓存。

frambuffer对应的设备文件是/dev/graphics/fb0在安卓设备中也是存在此设备文件,因此截屏实现思路就是获取此设备文件,然后从framebuffer中读取屏幕图像数据。在android中普通用户是没有权限读取到改设备文件的,因此我们需要获取手机root权限后,将此设备文件的权限更改,这样就可以在不root的情况下进行读取。

因为这种方式需要不断的读取framebuffer中的图像数据,所以截屏操作并不是那么的迅速,因此可以将读取framebuffer数据的操作放在一个任务中进行,或者开启一个服务,在数据读取完转换为图片后,服务关闭即可。这种方式可以实现对其他app的截屏,也可以将状态栏一同截取下来,现在主流的截屏实现都是通过这种方式,基于framebuffer可以实现区域截屏,滚动截屏等。但这种方式实现起来还是有一定的难度。在ARGB转换的时候,因为不同设备分辨率不同,可能会出现花屏.    

参考:http://blog.csdn.net/ericahdu/article/details/6496826

http://xzpeter.org/?p=229

猜你喜欢

转载自blog.csdn.net/hsk256/article/details/48752259