您的位置:首页 > 移动开发 > Android开发

android截屏之方法

2013-10-15 10:25 337 查看
最近做项目需要一个功能——android截屏,对其进行了研究,整理如下:

一、基于view对象截图。

View类是一个超类,android中几乎所有可视的对象都继承与它。在实际应用中,只要获取到了你所要截图的View类或其子类的对象view,就可以通过函数Bitmap.createBitmap(view.getDrawingCache())来获取其截图。比如:我需要获取当前activity的截图,只需要先获取顶层view对象,在调用函数,其代码如下:

View v=this.getWindow().getDecorView();

Bitmap bitmap=Bitmap.createBitmap(v.getDrawingCache());

这样就获取了Bitmap对象,可以对其进行需要的操作,比如写入文件生成图片,或者写到网络输出流进行传输。

优点:速度快,代码简单。

缺点:1、不能全局截图。只能截取自己写的application中的屏幕,因为获取不到外部应用的view对象。

2、不能截图标题栏。这在某些需求中是不能被接受的。

二、通过adb进行截图。

豌豆荚以及一些宣传不需要ROOT截图的软件,都是采用这种方法来截图的。

这种方法的实质是读取android设备的帧缓存文件,一般是/dev/graphics/fb0文件,里面存储的是raw格式的像素数据。

通过android设备与pc相连,打开android设备的debug模式,adb可以读取到android上的任意文件,其中就包括了/dev/graphics/fb0。对其进行解析,转码,就可以生成截图。

优点:可以对android设备全局截图,且不需要root

缺点:需要连pc,需要开debug模式。汗啊!让用户开调试模式,不晕么。所以这种方式对于我们的应用一般不适合。

三、在android端读取帧缓存文件进行截图。这种方法的实用性最强,它唯一的缺点是需要root权限。目前我主要研究了以下三种方式的实现:

1、通过jni调用C来实现截图的功能。首先要编写好C的代码,调用相关的库来实现截图的功能,然后将其编译好,最后在android中导入库,并进行调用。过程比较长,代码就不贴了,具体可以google。

2、通过shell调用可执行的c程序来实现截图。在网上搜索到了gsnap这个东东,它最初是基于linux板子的截图,李先静先生对其进行了修改,使其可以支持android截图。

具体实现方法如下:

(1)获取gsnap文件,将其推送到设备的/data/data/工程名/app_bin中。在模拟器上运行时,可以直 接用adb进行push操作。发布程序的时候,最后将gsnap放到assets文件夹下,再通过代码将其推送到指定目录下,其代码见附录代码1。

(2)对gsnap文件修改权限,使其可以被程序访问。

命令:chmod 777 /data/data/工程名/app_bin/gsnap

(3)调用该文件。

命令:/data/data/工程名/app_bin/gsnap test.jpg /dev/graphics/fb0

其中(2)、(3)可通过附录代码2中的RunCommand函数实现。

3、通过android直接调用该帧缓存文件截图。这种方法的优点是省去了调用C的过程,而且代码相对更清晰,易于维护与优化。缺点是dalvik虚拟机性能不够好,而且当图片分辨率较大时,内存也不一定够用。其代码见附录代码3。

总结到此为止,欢迎交流。

附录:

代码1:

private void addGsnap()

{

File localFile = getDir(“bin”, 0);

String CFilePath = (localFile.getAbsolutePath() + “/gsnap”);

File file=new File(CFilePath);

if(!file.exists())

{

copyFile(“gsnap”,CFilePath);

}

}

public boolean copyFile(String from, String to) {

try {

int bytesum = 0;

int byteread = 0;

InputStream inStream = getResources().getAssets().open(from);

OutputStream fs = new BufferedOutputStream(new FileOutputStream(

to));

byte[] buffer = new byte[8192];

while ((byteread = inStream.read(buffer)) != -1) {

bytesum += byteread;

fs.write(buffer, 0, byteread);

}

inStream.close();

fs.close();

return true;

} catch (Exception e) {

System.out.println(e.getMessage());

return false;

}

}

代码2:

public static int RunCommand(String paramString)

{

int i = 0;

Process localProcess = null;

try

{

localProcess = Runtime.getRuntime().exec(“su”);

OutputStreamWriter localOutputStreamWriter = new OutputStreamWriter(localProcess.getOutputStream

(), “UTF-8″);

// localOutputStreamWriter.write(“export LD_LIBRARY_PATH=/vendor/lib:/system/lib\n”);

//localOutputStreamWriter.flush();

localOutputStreamWriter.write(paramString + “\n”);

localOutputStreamWriter.flush();

localOutputStreamWriter.write(“exit\n”);

localOutputStreamWriter.flush();

localOutputStreamWriter.close();

localProcess.waitFor();

int j = localProcess.exitValue();

if (j == 0)

i = 1;

try

{

localProcess.destroy();

return i;

}

catch (Exception localException4)

{

System.out.println(localException4.getMessage());

while (true)

localException4.printStackTrace();

}

}

catch (Exception localException2)

{

System.out.println(localException2.getMessage());

while (true)

{

localException2.printStackTrace();

try

{

localProcess.destroy();

}

catch (Exception localException3)

{

localException3.printStackTrace();

}

}

}

finally

{

}

}

代码3:

public Bitmap Shot(Service service)

{

long a0=System.currentTimeMillis();

InputStream stream =null;

DataInputStream dStream=null;

try

{

File file = new File(“/dev/graphics/fb0″);

stream = new FileInputStream(file);

dStream = new DataInputStream(stream);

}

catch(Exception e){System.out.println(e.getMessage());return;}

byte[] piex = new byte[height * width * deepth];

try

{

if(dStream.read(piex, 0, height * width * deepth) != -1)

{

long a2=System.currentTimeMillis();

System.out.println(“读取字节数组”+(a2-a1)+”毫秒”);

stream.close();

dStream.close();

int []colors = new int[height * width];

for(int m=0;m<piex.length;m++)

{

if(m%4 == 0)

{

int b = piex[m];

int g = piex[m+1];

int r = piex[m+2];

int a = piex[m+3];

colors[m/4]= (a << 24) + (r <<16) + (g <<8) + b;

}

}

Bitmap bitmap = Bitmap.createBitmap(colors,width, height, Bitmap.Config.ARGB_8888);

return bitmap;

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: