Android 5.0之前屏幕截图的方法

时间:2021-11-26 13:55:22

截图的几种方法

Android获取屏幕截图主要有以下三种方法
1、通过view.getDrawingCache()获取指定View的绘制缓存来实现截屏。
这种方式Android 5.0之前也可以,且不需要权限。可以截取本应用内任意位置的屏幕截屏,可能会有些webview会截取不到。
注意这种方式只能获取当前应用内的截图(连顶部状态栏中的时间等都信息都获取不到,获取到的状态栏是一片空白)。

2、通过Linux底层驱动来实现截屏。
linux的图像信息都是通过FrameBuffer来写到显示设备上的,所以可以通过读取这个buffer的信息来获取屏幕截图。
DDMS工具就是通过这种方式来获取截图的。FrameBuffer对应的设备文件目录是/dev/graphics/fb0。
但是这种方法需要root权限,由于是直接从底层显示数据读取的,所以理论上是属于手机屏幕的任何信息都可以截取到。

3、通过Android 5.0后的MediaProjection API实现截屏。
该接口官方说是用来屏幕录制和音频录制,可以参照系统自带的sample案例ScreenCapture。
关于sample的分析可参照这篇 http://www.cnblogs.com/tgyf/p/4675082.html 。
Android 5.0后系统自带的截图功能也是使用此API,过程分析详见 http://blog.csdn.NET/kong92917/article/details/50495740 。
这种方法不用root,api是开放的,不过只针对L版以上。

Activity

public class MainActivity extends ListActivity {
    private TextView tv;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        String[] array = { "获取指定Activity整个屏幕,带状态栏", "获取指定Activity整个屏幕,不带状态栏",//
                "获取指定Activity指定View的区域屏幕", "获取指定Activity指定View的区域屏幕2", //
                "获取指定Activity指定区域屏幕", "使用Android 5.0后的MediaProjection API" };
        for (int i = 0; i < array.length; i++) {
            array[i] = i + "、" + array[i];
        }
        tv = new TextView(this);// 将内容显示在TextView中
        AbsListView.LayoutParams params = new AbsListView.LayoutParams(AbsListView.LayoutParams.WRAP_CONTENT, AbsListView.LayoutParams.WRAP_CONTENT);
        tv.setLayoutParams(params);
        tv.setTextColor(Color.BLUE);
        tv.setText("我是一个TextView");
        getListView().addFooterView(tv);
        setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, new ArrayList<String>(Arrays.asList(array))));
    }
    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        Bitmap bitmap = null;
        switch (position) {
        case 0:
            bitmap = SnapUtils.snapShot(this, true);
            SnapUtils.saveBitmap2Pic(bitmap, "bqt0.jpg");
            break;
        case 1:
            bitmap = SnapUtils.snapShot(this, false);
            SnapUtils.saveBitmap2Pic(bitmap, "bqt1.jpg");
            break;
        case 2:
            bitmap = SnapUtils.snapShot(this, v);
            SnapUtils.saveBitmap2Pic(bitmap, "bqt2.jpg");
            break;
        case 3:
            bitmap = SnapUtils.snapShot(this, tv);
            SnapUtils.saveBitmap2Pic(bitmap, "bqt3.jpg");
            break;
        case 4:
            bitmap = SnapUtils.snapShot(this, 300, 300, 100, 200);
            SnapUtils.saveBitmap2Pic(bitmap, "bqt4.jpg");
            break;
        case 5:
            startActivity(new Intent(this, Activity2.class));
            break;
        }
        if (bitmap != null) Toast.makeText(this, bitmap.getWidth() + "--" + bitmap.getHeight(), Toast.LENGTH_SHORT).show();
    }

}


工具类

