android截屏的几种方法

原文地址: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项目是开源的,所以可以使用aosp项目的密钥
另外需要在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);
                }
            }
        });

上述代码的调用结果如下:
android截屏的几种方法

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

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

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值