您的位置:首页 > 移动开发 > Android开发

【Android应用开发】-(13)屏幕截图功能--截取全屏,无需Root(附源码)

2013-01-30 23:19 567 查看
http://blog.csdn.net/tangcheng_ok/article/details/7688715

由于要做说明书,或者给客户看效果图,不得不通过截图的方式把屏幕接下来(当然了,还可以通过拍照来达到目的)。于是就Google找到一些需要Root权限,和不需要Root权限的截图应用,有些失望,多数不可用。于是就想自己开发一个截图的应用。在View 中提供一个getDrawingCache的方法,可以通过次方法获取View的截屏,但仅仅是截取View的。如果要截取状态栏呢?

    其实不然,在ICS中的SystemUI就实现了截图的功能,按组合键Power+Volume Add/Volume sub就能截取图片。代码目录:

frameworks/base/packages/SystemUI/src/com/android/systemui/screenshot/在此目录下就两个文件,主要的截图方法在GlobalScreenshot中,本文就通过移植SystemUI中截图的代码实现截图功能。

    首先是直接移植SystemUI的代码,实现截图效果,这部分的代码就不贴出来了,直接去下载代码吧,
关键的代码没有几句,最最主要的是:Surface.screenshot(),请看代码吧。

<span style="font-size:16px;">package org.winplus.ss;  

  

import java.io.File;  

import java.io.FileNotFoundException;  

import java.io.FileOutputStream;  

import java.io.IOException;  

import java.text.SimpleDateFormat;  

import java.util.Date;  

  

import android.app.Activity;  

import android.content.Context;  

import android.graphics.Bitmap;  

import android.graphics.Canvas;  

import android.graphics.Matrix;  

import android.os.Bundle;  

import android.util.DisplayMetrics;  

import android.util.Log;  

import android.view.Display;  

import android.view.Surface;  

import android.view.WindowManager;  

import android.os.SystemProperties;  

  

public class SimpleScreenshotActivity extends Activity {  

  

    private Display mDisplay;  

    private WindowManager mWindowManager;  

    private DisplayMetrics mDisplayMetrics;  

    private Bitmap mScreenBitmap;  

    private Matrix mDisplayMatrix;  

  

    @Override  

    public void onCreate(Bundle savedInstanceState) {  

        super.onCreate(savedInstanceState);  

        setContentView(R.layout.main);  

  

        new Thread(new Runnable() {  

  

            @Override  

            public void run() {  

                takeScreenshot();  

  

            }  

        }).start();  

    }  

  

    private float getDegreesForRotation(int value) {  

        switch (value) {  

        case Surface.ROTATION_90:  

            return 360f - 90f;  

        case Surface.ROTATION_180:  

            return 360f - 180f;  

        case Surface.ROTATION_270:  

            return 360f - 270f;  

        }  

        return 0f;  

    }  

  

    private void takeScreenshot() {  

        mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);  

        mDisplay = mWindowManager.getDefaultDisplay();  

        mDisplayMetrics = new DisplayMetrics();  

        mDisplay.getRealMetrics(mDisplayMetrics);  

        mDisplayMatrix = new Matrix();  

        float[] dims = { mDisplayMetrics.widthPixels,  

                mDisplayMetrics.heightPixels };  

  

        int value = mDisplay.getRotation();  

        String hwRotation = SystemProperties.get("ro.sf.hwrotation", "0");  

        if (hwRotation.equals("270") || hwRotation.equals("90")) {  

            value = (value + 3) % 4;  

        }  

        float degrees = getDegreesForRotation(value);  

  

        boolean requiresRotation = (degrees > 0);  

        if (requiresRotation) {  

            // Get the dimensions of the device in its native orientation  

            mDisplayMatrix.reset();  

            mDisplayMatrix.preRotate(-degrees);  

            mDisplayMatrix.mapPoints(dims);  

  

            dims[0] = Math.abs(dims[0]);  

            dims[1] = Math.abs(dims[1]);  

        }  

  

        mScreenBitmap = Surface.screenshot((int) dims[0], (int) dims[1]);  

  

        if (requiresRotation) {  

            // Rotate the screenshot to the current orientation  

            Bitmap ss = Bitmap.createBitmap(mDisplayMetrics.widthPixels,  

                    mDisplayMetrics.heightPixels, Bitmap.Config.ARGB_8888);  

            Canvas c = new Canvas(ss);  

            c.translate(ss.getWidth() / 2, ss.getHeight() / 2);  

            c.rotate(degrees);  

            c.translate(-dims[0] / 2, -dims[1] / 2);  

            c.drawBitmap(mScreenBitmap, 0, 0, null);  

            c.setBitmap(null);  

            mScreenBitmap = ss;  

        }  

  

        // If we couldn't take the screenshot, notify the user  

        if (mScreenBitmap == null) {  

            return;  

        }  

  

        // Optimizations  

        mScreenBitmap.setHasAlpha(false);  

        mScreenBitmap.prepareToDraw();  

          

        try {  

            saveBitmap(mScreenBitmap);  

        } catch (IOException e) {  

            System.out.println(e.getMessage());  

        }  

    }  

  

    public void saveBitmap(Bitmap bitmap) throws IOException {  

        String imageDate = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss")  

                .format(new Date(System.currentTimeMillis()));  

        File file = new File("/mnt/sdcard/Pictures/"+imageDate+".png");  

        if(!file.exists()){  

            file.createNewFile();  

        }  

        FileOutputStream out;  

        try {  

            out = new FileOutputStream(file);  

            if (bitmap.compress(Bitmap.CompressFormat.PNG, 70, out)) {  

                out.flush();  

                out.close();  

            }  

        } catch (FileNotFoundException e) {  

            e.printStackTrace();  

        } catch (IOException e) {  

            e.printStackTrace();  

        }  

    }  

}  

</span>  

PS:1、需要在AndroidManifest.xml中加入代码:android:sharedUserId="android.uid.system"

         2、由于调用了@hide的API,所以编译得时候请使用makefile编译。或者通过在Eclipse中添加Jar文件通过编译。

         3、此代码只在Android4.0中使用过,2.3的就没去做测试了。

原创文章转载请注明出处:http://www.blog.csdn.net/tangcheng_ok

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