Android 5.0之前屏幕截圖的方法


截圖的幾種方法

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_1new 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(thistrue);
            SnapUtils.saveBitmap2Pic(bitmap, "bqt0.jpg");
            break;
        case 1:
            bitmap = SnapUtils.snapShot(thisfalse);
            SnapUtils.saveBitmap2Pic(bitmap, "bqt1.jpg");
            break;
        case 2:
            bitmap = SnapUtils.snapShot(this, v);
            SnapUtils.saveBitmap2Pic(bitmap, "bqt2.jpg");
            break;
        case 3:
            bitmap = SnapUtils.snapShot(thistv);
            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();
        }
    }
}






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM