recently in the process of doing Android applications encountered a lot of problems, touch a number of methods, but still can not achieve the Sufaceview function. Today, I tried to summarize the method, I hope to write my painful experience can help to do this function of friends less detours, or to give some ideas. If any hero can do Surfaceview, please share the next ideas.
First, the function realizes without the Surfaceview condition
Public StaticBitmap takescreenshot (Activity Act) {if(act = =NULL||act.isfinishing ()) {LOG.D (TAG,"the act parameter is empty."); return NULL; } //gets the view of the currentView Scrview =Act.getwindow (). Getdecorview (); Scrview.setdrawingcacheenabled (true); Scrview.builddrawingcache (true); //Get status bar heightRect Statubarrect =NewRect (); Scrview.getwindowvisibledisplayframe (Statubarrect); intStatusbarheight =Statubarrect.top; intwidth =Act.getwindowmanager (). Getdefaultdisplay (). GetWidth (); intHeight =Act.getwindowmanager (). Getdefaultdisplay (). GetHeight (); Bitmap scrbmp=NULL; Try { //Remove the title barScrbmp = Bitmap.createbitmap (Scrview.getdrawingcache (),0, statusbarheight, width, height-statusbarheight); } Catch(IllegalArgumentException e) {log.d ("","# # # Rotating the screen causes the status bar to fail"); } scrview.setdrawingcacheenabled (false); Scrview.destroydrawingcache (); returnscrbmp; }
This situation can only intercept the general application, when the application contains Surfaceview, the Surfaceview area is black, for specific reasons, please go: http://blog.csdn.net/luoshengyang/article/details/8661317.
Second, the realization of containing surfaceview
2.1 Implementation code in case of system root
Private StaticFinal String device_name ="/dev/graphics/fb0"; @SuppressWarnings ("Deprecation") Public StaticBitmap Acquirescreenshot (context context) {WindowManager Mwinmanager=(WindowManager) context. Getsystemservice (Context.window_service); Displaymetrics Metrics=NewDisplaymetrics (); Display Display=Mwinmanager.getdefaultdisplay (); Display.getmetrics (metrics); //Screen Height intHeight =Metrics.heightpixels; //the width of the screen intwidth =Metrics.widthpixels; intPixelFormat =Display.getpixelformat (); PixelFormat LOCALPIXELFORMAT1=NewPixelFormat (); Pixelformat.getpixelformatinfo (PixelFormat, LOCALPIXELFORMAT1); //bit Depth intDeepth =Localpixelformat1.bytesperpixel; byte[] Arrayofbyte =New byte[Height * Width *Deepth]; Try { //read device cache, get screen image streamInputStream Localinputstream =Readasroot (); DataInputStream Localdatainputstream=NewDataInputStream (Localinputstream); Localdatainputstream.readfully (Arrayofbyte); Localinputstream.close (); int[] Tmpcolor =New int[Width *height]; intR, G, B; for(intj =0; J < Width * Height * deepth; J + =deepth) {b= Arrayofbyte[j] &0xFF; G= Arrayofbyte[j +1] &0xFF; R= Arrayofbyte[j +2] &0xFF; Tmpcolor[j/deepth] = (R << -) | (g <<8) | B | (0xff000000); } //Build BitmapBitmap Scrbitmap =Bitmap.createbitmap (tmpcolor, width, height, Bitmap.Config.ARGB_8888); returnScrbitmap; } Catch(Exception e) {log.d (TAG,"# # # Read screen failed"); E.printstacktrace (); } return NULL; } /** * @Title: Readasroot * @Description: Read screen with root access * @throws Exception * @throws*/ Public StaticInputStream Readasroot () throws Exception {File Devicefile=NewFile (device_name); Process localprocess= Runtime.getruntime (). EXEC ("su"); String Str="Cat"+ Devicefile.getabsolutepath () +"\ n"; Localprocess.getoutputstream (). Write (Str.getbytes ()); returnLocalprocess.getinputstream (); }
In the system root, you can read the frame buffer directly, so you can read the entire window image even if it contains Surfaceview.
2.2 Use Surfaceview and MediaPlayer to play the video, only get the surfaceview image here
/** * @Title: Getvideoframe * @Description: Gets the image of a frame of the video, but the resulting image is not necessarily an image of the specified position. * The local path of the @param path video * @param position video stream playback position * @return Bitmap returned video image * @throws*/@SuppressLint ("Newapi") Public StaticBitmap getvideoframe (String path, MediaPlayer MediaPlayer) {Bitmap bmp=NULL; //This method can be used for Android 9 and laterMediametadataretriever Retriever =NewMediametadataretriever (); Try{retriever.setdatasource (path); //This is a necessary sentence.String timestring =Retriever.extractmetadata (mediametadataretriever.metadata_key_duration); //get the total length, this sentence is also necessary LongTitaltime = Long.parselong (timestring) * +; LongVideoposition =0; Try{mediaplayer.setdatasource (path); if(Path.startswith ("http") ) {Mediaplayer.prepareasync (); } Else{mediaplayer.prepare (); } intDuration =mediaplayer.getduration (); //This calculates the time at which the screen is to be intercepted.Videoposition = Titaltime * Position/duration; } Catch(IOException e) {e.printstacktrace (); } if(Videoposition >0) {BMP=retriever.getframeattime (videoposition, mediametadataretriever.option_closest); } } Catch(IllegalArgumentException ex) {ex.printstacktrace (); } Catch(RuntimeException ex) {ex.printstacktrace (); } finally { Try{retriever.release (); } Catch(RuntimeException ex) {}}returnbmp; }
The above code simply gets the image on the Surfaceview, and the other control's image is not acquired. The principle is to read a position image of a local file instead of a.
2.3 No root, Surfaceview, still want?
This method I did not succeed, do not know whether really can achieve, here to give relevant information, hope that the need for friends can get help, if can be achieved, also please leave a message to teach, not very grateful.
The using Native Window API in the using Graphic API of the 12th of the Pro Android C + + with NDK.
End:
After many explorations, consulted the domestic "deep Android System" series author Dengfanping, he gave the answer:
I know what you're talking about. I have also done screenshots of the software, but the video image can not be truncated. According to my previous research, video data decoding directly from the decoding chip pushed to the screen, will not be through the Surfaceflinger to mix screen, on the high-pass chip is so. Think of it, and that's why the screenshots of Windows and Linux can't capture video-playing images. However, some chip platforms may be video data through the Surfaceflinger to mix screen, I personally think this situation is relatively small. BR Dengfanping
In short, this road seems to be difficult to walk through, I hope there are needs of friends less detours it.
Android app and Surfaceview issues summary