Research on application development of Android Screen recorder

Source: Internet
Author: User

1 Screen-cutting interface
If you want the screen before Android5.0, you need to get the system root permission. But after Android5.0 Android opened the new interface android.media.projection, developers use this interface, third-party applications no longer need to obtain the system root privileges can also be directly screen operation. Querying its official API indicates that the interface is primarily used for "screen" operations and "audio recording" operations, where only the functions used for the screen are discussed. Because of the use of media mapping technology means, so the interception of the screen is not a real device screen, but the interception through the mapping out of the "virtual screen." However, because we want to get is definitely a picture, and the "map" out of the picture and the system screen exactly the same, so for normal screenshot operation, this method is completely feasible.
Here's how to use the interface:
(1) First call Context.getsystemservice () with the parameter media_projection_service to get the Mediaprojectionmanager class instance.

Mmediaprojectionmanager= (Mediaprojectionmanager) Getsystemservice (Context.media_projection_service);

(2) Second, call Createscreencaptureintent () to get a intent; again, use Startactivityforresult () to start the screen capture, in the Onactivityresult () Get ResultCode and Resultdata in order to facilitate the use of getmediaprojection () below.

Startactivityforresult (Mmediaprojectionmanager.createscreencaptureintent (), request_media_projection);

(3) Return the result to getmediaprojection () to get the capture data.

Mmediaprojection = mmediaprojectionmanager.getmediaprojection (resultcode, data);

(4) Use the Mmediarecorder instance to get the screen surface through the Getsurface () method, and use the Mediaprojection temporary instance in the previous step to display the virtual screen through the Createvirtualdisplay () method.

 return                          Mmediaprojection.createvirtualdisplay ( "mainactivity" , Mscreenwidth,                        Mscreenheight, Mscreendensity, Displaymanager.virtual_display_flag_auto_mirror, Mmediarecorder.getsurface (),  null  /* callbacks  */, null  /*   Handler  */); 

2 Suspension window
First of all, a small suspended window display on the right side of the screen, click on a small suspension window, will pop up a large suspended window, with the relevant buttons to operate.
First of all, the basic principle of implementation, the effect of this desktop suspension window is similar to the widget, but it is more flexible than the widget. Mainly by windowmanager this class to implement, call this class AddView method for adding a floating window, updateviewlayout method to update the parameters of the window, Removeview to remove the suspended window.
Windowmanager.layoutparams This class is used to provide the parameters required for suspending windows, including several variables that are often used:
1) The type value is used to determine the kind of suspended window, which is generally set to Type_phone (2002), which is represented above all applications but below the status bar.
2) The Flags value is used to determine the behavior of the suspended window, such as non-focused, modal dialogs, and so on, with many properties.
3) The gravity value is used to determine the alignment of the suspended window, which is generally set to the upper-left corner, so that the coordinates can be conveniently calculated when the hover window is dragged.
4) The X value is used to determine the position of the suspended window, and if you want to move the suspended window horizontally, you need to change this value.
5) The Y value is used to determine the position of the suspended window, and if you want to move the suspended window vertically, you need to change this value.
6) The Width value specifies how wide the window is to be suspended.
7) The height value is used to specify the altitude of the suspended window.
Create a suspended window This form needs to be available to the user for permission, so you also need to add <uses-permission android:name= to the Androidmanifest.xml android.permission.SYSTEM_ Alert_window "/> This can add permissions directly to Manifest.xml before api23, but after android6.0, users are required to turn on permissions in the System app Rights Management.
How to create a floating window:
(1) First create a new layout file named Float_window_small.xml for the layout of the small hover window, and create a new layout file named Float_window_big.xml for the layout of the large suspended window.
(2) Create a new class named Floatwindowservice, which inherits from the service.


