截圖的幾種方法
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 。
這種方法不用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_1, new 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(this, true);
SnapUtils.saveBitmap2Pic(bitmap, "bqt0.jpg");
break;
case 1:
bitmap = SnapUtils.snapShot(this, false);
SnapUtils.saveBitmap2Pic(bitmap, "bqt1.jpg");
break;
case 2:
bitmap = SnapUtils.snapShot(this, v);
SnapUtils.saveBitmap2Pic(bitmap, "bqt2.jpg");
break;
case 3:
bitmap = SnapUtils.snapShot(this, tv);
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();
}
}
}