这篇文章主要讲解了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;
}
}
录屏功能就这么实现了,有什么不妥之处,敬请留言讨论。
看完上述内容,是不是对Android开发如何实现录屏小功能有进一步的了解,如果还想学习更多内容,欢迎关注亿速云行业资讯频道。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。