屏幕截图功能--截取全屏,无需Root(附源码)

来源:互联网 发布:app阅读软件 编辑:程序博客网 时间:2024/05/17 00:02

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

  1. <span style="font-size:16px;">package org.winplus.ss;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileNotFoundException;  
  5. import java.io.FileOutputStream;  
  6. import java.io.IOException;  
  7. import java.text.SimpleDateFormat;  
  8. import java.util.Date;  
  9.   
  10. import android.app.Activity;  
  11. import android.content.Context;  
  12. import android.graphics.Bitmap;  
  13. import android.graphics.Canvas;  
  14. import android.graphics.Matrix;  
  15. import android.os.Bundle;  
  16. import android.util.DisplayMetrics;  
  17. import android.util.Log;  
  18. import android.view.Display;  
  19. import android.view.Surface;  
  20. import android.view.WindowManager;  
  21. import android.os.SystemProperties;  
  22.   
  23. public class SimpleScreenshotActivity extends Activity {  
  24.   
  25.     private Display mDisplay;  
  26.     private WindowManager mWindowManager;  
  27.     private DisplayMetrics mDisplayMetrics;  
  28.     private Bitmap mScreenBitmap;  
  29.     private Matrix mDisplayMatrix;  
  30.   
  31.     @Override  
  32.     public void onCreate(Bundle savedInstanceState) {  
  33.         super.onCreate(savedInstanceState);  
  34.         setContentView(R.layout.main);  
  35.   
  36.         new Thread(new Runnable() {  
  37.   
  38.             @Override  
  39.             public void run() {  
  40.                 takeScreenshot();  
  41.   
  42.             }  
  43.         }).start();  
  44.     }  
  45.   
  46.     private float getDegreesForRotation(int value) {  
  47.         switch (value) {  
  48.         case Surface.ROTATION_90:  
  49.             return 360f - 90f;  
  50.         case Surface.ROTATION_180:  
  51.             return 360f - 180f;  
  52.         case Surface.ROTATION_270:  
  53.             return 360f - 270f;  
  54.         }  
  55.         return 0f;  
  56.     }  
  57.   
  58.     private void takeScreenshot() {  
  59.         mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);  
  60.         mDisplay = mWindowManager.getDefaultDisplay();  
  61.         mDisplayMetrics = new DisplayMetrics();  
  62.         mDisplay.getRealMetrics(mDisplayMetrics);  
  63.         mDisplayMatrix = new Matrix();  
  64.         float[] dims = { mDisplayMetrics.widthPixels,  
  65.                 mDisplayMetrics.heightPixels };  
  66.   
  67.         int value = mDisplay.getRotation();  
  68.         String hwRotation = SystemProperties.get("ro.sf.hwrotation""0");  
  69.         if (hwRotation.equals("270") || hwRotation.equals("90")) {  
  70.             value = (value + 3) % 4;  
  71.         }  
  72.         float degrees = getDegreesForRotation(value);  
  73.   
  74.         boolean requiresRotation = (degrees > 0);  
  75.         if (requiresRotation) {  
  76.             // Get the dimensions of the device in its native orientation  
  77.             mDisplayMatrix.reset();  
  78.             mDisplayMatrix.preRotate(-degrees);  
  79.             mDisplayMatrix.mapPoints(dims);  
  80.   
  81.             dims[0] = Math.abs(dims[0]);  
  82.             dims[1] = Math.abs(dims[1]);  
  83.         }  
  84.   
  85.         mScreenBitmap = Surface.screenshot((int) dims[0], (int) dims[1]);  
  86.   
  87.         if (requiresRotation) {  
  88.             // Rotate the screenshot to the current orientation  
  89.             Bitmap ss = Bitmap.createBitmap(mDisplayMetrics.widthPixels,  
  90.                     mDisplayMetrics.heightPixels, Bitmap.Config.ARGB_8888);  
  91.             Canvas c = new Canvas(ss);  
  92.             c.translate(ss.getWidth() / 2, ss.getHeight() / 2);  
  93.             c.rotate(degrees);  
  94.             c.translate(-dims[0] / 2, -dims[1] / 2);  
  95.             c.drawBitmap(mScreenBitmap, 00null);  
  96.             c.setBitmap(null);  
  97.             mScreenBitmap = ss;  
  98.         }  
  99.   
  100.         // If we couldn't take the screenshot, notify the user  
  101.         if (mScreenBitmap == null) {  
  102.             return;  
  103.         }  
  104.   
  105.         // Optimizations  
  106.         mScreenBitmap.setHasAlpha(false);  
  107.         mScreenBitmap.prepareToDraw();  
  108.           
  109.         try {  
  110.             saveBitmap(mScreenBitmap);  
  111.         } catch (IOException e) {  
  112.             System.out.println(e.getMessage());  
  113.         }  
  114.     }  
  115.   
  116.     public void saveBitmap(Bitmap bitmap) throws IOException {  
  117.         String imageDate = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss")  
  118.                 .format(new Date(System.currentTimeMillis()));  
  119.         File file = new File("/mnt/sdcard/Pictures/"+imageDate+".png");  
  120.         if(!file.exists()){  
  121.             file.createNewFile();  
  122.         }  
  123.         FileOutputStream out;  
  124.         try {  
  125.             out = new FileOutputStream(file);  
  126.             if (bitmap.compress(Bitmap.CompressFormat.PNG, 70, out)) {  
  127.                 out.flush();  
  128.                 out.close();  
  129.             }  
  130.         } catch (FileNotFoundException e) {  
  131.             e.printStackTrace();  
  132.         } catch (IOException e) {  
  133.             e.printStackTrace();  
  134.         }  
  135.     }  
  136. }  
  137. </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

原创粉丝点击