android截屏的几种方法
发布日期:2021-11-12 07:57:30 浏览次数:29 分类:技术文章

本文共 5033 字,大约阅读时间需要 16 分钟。

原文地址:http://www.codeweblog.com/android%E6%88%AA%E5%B1%8F%E7%9A%84%E5%87%A0%E7%A7%8D%E6%96%B9%E6%B3%95/

>
>

android截屏的几种方法

1. Surface.screenshot方法

try{    Display display = getWindowManager().getDefaultDisplay();    Method mth = Surface.class.getDeclaredMethod("screenshot", int.class, int.class);    Bitmap bmp = (Bitmap)mth.invoke(null, display.getWidth(),display.getHeight());    OutputStream out = MainActivity.this.openFileOutput("screen.png", MODE_WORLD_READABLE);    bmp.compress(Bitmap.CompressFormat.PNG, 100, out);    out.close();    Log.i("zxp","capture succeed");}catch(Exception e){    Log.e("zxp","unable capture screen: ",e);}

即通过反射调用Surface的隐藏方法public static native Bitmap screenshot(int width, int height);。此方法需要android.permission.READ_FRAME_BUFFER权限,而这个权限只能授予系统应用。所以需要源码编译或使用plantform密钥签名。因为android项目是开源的,所以可以使用。

另外需要在AndroidManifext.xml中的manifest标签中添加android:sharedUserId="android.uid.system"
局限:只能在虚拟机或其他使用android源码中密钥编译的系统中使用。

在安卓4.0 到 4.2时,com.android.view.Surface有个隐藏的API: public static Bitmap screenshot(int width, int height) 可以用于截屏,Surface这个class本身是没有hide标志的,只是screenshot方法有hide。添加READ_FRAME_BUFFER权限,在源码环境下用platform签名编译,调用Surface.screenshot(width, height)能正确运行并截屏返回Bitmap。

安卓4.3及以后screenshot方法被修改到了com.android.view.SurfaceControl中,SurfaceControl这个class是hide的。使用和上述4.2中同样的操作,在安卓4.4系统中编译,调用SurfaceControl.screenshot(width, height),

2. 使用shell命令screencap,screenshot

screencap与screenshot用法

usage: screencap [-hp] [-d display-id] [FILENAME]   -h: this message   -p: save the file as a png.   -d: specify the display id to capture, default 0.If FILENAME ends with .png it will be saved as a png.If FILENAME is not given, the results will be printed to stdout.---------------------------------------------------------------usage: screenshot [-s soundfile] filename.png   -s: play a sound effect to signal success   -i: autoincrement to avoid overwriting filename.png

screencap与screenshot都可以截屏并保存为文件。但screencap可以将截取的图片直接打印到输出流。对于一些其他操作而不需要保存到文件时可以使用screencap。

局限:需要root权限。

findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                try {                    //转为灰色图片或其他操作                    Bitmap bmp = convert2Grey(captureScreen());                    //保存到文件                    OutputStream out = openFileOutput("gray.png",                            Context.MODE_WORLD_READABLE);                    bmp.compress(Bitmap.CompressFormat.PNG, 100, out);                    out.flush();                    out.close();                    Log.i("zxp", "capture succeed");                } catch (Exception e) {                    Log.e("zxp", "unable capture screen: ", e);                }            }        });
public Bitmap captureScreen() throws Exception {        Process pro = Runtime.getRuntime().exec("su -c screencap -p");        InputStream in = pro.getInputStream();        Bitmap bmp = BitmapFactory.decodeStream(in);        in.close();        pro.destroy();        return bmp;    }    public Bitmap convert2Grey(Bitmap img) {        int width = img.getWidth(); // 获取位图的宽        int height = img.getHeight(); // 获取位图的高        int[] pixels = new int[width * height]; // 通过位图的大小创建像素点数组        img.getPixels(pixels, 0, width, 0, 0, width, height);        int alpha = 0xFF << 24;        for (int i = 0; i < height; i++) {            for (int j = 0; j < width; j++) {                int grey = pixels[width * i + j];                int red = ((grey & 0x00FF0000) >> 16);                int green = ((grey & 0x0000FF00) >> 8);                int blue = (grey & 0x000000FF);                grey = (int) ((float) red * 0.3 + (float) green * 0.59 + (float) blue * 0.11);                grey = alpha | (grey << 16) | (grey << 8) | grey;                pixels[width * i + j] = grey;            }        }        Bitmap result = Bitmap.createBitmap(width, height, Config.RGB_565);        result.setPixels(pixels, 0, width, 0, 0, width, height);        return result;    }

3.View.getDrawingCache()

这个方法没有其他限制,但它只能取得调用者的图像。

findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                try {                    //因为调用者是被点击的button,所以只能取得该Button的图像                    v.setDrawingCacheEnabled(true);                    Bitmap bmp = v.getDrawingCache();                    OutputStream out = openFileOutput("button.png",                            Context.MODE_WORLD_READABLE);                    bmp.compress(Bitmap.CompressFormat.PNG, 100, out);                    out.flush();                    out.close();                    Log.i("zxp", "capture succeed");                } catch (Exception e) {                    Log.e("zxp", "unable capture screen: ", e);                }            }        });

上述代码的调用结果如下:

但可以调用顶级view取得整个activity的图像

public Bitmap getTopView(){        View view = getWindow().getDecorView();        view.setDrawingCacheEnabled(true);        return view.getDrawingCache();    }

局限:该方法只能取得调用者view的图像,也就是说这不是实际意义上的“截屏”.

转载地址:https://blog.csdn.net/happy_love1990/article/details/76438951 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Android:控件GridView的使用
下一篇:Android shape drawable XML 可绘制图形的创建与使用

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2024年03月30日 18时18分25秒