public class SnapUtils {
    //******************************************************************************************
    //                                                                            屏幕截图
    //******************************************************************************************
    /**获取指定Activity整个屏幕截图,这种方式只能获取当前应用的截图(连顶部状态栏中的时间等都获取不到)
     * @param withStatusBar 是否包含状态栏
     */
    public static Bitmap snapShot(Activity activity, boolean withStatusBar) {
        int statusBarHeight = 0;
        if (!withStatusBar) {
            Rect frame = new Rect();
            activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
            statusBarHeight = frame.top;
        }
        DisplayMetrics metric = new DisplayMetrics();
        ((WindowManager) activity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(metric);
        return snapShot(activity, 0, statusBarHeight, metric.widthPixels, metric.heightPixels - statusBarHeight);
    }
    /**
     * 获取指定Activity指定View的屏幕截图,这种方式只能获取当前应用的截图(连顶部状态栏中的时间等都获取不到)
     * @param activity
     * @param view
     * @return
     */
    public static Bitmap snapShot(Activity activity, View view) {
        return snapShot(activity, (int) view.getX(), (int) view.getY(), (int) view.getWidth(), (int) view.getHeight());
    }
    /**
     * 获取指定Activity指定区域的屏幕截图,这种方式只能获取当前应用的截图(连顶部状态栏中的时间等都获取不到)
     * @param activity        所要截取的Activity
     * @param x        The x coordinate of the first pixel in source
     * @param y        The y coordinate of the first pixel in source
     * @param width        The number of pixels in each row
     * @param height        The number of rows
     * @return        A copy of a subset of the source bitmap or the source bitmap itself.
     */
    public static Bitmap snapShot(Activity activity, int x, int y, int width, int height) {
        View view = activity.getWindow().getDecorView();
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();
        Bitmap cache = view.getDrawingCache();
        Bitmap bitmap = Bitmap.createBitmap(cache, x, y, width, height);
        view.destroyDrawingCache();
        return bitmap;
    }
    /**
     * 保存bitmap为图片
     * @param bitmap
     * @param fileName    文件名,注意是保存在了SD卡根目录下
     */
    public static void saveBitmap2Pic(Bitmap bitmap, String fileName) {
        try {
            File file = new File(Environment.getExternalStorageDirectory().getPath(), fileName);
            file.createNewFile();//在window中没问题,但是在Android上必须加这一句,否然报异常 java.io.FileNotFoundException: xxx: open failed: EROFS (Read-only file system)
            FileOutputStream out = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}


Android 5.0之前屏幕截图的方法的更多相关文章

  1. Android 5&period;0之后屏幕截图的方法

    截图的几种方法 Android获取屏幕截图主要有以下三种方法 1.通过view.getDrawingCache()获取指定View的绘制缓存来实现截屏. 这种方式Android 5.0之前也可以,且不 ...

  2. Xamarin&period;Android 6&period;0以后开启权限方法

    Android 6.0 版本以上一些危险权限只能在运行的时候依次询问用户是否赋予,所以在开发的时候使用 RequestPermissions 方法单独请求所需要的权限. 代码: //开启相机权限 if ...

  3. Android全屏(包含3种隐藏顶部状态栏及标题栏和一种隐藏Android 4&period;0平板底部状态栏的方法)

    http://www.xuebuyuan.com/558284.html 方法一 public class MainActivity extends Activity { @Override prot ...

  4. Android 6&period;0 SDK 找不到HttpClient的解决方法

    一.情况描述 在eclipse或Android Studio开发时(笔者目前只用过Android Studio),设置Android SDK的编译版本为23时,且使用了httpClient相关类的库项 ...

  5. android 6&period;0 SDK中删除HttpClient的相关类的解决方法

    一.出现的情况 在eclipse或 android studio开发, 设置android SDK的编译版本为23时,且使用了httpClient相关类的库项目:如android-async-http ...

  6. Android 4&period;0 ProGuard 代码混淆 以及 proguard returned with error code 1&period;See console异常的解决方法

    最近呢说要上线,就去找了下上线的方法...之前做过代码混淆,用的是progarud.cfg,但是呢自己反编译了之后还是无效,然后就丢着先不管了,因为实在不知道什么情况.今天来上线的时候结果总是报错,总 ...

  7. android 获取栈顶activty的方法总结(兼容API 5&period;0)

    声明:本文为Dujinyang CSDN原创投稿文章,未经许可,禁止任何形式的转载. 最近5.0\6.0\7.0 安卓系统都陆续上岗了,兼容性和代码更新是个很头疼的问题,这次我们来说下TASK的基础和 ...

  8. Android 8&period;0 的部分坑及对应解决方法

    虽然 Android 9.0 都已经面世了,本篇文章写的有点迟了. 但是迟到好过不到,因此基于此这边还是记录一下项目中遇到的 Android 8.0 的坑及对应解决方法. 每次系统升级,虽然系统功能更 ...

  9. Gradle 同步时报错,Could not find com&period;android&period;support&period;constraint&colon;constraint-layout&colon;1&period;0&period;0-alpha8的解决方法

    Error:Could not find com.android.support.constraint:constraint-layout:1.0.0-alpha8. 原因: SDK 中可能是没有安装 ...

随机推荐

  1. Java Web之网上购物系统(提交订单、查看我的订单)

    作业终于做完了,好开心......虽然这一周经历不是那么顺利,但是觉得还是收获了不少,有过想哭的冲动,代码不会写,事情办不好,各种发愁.空间里发小发了带父母出去游玩的照片,瞬间能量值不知道是被击退的多 ...

  2. GIT 操作

    1. 查看某个文件某次提交修改的内容 git show commitid  a.txt  2. git rm 和 git rm --cached  当我们需要删除暂存区或分支上的文件, 同时工作区也不 ...

  3. js &sol;jquery停止事件冒泡和阻止浏览器默认事件

    1>js阻止冒泡事件 var el = window.document.getElementById("a"); el.onclick = function (e) { // ...

  4. 转:Media Player Classic - HC 源代码分析

    VC2010 编译 Media Player Classic - Home Cinema (mpc-hc) Media Player Classic - Home Cinema (mpc-hc)播放器 ...

  5. CentOS 7&colon;如何安装防火墙&quest;

    对于纯净版的CentOS 7,您必须手动安装防火墙.但是你就算安装了防火墙还是不能马上运行它,你需要再做一些操作才能让它工作. 在CentOS 7中按照以下步骤来设置防火墙 第一步,通过yum安装sy ...

  6. Top 10 Uses of a Message Queue

    Top 10 Uses of a Message QueueAsynchronicity, Work Dispatch, Load Buffering, Database Offloading, an ...

  7. Rails &lpar;堆栈&rpar;&lt&semi;数据结构&gt&semi;

    题意:<看图片> 解题思路:栈的简单应用: #include<iostream> #include<stack> #include<algorithm> ...

  8. (转)spring aop&lpar;下)

    昨天记录了Spring AOP学习的一部分(http://www.cnblogs.com/yanbincn/archive/2012/08/13/2635413.html),本来是想一口气梳理完的.但 ...

  9. &lbrack;三&rsqb;JavaIO之IO体系类整体设计思路 流的概念以及四大基础分类

    从本文开始,将正式进入JavaIO的简介 在继续javaIO系列的文章之前 可以过去看一下 本人博客上的设计模式中的 适配器模式和装饰器模式 这会对接下来的阅读大有帮助   本文是从逻辑上介绍整个的J ...

  10. 《C&num;从现象到本质》读书笔记(六)第8章委托和事件

    <C#从现象到本质>读书笔记(六)第二部分 C#特性 第8章委托和事件 从这一部分开始,知识点就相对少了,重要的是代码练习.奈何太高深的代码平常不怎么用,这些特性也不是经常写代码的. 委托 ...