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

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

2012-06-25 09:36 423 查看
由于要做说明书,或者给客户看效果图,不得不通过截图的方式把屏幕接下来(当然了,还可以通过拍照来达到目的)。于是就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(),请看代码吧。

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();
		}
	}
}


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