標籤:des android style http io color ar os 使用
今天做項目要用到android截屏功能,一開始我還慶幸看過一些部落格的文章,自信能輕鬆解決。。。- - 結果坑了一天才搞了個差不多的交差。。。哎!
關於android截屏的代碼,大致有3種方法,有興趣的看下去吧。
方法一:
網上看了很多文章,大多用的是這樣的方法,直接把一個View轉換成Bitmap,然後儲存到sd卡。
/**
* 根據view來產生bitmap圖片,可用於功能
*/
public static Bitmap getViewBitmap(View v) {
v.clearFocus(); //
v.setPressed(false); //
// 能畫緩衝就返回false
boolean willNotCache = v.willNotCacheDrawing();
v.setWillNotCacheDrawing(false);
int color = v.getDrawingCacheBackgroundColor();
v.setDrawingCacheBackgroundColor(0);
if (color != 0) {
v.destroyDrawingCache();
}
v.buildDrawingCache();
Bitmap cacheBitmap = v.getDrawingCache();
if (cacheBitmap == null) {
return null;
}
Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);
// Restore the view
v.destroyDrawingCache();
v.setWillNotCacheDrawing(willNotCache);
v.setDrawingCacheBackgroundColor(color);
return bitmap;
}
/**
* 儲存Bitmap圖片為本地檔案
*/
public static void saveFile(Bitmap bitmap, String filename) {
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(filename);
if (fileOutputStream != null) {
bitmap.compress(Bitmap.CompressFormat.PNG, 90, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
}
} catch (FileNotFoundException e) {
L.d("Exception:FileNotFoundException");
e.printStackTrace();
} catch (IOException e) {
L.d("IOException:IOException");
e.printStackTrace();
}
}
這個方法用起來很簡單,saveFile(getViewBitmap(view),filename);一句代碼就搞定了。
不過在項目裡用上之後坑爹的發現WebView截不了圖!!QAQ 好吧,只好無奈的到處找資料。
翻遍百度Google找到了這樣的代碼:
/**
* 截取webView可視地區的
* @param webView 前提:WebView要設定webView.setDrawingCacheEnabled(true);
* @return
*/
public static Bitmap captureWebViewVisibleSize(WebView webView) {
Bitmap bmp = webView.getDrawingCache();
return bmp;
}
/**
* 截取webView快照(webView載入的整個內容的大小)
* @param webView
* @return
*/
public static Bitmap captureWebView(WebView webView) {
Picture snapShot = webView.capturePicture();
Bitmap bmp = Bitmap.createBitmap(snapShot.getWidth(),
snapShot.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmp);
snapShot.draw(canvas);
return bmp;
}
不過還是解決不了我的問題,原因我想應該是我的webview是用了anychart的js檔案和swf檔案來組建圖表的,網上也找到一些人情況跟我一樣,說是用了swf的網頁不能。
方法二:
截取當前Activity的視圖並儲存。這個可以說比方法一更簡單,只是不夠靈活,因為截的圖是整個螢幕,可是我又不要狀態列和標題列。QAQ
不過如果成功的話,可以把截的圖裁剪一下取出自己需要的部分,也是沒問題的。可惜這個方法也不能截出WebView的動態圖表。
代碼給出如下:
/**
* 截屏
* @param activity
* @return
*/
public static Bitmap captureScreen(Activity activity) {
activity.getWindow().getDecorView().setDrawingCacheEnabled(true);
Bitmap bmp=getWindow().getDecorView().getDrawingCache();
return bmp;
}
其實這個方法也算是方法一的延伸,都是用到View的getDrawingCache()方法來擷取Bitmap,所以不行也是理所當然的。
方法三:
第三種方法是用FrameBuffer實現的截屏,這才是真正意義上的!(哎,加班了1個小時,終於讓我找到些眉目了!)
先介紹下FrameBuffer:framebuffer是linux核心對顯示的最底層驅動。在一般的linux檔案系統中,通過/dev/fb0裝置檔案來提供給應用程式對framebuffer進行讀寫的訪問。這裡,如果有多個顯示裝置,就將依次出現fb1,fb2,…等檔案。而在我們所說的android系統中,這個裝置檔案被放在了/dev/graphics/fb0,而且往往只有這一個。
(你看懂了嗎?反正我看不懂。。。)
至於詳細的原理有興趣的可以去百度“FrameBuffer中擷取Android螢幕”
下面說我整理的代碼,經測試在My Phone上是可以成功的,使用了anychart的webview也能截下來。
/**
* 截屏
* @param activity
* @return
*/
public static Bitmap captureScreen(Activity activity) {
// 擷取螢幕大小:
DisplayMetrics metrics = new DisplayMetrics();
WindowManager WM = (WindowManager) activity
.getSystemService(Context.WINDOW_SERVICE);
Display display = WM.getDefaultDisplay();
display.getMetrics(metrics);
int height = metrics.heightPixels; // 螢幕高
int width = metrics.widthPixels; // 螢幕的寬
// 擷取顯示方式
int pixelformat = display.getPixelFormat();
PixelFormat localPixelFormat1 = new PixelFormat();
PixelFormat.getPixelFormatInfo(pixelformat, localPixelFormat1);
int deepth = localPixelFormat1.bytesPerPixel;// 位深
byte[] piex = new byte[height * width * deepth];
try {
Runtime.getRuntime().exec(
new String[] { "/system/bin/su", "-c",
"chmod 777 /dev/graphics/fb0" });
} catch (IOException e) {
e.printStackTrace();
}
try {
// 擷取fb0資料輸入流
InputStream stream = new FileInputStream(new File(
"/dev/graphics/fb0"));
DataInputStream dStream = new DataInputStream(stream);
dStream.readFully(piex);
} catch (Exception e) {
e.printStackTrace();
}
// 儲存圖片
int[] colors = new int[height * width];
for (int m = 0; m < colors.length; m++) {
int r = (piex[m * 4] & 0xFF);
int g = (piex[m * 4 + 1] & 0xFF);
int b = (piex[m * 4 + 2] & 0xFF);
int a = (piex[m * 4 + 3] & 0xFF);
colors[m] = (a << 24) + (r << 16) + (g << 8) + b;
}
// piex產生Bitmap
Bitmap bitmap = Bitmap.createBitmap(colors, width, height,
Bitmap.Config.ARGB_8888);
return bitmap;
}
記得在AndroidManifest.xml加上兩行許可權:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_FRAME_BUFFER" />
還有需要注意的是,手機需要root許可權,沒root過的手機我還沒試過,但估計是不行的。
所以搞了大半天,還是不滿意!又不是每個人的手機都有root許可權。。。QAQ 但也已經儘力了,先這樣吧!之後會改進的~
Android新姿勢:截屏代碼整理