系统截图和 adb 截图
发布时间:2025-06-24 20:41:34 作者:北方职教升学中心 阅读量:712
系统截图和 adb 截图。截图原理
我们的手机一般同时按下音量-键和电源键就会将当前屏幕显示的内容截取下来,那里面具体经过哪些流程呢?
Android中每一个页面都是一个Activity,通过Window对象实现页面的显示,每个Window对象实际上都是PhoneWindow的实例,当我们在Activity页面点击屏幕的时候,会触发点击事件,这个事件会一层层分发到处理它的view上,大致会经过这些view:
先会调PhoneWindowManager中的dispatchUnhandledKey方法,一层层往下,这里不详细展开,我们往下找会发现最终会调用一个takeScreenshot截屏的方法:
privatevoidtakeScreenshot(){synchronized(mScreenshotLock){if(mScreenshotConnection !=null){return;}ComponentNamecn =newComponentName("com.android.systemui","com.android.systemui.screenshot.TakeScreenshotService");Intentintent =newIntent();intent.setComponent(cn);ServiceConnectionconn =newServiceConnection(){@OverridepublicvoidonServiceConnected(ComponentNamename,IBinderservice){synchronized(mScreenshotLock){if(mScreenshotConnection !=this){return;}Messengermessenger =newMessenger(service);Messagemsg =Message.obtain(null,1);finalServiceConnectionmyConn =this;Handlerh =newHandler(mHandler.getLooper()){@OverridepublicvoidhandleMessage(Messagemsg){synchronized(mScreenshotLock){if(mScreenshotConnection ==myConn){mContext.unbindService(mScreenshotConnection);mScreenshotConnection =null;mHandler.removeCallbacks(mScreenshotTimeout);}}}};msg.replyTo =newMessenger(h);msg.arg1 =msg.arg2 =0;if(mStatusBar !=null&&mStatusBar.isVisibleLw())msg.arg1 =1;if(mNavigationBar !=null&&mNavigationBar.isVisibleLw())msg.arg2 =1;try{messenger.send(msg);}catch(RemoteExceptione){}}}@OverridepublicvoidonServiceDisconnected(ComponentNamename){}};if(mContext.bindServiceAsUser(intent,conn,Context.BIND_AUTO_CREATE,UserHandle.CURRENT)){mScreenshotConnection =conn;mHandler.postDelayed(mScreenshotTimeout,10000);}}}
这里通过反射机制调用了TakeScreenshotService的bindServiceAsUser方法,创建TakeScreenshotService服务,再通过其内部的SurfaceControl.screenshot 生成 bitmap,生成图片成功会给系统发送通知。实现方式
Android 截图主要为四种:View 截图、实现方式
- 1. View截图
- 2. WebView截图
- 3. 屏幕截图
下面列出了一些常用的转换方法:
// Bitmap 转 Base64privatestaticStringgetBitmapString(Bitmapbitmap){Stringresult =null;ByteArrayOutputStreamout =null;try{if(bitmap !=null){out =newByteArrayOutputStream();bitmap.compress(Bitmap.CompressFormat.PNG,100,out); out.flush();out.close(); byte[]bitmapBytes =out.toByteArray();result =Base64.encodeToString(bitmapBytes,Base64.DEFAULT);}}catch(IOExceptione){e.printStackTrace();}finally{try{if(out !=null){out.flush();out.close();}}catch(IOExceptione){e.printStackTrace();}}returnresult;}// Bitmap 转 Byteprivatestaticbyte[]getBitmapByte(Bitmapbitmap){ByteArrayOutputStreamout =newByteArrayOutputStream();// 转换类型,压缩质量,字节流资源bitmap.compress(Bitmap.CompressFormat.PNG,100,out);try{out.flush();out.close();}catch(IOExceptione){e.printStackTrace();}returnout.toByteArray();}// Drawable 转 BitmappublicstaticBitmaptoBitmap(Drawabledrawable){if(drawable instanceofBitmapDrawable){return((BitmapDrawable)drawable).getBitmap();}elseif(drawable instanceofColorDrawable){//colorBitmapbitmap =Bitmap.createBitmap(32,32,Bitmap.Config.ARGB_8888);Canvascanvas =newCanvas(bitmap);canvas.drawColor(((ColorDrawable)drawable).getColor());returnbitmap;}elseif(drawable instanceofNinePatchDrawable){//.9.pngBitmapbitmap =Bitmap.createBitmap(drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight(),Bitmap.Config.ARGB_8888);Canvascanvas =newCanvas(bitmap);drawable.setBounds(0,0,drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight());drawable.draw(canvas);returnbitmap;}returnnull;}