(3) as shown in the Onstartcommand method of Floatwindowservice, a timer timer is turned on, and every 500 milliseconds (0.5 seconds) is executed once Refreshtask (). Refreshtask inherit TimerTask, in the refreshtask, to judge, if the cell phone is currently on the desktop, it should show the suspended window, if the phone returned to open the application of the floating window, it should remove the suspended window. When the Floatwindowservice is destroyed, the timer should be stopped, otherwise it will continue to run.
Creating and removing suspended Windows is managed by the Mywindowmanager class, which is much better managed than writing the code directly into activity or service, using a specialized tool class. However, if you want to create a suspended window, you must first write the view of the suspended window. Create a new class named Floatwindowsmallview, inherited from LinearLayout. Create a new class named Floatwindowbigview, also inherit from LinearLayout.
(4) in Floatwindowsmallview, by Ontouchevent (Motionevent event) to determine the operation of the finger on the screen:
1) Action_down: Records the necessary data when the finger is pressed, and the ordinate values need to be subtracted from the status bar height.
2) Action_move: When the finger moves, use the Updateviewposition () method to update the position of the small hover window.
3) Action_up: If the finger leaves the screen, xdowninscreen and Xinscreen are equal, and ydowninscreen and Yinscreen are equal, the click event is triggered and the large float window is opened via Openbigwindow ().
(5) in Floatwindowbigview, set 2 buttons Startrecord and Stoprecord to monitor the Startrecord settings:
1.startrecord: Remove the large suspension window, create a small suspension window, open the Screenrecordservice.
2.stoprecord: Remove the large suspension window, create a small suspension window, close the Screenrecordservice.
3. Use case Motionevent.action_down of Ontouchevent (Motionevent event) to remove the large suspension window and create a small suspension window.
3 video Recording
Complete the video recording in Screenrecordservice with a screenshot, screenrecordservice inherit the service. To increase support for recorded audio and video, the Android system provides a Mediarecorder class. The use of this class is also very simple, let's take a look at this class.


Very similar to the MediaPlayer class Mediarecorder has its own state diagram. Here is an introduction to the various states of Mediarecorder:
1) Initial: Initial state, when a Mediarecorder object is created using the new () method, or the Reset () method is called, the Mediarecorder object is in the Initial state. After the video source or audio source is set, it is converted to the initialized state. In addition, any State other than the released state can get Mediarecorder into that state by calling the Reset () method.
2) Initialized: Initialized state, you can enter the state by calling the Setaudiosource () or Setvideosource () method in the initial state. In this state, the output format can be set by the Setoutputformat () method, at which point the Mediarecorder is converted to the datasourceconfigured state. In addition, the reset () method is used to enter the initial state.
3) datasourceconfigured: Data source configuration status, which can be set encoding mode, output file, screen rotation, preview display and so on. This state can be entered in the initialized state through the Setoutputformat () method. In addition, the reset () method can be used to return to the initial state or to the prepared state via the Prepare () method.
4) Prepared: Ready state, in datasourceconfigured state through the prepare () method into the state. In this state you can enter the recording state via Start (). In addition, the reset () method can be used to return to the initialized state.
5) Recording: Recording status, you can enter the state by calling the start () method in the prepared state. In addition, it can be returned to the initial state via the Stop () method or the Reset () method.
6) Released: Release status (the word given in the official document is called the Idle state), you can enter this state by calling the release () method in the initial state, which frees all resources that are bound to the Mediarecorder object.
7) Error: Wrong state, when the error occurs, enter this state, it can go through the Reset () method to enter the initial state.
The following is a description of the application steps for video admission:
1) First get the pixel, get metrics through getdisplaymetrics (), get the resolution of the phone screen.

        New displaymetrics ();         = Getresources (). Getdisplaymetrics (); // get displaymetrics        in service mscreendensity = metrics.densitydpi;         = metrics.widthpixels;         = Metrics.heightpixels;

2) since we need to store the recorded video in the phone's memory, set the storage path to the folder of the phone's public store video, and get the path as follows:

Environment.getexternalstoragepublicdirectory (environment.directory_movies).

