由於要做說明書,或者給客戶看,不得不通過的方式把螢幕接下來(當然了,還可以通過拍照來達到目的)。於是就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;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);new Thread(new Runnable() {@Overridepublic 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 orientationmDisplayMatrix.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