Android开发实现录屏小功能
程序员文章站
2022-08-10 19:14:45
最近开发中,要实现录屏功能,查阅相关资料,发现调用 mediaprojectionmanager的api 实现录屏功能即可:import android.manifest;import android...
最近开发中,要实现录屏功能,查阅相关资料,发现调用 mediaprojectionmanager的api 实现录屏功能即可:
import android.manifest; import android.app.activity; import android.content.context; import android.content.intent; import android.content.pm.packagemanager; import android.media.projection.mediaprojectionmanager; import android.os.build; import android.os.bundle; import android.util.displaymetrics; import android.util.log; public class recordscreenactivity extends activity { private boolean isrecord = false; private int mscreenwidth; private int mscreenheight; private int mscreendensity; private int request_code_permission_storage = 100; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); requestpermission(); getscreenbaseinfo(); startscreenrecord(); } @override protected void onactivityresult(int requestcode, int resultcode, intent data) { super.onactivityresult(requestcode, resultcode, data); if (requestcode == 1000) { if (resultcode == result_ok) { //获得录屏权限,启动service进行录制 intent intent = new intent(this, screenrecordservice.class); intent.putextra("resultcode", resultcode); intent.putextra("resultdata", data); intent.putextra("mscreenwidth", mscreenwidth); intent.putextra("mscreenheight", mscreenheight); intent.putextra("mscreendensity", mscreendensity); startservice(intent); finish(); } } } //start screen record private void startscreenrecord() { //manages the retrieval of certain types of mediaprojection tokens. mediaprojectionmanager mediaprojectionmanager = (mediaprojectionmanager) getsystemservice(context.media_projection_service); //returns an intent that must passed to startactivityforresult() in order to start screen capture. intent permissionintent = mediaprojectionmanager.createscreencaptureintent(); startactivityforresult(permissionintent, 1000); } /** * 获取屏幕基本信息 */ private void getscreenbaseinfo() { //a structure describing general information about a display, such as its size, density, and font scaling. displaymetrics metrics = new displaymetrics(); getwindowmanager().getdefaultdisplay().getmetrics(metrics); mscreenwidth = metrics.widthpixels; mscreenheight = metrics.heightpixels; mscreendensity = metrics.densitydpi; } @override protected void ondestroy() { super.ondestroy(); } private void requestpermission() { if (build.version.sdk_int >= 23) { string[] permissions = { manifest.permission.read_external_storage, manifest.permission.write_external_storage, manifest.permission.record_audio, manifest.permission.camera }; for (string str : permissions) { if (this.checkselfpermission(str) != packagemanager.permission_granted) { this.requestpermissions(permissions, request_code_permission_storage); return; } } } } @override public void onrequestpermissionsresult(int requestcode, string[] permissions,int[] grantresults) { super.onrequestpermissionsresult(requestcode, permissions, grantresults); if(requestcode==request_code_permission_storage){ startscreenrecord(); } } }
service 里面进行相关录制工作
import android.app.service; import android.content.context; import android.content.intent; import android.hardware.display.displaymanager; import android.hardware.display.virtualdisplay; import android.media.mediarecorder; import android.media.projection.mediaprojection; import android.media.projection.mediaprojectionmanager; import android.os.environment; import android.os.ibinder; import android.support.annotation.nullable; import android.util.log; import java.text.simpledateformat; import java.util.date; /** * created by dzjin on 2018/1/9. */ public class screenrecordservice extends service { private int resultcode; private intent resultdata=null; private mediaprojection mediaprojection=null; private mediarecorder mediarecorder=null; private virtualdisplay virtualdisplay=null; private int mscreenwidth; private int mscreenheight; private int mscreendensity; private context context=null; @override public void oncreate() { super.oncreate(); } /** * called by the system every time a client explicitly starts the service by calling startservice(intent), * providing the arguments it supplied and a unique integer token representing the start request. * do not call this method directly. * @param intent * @param flags * @param startid * @return */ @override public int onstartcommand(intent intent, int flags, int startid) { try{ resultcode=intent.getintextra("resultcode",-1); resultdata=intent.getparcelableextra("resultdata"); mscreenwidth=intent.getintextra("mscreenwidth",0); mscreenheight=intent.getintextra("mscreenheight",0); mscreendensity=intent.getintextra("mscreendensity",0); mediaprojection=createmediaprojection(); mediarecorder=createmediarecorder(); virtualdisplay=createvirtualdisplay(); mediarecorder.start(); }catch (exception e) { e.printstacktrace(); } /** * start_not_sticky: * constant to return from onstartcommand(intent, int, int): if this service's process is * killed while it is started (after returning from onstartcommand(intent, int, int)), * and there are no new start intents to deliver to it, then take the service out of the * started state and don't recreate until a future explicit call to context.startservice(intent). * the service will not receive a onstartcommand(intent, int, int) call with a null intent * because it will not be re-started if there are no pending intents to deliver. */ return service.start_not_sticky; } //createmediaprojection public mediaprojection createmediaprojection(){ /** * use with getsystemservice(class) to retrieve a mediaprojectionmanager instance for * managing media projection sessions. */ return ((mediaprojectionmanager)getsystemservice(context.media_projection_service)) .getmediaprojection(resultcode,resultdata); /** * retrieve the mediaprojection obtained from a succesful screen capture request. * will be null if the result from the startactivityforresult() is anything other than result_ok. */ } private mediarecorder createmediarecorder(){ simpledateformat simpledateformat=new simpledateformat("yyyy-mm-dd-hh-mm-ss"); string filepathname= environment.getexternalstoragedirectory()+"/"+simpledateformat.format(new date())+".mp4"; //used to record audio and video. the recording control is based on a simple state machine. mediarecorder mediarecorder=new mediarecorder(); //set the video source to be used for recording. mediarecorder.setvideosource(mediarecorder.videosource.surface); //set the format of the output produced during recording. //3gpp media file format mediarecorder.setoutputformat(mediarecorder.outputformat.three_gpp); //sets the video encoding bit rate for recording. //param:the video encoding bit rate in bits per second. mediarecorder.setvideoencodingbitrate(5*mscreenwidth*mscreenheight); //sets the video encoder to be used for recording. mediarecorder.setvideoencoder(mediarecorder.videoencoder.h264); //sets the width and height of the video to be captured. mediarecorder.setvideosize(mscreenwidth,mscreenheight); //sets the frame rate of the video to be captured. mediarecorder.setvideoframerate(60); try{ //pass in the file object to be written. mediarecorder.setoutputfile(filepathname); //prepares the recorder to begin capturing and encoding data. mediarecorder.prepare(); }catch (exception e){ e.printstacktrace(); } return mediarecorder; } private virtualdisplay createvirtualdisplay(){ /** * name string: the name of the virtual display, must be non-empty.this value must never be null. width int: the width of the virtual display in pixels. must be greater than 0. height int: the height of the virtual display in pixels. must be greater than 0. dpi int: the density of the virtual display in dpi. must be greater than 0. flags int: a combination of virtual display flags. see displaymanager for the full list of flags. surface surface: the surface to which the content of the virtual display should be rendered, or null if there is none initially. callback virtualdisplay.callback: callback to call when the virtual display's state changes, or null if none. handler handler: the handler on which the callback should be invoked, or null if the callback should be invoked on the calling thread's main looper. */ /** * displaymanager.virtual_display_flag_auto_mirror * virtual display flag: allows content to be mirrored on private displays when no content is being shown. */ return mediaprojection.createvirtualdisplay("mediaprojection",mscreenwidth,mscreenheight,mscreendensity, displaymanager.virtual_display_flag_auto_mirror,mediarecorder.getsurface(),null,null); } @override public void ondestroy() { super.ondestroy(); if(virtualdisplay!=null){ virtualdisplay.release(); virtualdisplay=null; } if(mediarecorder!=null){ mediarecorder.stop(); mediarecorder=null; } if(mediaprojection!=null){ mediaprojection.stop(); mediaprojection=null; } } @nullable @override public ibinder onbind(intent intent) { return null; } }
录屏功能就这么实现了,有什么不妥之处,敬请留言讨论。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 记录集内随机取记录的代码