3) Obtain an instance of Mediarecorder, initialize Mediarecorder:
To set the video source for recording Setvideosource (MediaRecorder.VideoSource.SURFACE);
Set sound Source: Setaudiosource (MediaRecorder.AudioSource.MIC);
Format the recorded audio and video file: Setoutputformat (MediaRecorder.OutputFormat.MPEG_4);
Set the encoding format for the recorded video: Setvideoencoder (MediaRecorder.VideoEncoder.H264);
Set the encoded format of the recorded sound: Setaudioencoder (MediaRecorder.AudioEncoder.AAC);
Set the encoded bit rate for the recorded sound: setvideoencodingbitrate (512 * 1000);
Set capture frame rate for recorded video: Setvideoframerate (40);
Set the width to shoot and the height of the video: Setvideosize (Mscreenwidth, mscreenheight);
Set the storage path for recorded video: Setoutputfile (Mvecordfile.getabsolutepath ());
4) Call Mediarecorder's Prepare () method to complete the preparation for recording the video.
5) in Screenrecordservice Onstartcommand (Intent Intent, int flags, int startid), call the Startrecord () method.
(1) Get ResultCode, data, and Mediaprojectionmanager instances from the Shotapplication shared class.
(2) through the concatenation of the following mmediarecorder.getsurface (), we put the output of mmediaprojection into surface, and surface is the input source of Mediarecorder, This completes the Mmediaprojection output content encoding, that is, the screen capture data encoding mvirtualdisplay.

return mmediaprojection.createvirtualdisplay ("mainactivity", Mscreenwidth,                        mscreenheight, Mscreendensity,                        displaymanager.virtual_display_flag_auto_mirror,                        null/*   */null/**/);

(3) Call the Start () method of Mediarecorder to start recording.
6) in the OnDestroy () method of the Screenrecordservice:
(1) Call the Stop () method of the Mediarecorder and reset () method to complete the recording

Mmediarecorder.stop (); Mmediarecorder.reset ();

(2) Release the Mvirtualdisplay.

       ifnull) {            return;        }        Mvirtualdisplay.release ();

(3) Stop the screenshot and empty it.

        if NULL ) {            mmediaprojection.stop ();             NULL ;        }

(4) Send the broadcast, notify the System Media Library update.

Sendbroadcast (new  Intent (Intent.action_media_scanner_scan_file,uri.parse ("file://" + Sampledir.getabsolutepath (). toString ()));

4 Permission Acquisition
Prior to Android 6.0, the app's permissions were available at Androidmanifest.xml static request, but after Android 6.0, the new access method requires a static request in the Androidmanifest file as in the previous version. The app also needs to request permissions as needed, using a dialog box that displays a request permission to the user. These dynamically requested permissions can be manually closed in the system settings. In addition, for the category normal permissions, still only need to be static in the Androidmanifest file, system installation will be directly obtained.
In the system authorization pop-up window link, the Reminder box will have a no longer prompt check box, if the user click not too prompt, and refused to authorize, then the next time the authorization, the System authorization popup box will not be prompted, so we need to customize the permission pop-up popup box, then the flowchart becomes as follows.

The permissions that the recorder application needs to dynamically obtain are as follows:
(1) <uses-permission android:name= "Android.permission.SYSTEM_ALERT_WINDOW"/>
(2) <uses-permission android:name= "Android.permission.WRITE_EXTERNAL_STORAGE"/>
(3) <uses-permission android:name= "Android.permission.RECORD_AUDIO"/>
These are the permissions to open the hover window, write SDcard storage, and turn on the microphone. The above three types of permissions are divided into 2 categories:
<1> System permissions:
Where write SDcard storage and the right to turn on the microphone, for the system permissions of the dangerous type, need to apply dynamically. To process permission requests:
1) Use Method Checkselfpermission () to determine whether there is permission.
2) If there is no permission, Pop dialog to the user select: Requestpermission (), the second parameter code corresponds to code in the Onrequestpermissionresult () method.
3) Determine if the user has confirmed the permission Onrequestpermissionresult ().
4) Show the User a dialog in front of the dialog box that is selected to guide the user to make a selection.
Since this application requires 2 permissions, it cannot be applied in accordance with the above method of applying individual permissions. Processing multiple permission requests at once:
1) in the Requestpermissions () method, define a list permissionsneeded, by means of method Addpermission () to add the required permission to the list.
2) Use the For loop to pop up the request dialog box for the user to choose whether the permission is promised.
3) If all permissions are authorized, still callback Onrequestpermissionsresult, check whether the permission of the request is authorized.
4) in mainactivity oncreate use if (Build.VERSION.SDK_INT >= 23) to determine the program authorization, that is, run the Requestpermissions () method.
<2> Special Permission Authorization
Enabling the Suspend window permission is a special permission authorization, in addition to this there is a special permission authorization (Android.permission.WRITE_SETTINGS), for these two special permissions, processing as follows:
If it is for "Android.permission.SYSTEM_ALERT_WINDOW" and
"Android.permission.WRITE_SETTINGS" These two permissions, If it is run on the version 6.0 is the need to go to the new permissions model, if it is running on the old version, you need to make a judgment, at this time encountered a problem is, in Google's official recommendation, in determining whether the app running system on Android m, Its judgment is as follows: Build.VERSION.CODENAME.equals ("MNC"); actually found this sentence is invalid, instead of Build.VERSION.SDK_INT >= 23, need another special treatment.
For System_alert_window permissions, you need to send a action_manage_overlay_permission to the system. Such an action, at the same time, can be judged by the Settings.candrawoverlays () method before it has been authorized.

           // Check that the special permission to open the Float window is authorized            if (! settings.candrawoverlays (Getapplicationcontext ())) {                requestalertwindowpermission ();            }

