美文网首页
屏幕截图

屏幕截图

作者: Dapengyou | 来源:发表于2017-10-19 15:37 被阅读69次

    Activity界面区域划分

    如图:最大的红色区域是屏幕界面,绿色次大区域我们称之为“应用界面区域”,蓝色的区域我们称之为“View绘制区域”;屏幕顶端、应用界面区之外的那部分显示手机电池网络运营商信息的为“状态栏”,应用区域顶端、View绘制区外部显示Activity名称的部分我们称为“标题栏”。

    获取状态栏高度

    获取状态栏一般常用的有三种方法:

    1. 通过系统资源尺寸获取

      int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
      if(resourceId > 0){
          int statusBarHeight = getResources().getDimensionPixelSize(resourceId);
      }
          
      

    使用getIdentifier()方法

    方法一
    Resources resources = context.getResources();
    

    int resourceId = resources.getIdentifier(com.test.androidtest:drawable/icon",null,null);

    第一个参数格式是:包名 + : + 资源文件夹名 + / +资源名,然后其他的可以为null
    #####方法二
    

    Resources resources = context.getResources();
    int resourceId = getResources().getIdentifier("icon", "drawable", "com.test.androidtest");

    第一个参数为ID名,第二个为资源属性是ID或者是Drawable,第三个为包名。
    
    一般来讲是推荐第二种方法
    

    在获取状态栏高度时, 因为状态栏高度定义在Android系统尺寸资源中status_bar_height,但并不能公开使用,一般会像这样使用:android.R.dimen.status_bar_height,由于系统为我们提供了一个Resource类,所以我们可以通过这个类来获取资源 status_bar_height.

    因此代码的写法是

    int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
    

    可对照getIdentifier()的方法二进行比对

    1. 使用屏幕和应用区域高度的差值确定

        // 获取状态栏高度
       Rect frame = new Rect();
       // 测量屏幕宽和高
       view.getWindowVisibleDisplayFrame(frame);
       int stautsHeight = frame.top;
      

      如果单单获取statusBar高度而不获取titleBar高度时,这种方法并不推荐大家使用,因为这种方法依赖于WMS(窗口管理服务的回调)。正是因为窗口回调机制,所以在Activity初始化时执行此方法得到的高度是0,这就是很多人获取到statusBar高度为0的原因。这个方法推荐在回调方法onWindowFocusChanged()中执行,才能得到预期结果。

    2. 使用应用区域的top属性

       //屏幕  
       DisplayMetrics dm = new DisplayMetrics();  
       
       getWindowManager().getDefaultDisplay().getMetrics(dm);  
      
       //应用区域  
       Rect outRect1 = new Rect();  
      
       getWindow().getDecorView().getWindowVisibleDisplayFrame(outRect1);  
      
      int statusBar = dm.heightPixels - outRect1.height();  //状态栏高度=屏幕高度-应用区域高度  
      

    获取标题栏高度

    1. 通过View提供的方法获取高度
      int viewTop = activity.getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();
    
    

    通过Activity的getWindow().findViewById(Window.ID_ANDROID_CONTENT)获取系统当前显示的view根(是一个framelayout对象),android绘制会将要绘制的view放置在framelayout中绘制。

    1. 通过屏幕获取高度
           int statusHeight = -1;
        //屏幕
           DisplayMetrics dm = new DisplayMetrics();
    
           activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
    
           int resourceId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
    
           if (resourceId > 0) {
    
               statusHeight = activity.getResources().getDimensionPixelSize(resourceId);
    
           } 
           //View绘制区域,//viewtop方法一
           Rect outRect2 = new Rect();
           activity.getWindow().findViewById(Window.ID_ANDROID_CONTENT).getDrawingRect(outRect2);
           int viewTop = dm.heightPixels - statusHeight - outRect2.height();
    
    

    写入SD卡

     private static boolean savePic(Bitmap pBitmap, File strName) {
            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream(strName);
                if (null != fos) {
                    pBitmap.compress(Bitmap.CompressFormat.PNG, 90, fos);
                    fos.flush();
                    fos.close();
                    return true;
                }
    
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return false;
        }
    

    关于flush()方法,api中有如下描述

    刷新此输出流并强制写出所有缓冲的输出字节(刷新数据并将数据转交给操作系统 )

    实现截图

     /**
         * 截图
         *
         * @param activity
         * @return 截图并且保存sdcard成功返回true,否则返回false
         */
        public static boolean shotBitmap(Activity activity) {
            String sdCardDir = Environment.getExternalStorageDirectory() + "/jietu/";
            File dirFile = new File(sdCardDir);  //目录转化成文件夹
            if (!dirFile.exists()) {              //如果不存在,那就建立这个文件夹
                dirFile.mkdirs();
            }
            //指定目录
            File file = new File(sdCardDir, System.currentTimeMillis() + ".png");
            return ScreenShotUtils.savePic(takeScreenShot(activity), file);
        }
    

    Environment.getExternalStorageDirectory()是获得根目录,System.currentTimeMillis()是获得系统时间

    File file = new File(sdCardDir, System.currentTimeMillis() + ".png");

    这句话的意思就是,截下来的图以 ==当前系统时间戳.png== 的形式存到根目录下的 ==jietu== 文件夹下。

    终极代码

    MainActivity:

    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            Button button = (Button) findViewById(R.id.btn);
    
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    boolean result = ScreenShotUtils.shotBitmap(MainActivity.this);
                    if (result) {
                        Toast.makeText(MainActivity.this, "截图成功.", Toast.LENGTH_SHORT).show();
                    } else {
                        Toast.makeText(MainActivity.this, "截图失败.", Toast.LENGTH_SHORT).show();
                    }
                }
            });
    
        }
    }
    

    ScreenShotUtils:

    /**
     * 进行截屏工具类
     */
    public class ScreenShotUtils {
        /**
         * 进行截取屏幕
         *
         * @param activity
         * @return bitmap
         */
        public static Bitmap takeScreenShot(Activity activity) {
            Bitmap bitmap = null;
            int statusHeight = -1;
            View view = activity.getWindow().getDecorView();
            // 设置是否可以进行绘图缓存
            view.setDrawingCacheEnabled(true);
            // 如果绘图缓存无法,强制构建绘图缓存
            view.buildDrawingCache();
            // 返回这个缓存视图
            bitmap = view.getDrawingCache();
            Log.d("123", "bitmap.getHeight():" + bitmap.getHeight());
    
            int resourceId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
            if (resourceId > 0) {
    
                statusHeight = activity.getResources().getDimensionPixelSize(resourceId);
    
            }
            int viewTop = activity.getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();
    
            int width = activity.getWindowManager().getDefaultDisplay().getWidth();
            int height = activity.getWindowManager().getDefaultDisplay().getHeight();
            // 根据坐标点和需要的宽和高创建bitmap
            bitmap = Bitmap.createBitmap(bitmap, 0, statusHeight + viewTop, width, height - statusHeight - viewTop);
            return bitmap;
        }
    
    
        /**
         * 保存图片到sdcard中
         *
         * @param pBitmap
         */
        private static boolean savePic(Bitmap pBitmap, File strName) {
            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream(strName);
                if (null != fos) {
                    pBitmap.compress(Bitmap.CompressFormat.PNG, 90, fos);
                    fos.flush();
                    fos.close();
                    return true;
                }
    
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return false;
        }
    
        /**
         * 截图
         *
         * @param activity
         * @return 截图并且保存sdcard成功返回true,否则返回false
         */
        public static boolean shotBitmap(Activity activity) {
            String sdCardDir = Environment.getExternalStorageDirectory() + "/wurenji/";
            File dirFile = new File(sdCardDir);  //目录转化成文件夹
            if (!dirFile.exists()) {              //如果不存在,那就建立这个文件夹
                dirFile.mkdirs();
            }
            //指定目录
            File file = new File(sdCardDir, System.currentTimeMillis() + ".png");
            return ScreenShotUtils.savePic(takeScreenShot(activity), file);
        }
    
    
    }
    

    activity_main.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:background="@color/gray"
        tools:context="com.test.screenshot.MainActivity">
    
        <TextView
            android:id="@+id/tv"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="点击截图哦"
            android:gravity="center"
            android:padding="10dp"
            android:textSize="20sp" />
    
        <ImageView
            android:id="@+id/img"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="10dip"
            android:scaleType="fitXY" />
    
        <Button
            android:id="@+id/btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="10dip"
            android:text="点击截图" />
    
    </LinearLayout>
    
    

    参考博客

    相关文章

      网友评论

          本文标题:屏幕截图

          本文链接:https://www.haomeiwen.com/subject/qtouuxtx.html