Android 截圖實現的幾種方式
Android 截圖分為四種:View 截圖、WebView 截圖、系統截圖 和 adb 截圖
1、View 截圖
View 截圖是將當前 View 介面擷取下來,而對於螢幕上其他資訊比如:狀態列或其他應用的介面將無法擷取。
1.1 擷取除了導航欄之外的螢幕
// 開始截圖
private static byte[] screenshotView() {
// ⬇⬇⬇ 可直接放入點選事件中 ⬇⬇⬇
View view = getWindow().getDecorView(); // view可以替換成你需要截圖的控制元件,如父控制元件 RelativeLayout,LinearLayout
// view.setDrawingCacheEnabled(true); // 設定快取,可用於實時截圖
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
// view.setDrawingCacheEnabled(false); // 清空快取,可用於實時截圖
String bitmapString = getBitmapString(bitmap); // 點陣圖轉 Base64 String
// byte[] drawByte = getBitmapByte(bitmap); // 點陣圖轉為 Byted
Log.d("111111 合併>>", "bitmapString ====:" + bitmapString);
matting_img02.setImageBitmap(bitmap); // ImageView控制元件直接圖片展示截好的圖片
// ⬆⬆⬆ 可直接放入點選事件中 ⬆⬆⬆
return drawByte;
}
// 點陣圖轉 Base64 String
private static String getBitmapString(Bitmap bitmap) {
String result = null;
ByteArrayOutputStream out = null;
try {
if (bitmap != null) {
out = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
byte[] bitmapBytes = out.toByteArray();
result = Base64.encodeToString(bitmapBytes, Base64.DEFAULT); // Base64.DEFAULT會自動換行,傳給前端會報錯,所以要用Base64.NO_WRAP
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.flush();
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
// 點陣圖轉 Byte
private static byte[] getBitmapByte(Bitmap bitmap) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
// 引數1轉換型別,引數2壓縮質量,引數3位元組流資源
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
try {
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
return out.toByteArray();
}
1.2 擷取某個控制元件或者區域
// 方法1
private static byte[] screenshotView1() {
View view = title;
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache());
byte[] drawByte = getBitmapByte(bitmap);
return drawByte;
}
// 方法2
private static byte[] screenshotView2() {
View view = title;
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
// 使用 Canvas,呼叫自定義 view 控制元件的 onDraw 方法,繪製圖片
Canvas canvas = new Canvas(bitmap);
dView.draw(canvas);
byte[] drawByte = getBitmapByte(bitmap);
return drawByte;
}
2、WebView 截圖
WebView 截圖有四種方式
2.1 使用 capturePicture() 方法(已廢棄)
private static byte[] screenshotWebView() {
Picture picture = webview.capturePicture();
//建立點陣圖
Bitmap bitmap = Bitmap.createBitmap(picture.getWidth(), picture.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
// 繪製(會呼叫 native 方法,完成圖形繪製)
picture.draw(canvas);
byte[] drawByte = getBitmapByte(bitmap);
return drawByte;
}
2.2 使用 getScale() 方法(已廢棄)
private static byte[] screenshotWebView() {
float scale = webView.getScale();
int webViewHeight = (int) (webView.getContentHeight()*scale+0.5);
Bitmap bitmap = Bitmap.createBitmap(webView.getWidth(),webViewHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
webView.draw(canvas);
byte[] drawByte = getBitmapByte(bitmap);
return drawByte;
}
2.3 使用 getDrawingCache() 方法
private static byte[] screenshotWebView() {
Bitmap bitmap = webView.getDrawingCache();
byte[] drawByte = getBitmapByte(bmp);
return drawByte;
}
2.4 使用 draw() 方法
private static byte[] screenshotWebView() {
// webView.setDrawingCacheEnabled(true); // 設定快取
Bitmap bitmap = Bitmap.createBitmap(webView.getWidth(), webView.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
webView.draw(canvas);
webView.destroyDrawingCache();
byte[] drawByte = getBitmapByte(bitmap);
// webView.setDrawingCacheEnabled(false); // 清空快取
return drawByte;
}
2.5 截長圖配置
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
WebView.enableSlowWholeDocumentDraw();
}
setContentView(R.layout.activity_webview);
WebView 截圖可能擷取不到 cavans 元素,原因是開啟了硬體加速,可在 AndroidManifest.xml 中設定屬性 android:hardwareAccelerated="false"
關閉硬體加速可能導致頁面出現意外情況
3、系統截圖
3.1 MediaProjection
public static final int REQUEST_MEDIA_PROJECTION = 10001;
// 申請截圖許可權
private void getScreenShotPower() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
MediaProjectionManager mProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
if (mProjectionManager != null) {
startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_MEDIA_PROJECTION);
}
}
}
private MediaProjection mMediaProjection;
// 回撥
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_MEDIA_PROJECTION && data != null) {
if (resultCode == RESULT_OK) {
MediaProjection mediaProjection = mMediaProjectionManager.getMediaProjection(resultCode, data);
if (mediaProjection == null) {
Toast.makeText(this,"程式發生錯誤:MediaProjection@1",Toast.LENGTH_SHORT).show();
return;
}
// mediaProjection 就是當前螢幕流
} else if (resultCode == RESULT_CANCELED) {
Log.d(TAG, "使用者取消");
}
}
}
3.2 Surface(需要 root 許可權)
使用前需要:
在 AndroidMenifest.xml 中新增 android:sharedUserId="android.uid.system" 屬性
需要給程式新增系統簽名
或者 root 系統
使用 Java 反射機制,呼叫系統 API 截圖:
private void screenshotSystem() {
Class<?> surfaceClass;
Method method = null;
Bitmap bitmap = null;
try {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
surfaceClass = Class.forName("android.view.SurfaceControl");
} else {
surfaceClass = Class.forName("android.view.Surface");
}
method = surfaceClass.getDeclaredMethod("screenshot", Integer.TYPE, Integer.TYPE);
method.setAccessible(true);
bitmap = (Bitmap)method.invoke((Object)null, webview.getWidth(), webview.getHeight());
byte[] drawByte = getBitmapByte(bitmap);
} catch (ClassNotFoundException e){
e.printStackTrace();
} catch (NoSuchMethodException e){
e.printStackTrace();
} catch (IllegalAccessException e){
e.printStackTrace();
} catch (InvocationTargetException e){
e.printStackTrace();
}
}
3.3 PixelCopy
private void screenshotSystem() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
PixelCopy.request(getWindow(), bitmap, new PixelCopy.OnPixelCopyFinishedListener() {
@Override
public void onPixelCopyFinished(int copyResult){
if (PixelCopy.SUCCESS == copyResult) {
byte[] drawByte = getBitmapByte(bitmap);
} else {
// onErrorCallback()
}
}
}, new Handler());
}
}
3.4 framebuffer(需要 root 許可權)
String DEVICE_NAME = "/dev/graphics/fb0";
File deviceFile = new File(DEVICE_NAME);
Process localProcess = Runtime.getRuntime().exec("supersu");
String str = "cat " + deviceFile.getAbsolutePath() + "\n";
localProcess.getOutputStream().write(str.getBytes());
return localProcess.getInputStream();
3.5 screencap 命令(需要 root 許可權)
private static String getScreenshot(){
Process process = null;
String filePath = "mnt/sdcard/" + System.currentTimeMillis() + ".png";
try {
process = Runtime.getRuntime().exec("su");
PrintStream outputStream = null;
outputStream = new PrintStream(new BufferedOutputStream(process.getOutputStream(), 8192));
outputStream.println("screencap -p " + filePath);
outputStream.flush();
outputStream.close();
process.waitFor();
} catch (Exception e) {
e.printStackTrace();
} finally {
if(process != null){
process.destroy();
}
}
return filePath;
}
4、adb 截圖
-
$ adb shell
-
shell@ $ screencap /sdcard / screen.png
-
shell@ $ exit
-
$ adb pull /sdcard / screen.png
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70033950/viewspace-2987340/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- python 三種方式實現截圖Python
- Android長截圖的實現Android
- 實現 JavaScript 沙箱的幾種方式JavaScript
- css實現圖片自適應容器的幾種方式CSS
- AOP 有幾種實現方式?
- 實現登入態的幾種方式
- java幾種代理模式的實現方式Java模式
- 分散式鎖的幾種實現方式~分散式
- 互動投影的幾種實現方式
- Android 截圖的各種騷操作Android
- 分散式事務的幾種實現方式分散式
- css實現水平垂直居中的幾種方式CSS
- Android生成ViewModel例項的幾種方式AndroidView
- win10怎麼截圖_win10截圖的幾種方法Win10
- 實現繼承的幾種方式及工作原理繼承
- 三欄式佈局的幾種實現方式
- 幾種實現延時任務的方式(一)
- 【工具篇】在.Net中實現HTML生成圖片或PDF的幾種方式HTML
- 兩種方式實現輪播圖
- js實現繼承的幾種方式和對比JS繼承
- Java建立多執行緒的幾種方式實現Java執行緒
- 小結:二叉樹的幾種實現方式二叉樹
- web前端換行程式碼的幾種實現方式!Web前端行程
- 實現圖片染色效果的三種方式
- 紅魔Mars手機怎麼截圖截圖?紅魔Mars手機的幾種螢幕截圖方法
- css3實現動畫有幾種方式?CSSS3動畫
- 實現圖片懶載入的三種方式
- Android回顧--(十二) 資料儲存的幾種方式Android
- Android中取消系統標題欄的幾種方式Android
- js實現視訊截圖,視訊批量截圖,canvas實現JSCanvas
- 玩轉SpringBoot:SpringBoot的幾種定時任務實現方式Spring Boot
- React 提供了幾種方式來實現條件渲染React
- Python網頁截圖/螢幕截圖/截長圖如何實現?Python網頁
- 使用Vue實現圖片上傳的三種方式Vue
- C#委託的幾種表現方式C#
- UIView設定背景圖片幾種方式UIView
- 手把手教你實現Android真機遠端截圖Android
- 突破Android P非SDK API限制的幾種程式碼實現AndroidAPI