For write_settings permissions, you need to send a action_manage_write_settings such an action to the system, and you can use Settings.System.canWrite (). Method has been authorized before it is judged.
Study on the process of 5 recording screen application
The realization of the recording screen application is basically this:
1, abandon the application of the interface button to turn off the recording screen, the use of small floating icon and click the large icon appears to realize the recording screen keys. The floating icon is implemented by Floatwindowservice, which inherits from the service class, which makes it easy to create a layout with only the floating icon, and use the StartService (Intent Intent) method to open the service in places such as activity.
2, we want users to be able to drag the small icon at any time in the interface, small icon position variable, when clicking on small icons, large icons appear and, click on the button, as well as the periphery of the icon, large icons to remove, rebuild small icons.
3, the image is saved as MP4 format, the path for the mobile phone sdcard movies file directory, the self-built folder Recordvideo.
4, the priority of the floating ball for the general application of the top layer, that is, in addition to the status bar drop-down list, the ball is always visible, this is due to the nature of the service class. While watching TV and other circumstances will be less suitable, but the design allows users to readily and easily accept the desired screen image.
A screenshot request result data sharing class Shotapplication
As mentioned above, screen capture requires user consent, the initial run will have a request dialog, consent before continuing, or the program will be terminated. Since the user is required to select the information, that in the issue of the screenshot request can not be used in a simple startactivity (Intent Intent) method, but to use the Startactivityforresult (Intent Intent, Intresquestcode) method. However, the Startactivityforresult (Intent Intent, int resquestcode) method in the service class is not available, rather there is no onactivityresult that can be overloaded with subclasses (int Resquestcode, int resultcode, Intent data) method. But the reality is that the Screenrecordservice class will use the back two return values (ResultCode and data) to construct the object of the Mediaprojection class in the process of realizing the recording screen.
If it is possible to record the screen directly in the activity, there is no problem. But the problem is that we need to be able to do it quickly and easily at any time we want to intercept the screen, which requires a small ball that is implemented and floated on top of the general application window using Floatwindowservice. And in the activity to achieve the words can not achieve this effect, often can only be obtained by the application itself interface, or hide it after the next layer of the interface, in short do not want to get the effect.
Therefore, the first problem is that the object of class Screenrecordservice can get both data. Also note that bundles can perform general data loading and assign to intent class objects, which are then sent to the target class together, but the parameter data itself is the intent type. Here we take the idea of data sharing, taking advantage of the subclass Shotapplication inherited from the application class, and then defining the member variables that need to be shared (some are objects of other classes).
Where the Mediaprojectionmanager class object is used when sending a screenshot request and building a Mediaprojection class object, the setting and acquisition of member values is straightforward and does not explain. Then the data transfer is clear: first from the main program class mainactivity into the shared class shotapplication, and then the service class Screenrecordservice from the shared class shotapplication extracted.
Two, the main program class mainactivity to do 5 things
1) First judge the Android platform, if it is api>=23, first make a dynamic request for permission.
2) make a screenshot request to the user. This is the 1th thing the class mainactivity do. Of course, you need to get the class Mediaprojectionmanager instance before this.
Since the OnCreate () method is automatically called after the app is turned on, Startintent is called when the Start button is clicked, so the screenshot request code is executed automatically the first time it is run. If this is the first time after the app is installed, the Screenshot Permission dialog box will pop up, requiring user authorization.
3) The 2nd thing the class mainactivity does is write the value returned by the user operation and the class Mediaprojectionmanager instance of the initial fetch into the data sharing class shotapplication.
4) class mainactivity do the 3rd thing is definitely to open the floating window service.
5) The 4th thing the class Mainactivity does is to destroy itself (finish ()), and then the control is handed over to the floating small form of the service class.
Third, service class Floatwindowservice complete the creation, removal and control of the size of the suspended window
Starting with the Onstartcommand (Intent Intent, int flags, int startid) method, turn on the timer and call Refreshtask () every 0.5 seconds.
1) If the current interface is the desktop and there is no hover window display, create a hover window and call Createsmallwindow ().
2) The current interface is to return to the application of the interface, and has a floating window display, then remove the suspended window, call Removesmallwindow () and Removebigwindow ().
3) Listen for the icon's Click event in class Floatwindowsmallview, call Createbigwindow ().
4) Listen for the button's click event in class Floatwindowbigview:
1. Click Start Recording, remove the large suspension window, create a small suspension window, and start Screenrecordservice.
2. When you click Finish recording, remove the large suspension window, create a small floating window, and stop the Screenrecordservice.
Iv. Service class Screenrecordservice complete recording screen work
(1) The Createrecorddir (), Initrecorder (), and Preparerecorder () methods are called in OnCreate ().
1) Createrecorddir () to create a saved path for recording video;
2) Initrecorder () is responsible for the initialization of Mediarecorder;
3) Preparerecorder () is responsible for invoking the prepare () method of the Mediarecorder instance.
(2) calling Startrecord () in Onstartcommand is responsible for turning on the screenshot, creating a surface, and recording the video.
(3) Stop recording the video in the Screenrecordservice OnDestroy () and stop the screenshot.
(4) Send the broadcast, notify the System Media Library update.
6 Summary
(1) The screenshot function is a new interface (or an open one) that starts at Android5.0, so this method can only be used for more than 5.0 Android versions (API21 or more).
(2) The floating window is realized by WindowManager this class, and the AddView method of calling this class can add a floating window.
(3) When applying mediarecorder, it should be noted that, similar to the MediaPlayer use of Mediarecorder recording, it is necessary to strictly observe the sequence of function calls in the state diagram description, call different functions in different states, or else an exception will occur.
(4) After Android 6.0, the new access to permissions in addition to the same as in the previous version of the Androidmanifest file in the static request, the application needs to be requested according to the required permissions, in a way to show the User a Request Permission dialog box, in order to get the appropriate permissions.
(5) The Startactivityforresult (Intent Intent, int resquestcode) method is not available in the service class, specifically, there is no onactivityresult for subclasses overloading (int Resquestcode, int resultcode, Intent data) method, we can take the idea of sharing class to get resultcode and data.

Research on application development of Android Screen recorder

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.