时间:2020-10-12 09:32:44 | 栏目:Android代码 | 点击:次
本文实例为大家分享了android实现录屏功能的具体代码,供大家参考,具体内容如下
1、mian.activity
package com.fpt.screenvideo; import android.content.Context; import android.content.Intent; import android.graphics.Color; import android.media.projection.MediaProjectionManager; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.DisplayMetrics; import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.RadioGroup; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private Button mTextView,off_btn; private static final String RECORD_STATUS = "record_status"; private static final int REQUEST_CODE = 1000; private int mScreenWidth; private int mScreenHeight; private int mScreenDensity; /** 是否已经开启视频录制 */ private boolean isStarted = false; /** 是否为标清视频 */ private boolean isVideoSd = true; /** 是否开启音频录制 */ private boolean isAudio = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.i(TAG, "onCreate"); if(savedInstanceState != null) { isStarted = savedInstanceState.getBoolean(RECORD_STATUS); } getView() ; getScreenBaseInfo(); } private void getView() { mTextView = findViewById(R.id.button_control); off_btn=findViewById(R.id.button_contro2); off_btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //// Intent service = new Intent(this, ScreenRecordService.class); // stopService(service); // isStarted = !isStarted; } }); if(isStarted) { statusIsStarted(); } else { statusIsStoped(); } mTextView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub if(isStarted) { stopScreenRecording();//功能 statusIsStoped();//仅仅是状态 Log.i(TAG, "Stoped screen recording"); } else { startScreenRecording();//功能 } } }); RadioGroup radioGroup = (RadioGroup) findViewById(R.id.redio_group); radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { // TODO Auto-generated method stub switch (checkedId) { case R.id.sd_button: isVideoSd = true; break; case R.id.hd_button: isVideoSd = false; break; default: break; } } }); CheckBox audioBox = (CheckBox) findViewById(R.id.audio_check_box); audioBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { // TODO Auto-generated method stub isAudio = isChecked; } }); } /** * 开启屏幕录制时的UI状态 */ private void statusIsStarted() { mTextView.setText("停止录制"); mTextView.setBackgroundColor(Color.GREEN); } /** * 结束屏幕录制后的UI状态 */ private void statusIsStoped() { mTextView.setText("开始录制"); mTextView.setBackgroundColor(Color.RED); } /** * 获取屏幕相关数据 */ private void getScreenBaseInfo() { DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); mScreenWidth = metrics.widthPixels; mScreenHeight = metrics.heightPixels; mScreenDensity = metrics.densityDpi; } @Override protected void onSaveInstanceState(Bundle outState) { // TODO Auto-generated method stub super.onSaveInstanceState(outState); outState.putBoolean(RECORD_STATUS, isStarted); } /** * 获取屏幕录制的权限 */ private void startScreenRecording() { // TODO Auto-generated method stub MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE); Intent permissionIntent = mediaProjectionManager.createScreenCaptureIntent(); startActivityForResult(permissionIntent, REQUEST_CODE); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // TODO Auto-generated method stub super.onActivityResult(requestCode, resultCode, data); if(requestCode == REQUEST_CODE) { if(resultCode == RESULT_OK) { // 获得权限,启动Service开始录制 Intent service = new Intent(this, ScreenRecordService.class); service.putExtra("code", resultCode); service.putExtra("data", data); service.putExtra("audio", isAudio); service.putExtra("width", mScreenWidth); service.putExtra("height", mScreenHeight); service.putExtra("density", mScreenDensity); service.putExtra("quality", isVideoSd); startService(service); // 已经开始屏幕录制,修改UI状态 isStarted = !isStarted; statusIsStarted(); // simulateHome(); // this.finish(); // 可以直接关闭Activity Log.i(TAG, "Started screen recording"); } else { Toast.makeText(this, "跳出提示框", Toast.LENGTH_LONG).show(); Log.i(TAG, "User cancelled"); } } } /** * 关闭屏幕录制,即停止录制Service */ private void stopScreenRecording() { // TODO Auto-generated method stub Intent service = new Intent(this, ScreenRecordService.class); stopService(service); isStarted = !isStarted; } /** * 模拟HOME键返回桌面的功能 */ private void simulateHome() { Intent intent = new Intent(Intent.ACTION_MAIN); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addCategory(Intent.CATEGORY_HOME); this.startActivity(intent); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { // 在这里将BACK键模拟了HOME键的返回桌面功能(并无必要) if(keyCode == KeyEvent.KEYCODE_BACK) { simulateHome(); return true; } return super.onKeyDown(keyCode, event); } }
2、ScreenRecordService
package com.fpt.screenvideo; 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.util.Log; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; public class ScreenRecordService extends Service { private static final String TAG = "ScreenRecordingService"; private int mScreenWidth; private int mScreenHeight; private int mScreenDensity; private int mResultCode; private Intent mResultData; /** 是否为标清视频 */ private boolean isVideoSd; /** 是否开启音频录制 */ private boolean isAudio; private MediaProjection mMediaProjection; private MediaRecorder mMediaRecorder; private VirtualDisplay mVirtualDisplay; @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); Log.i(TAG, "Service onCreate() is called"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { // TODO Auto-generated method stub Log.i(TAG, "Service onStartCommand() is called"); mResultCode = intent.getIntExtra("code", -1); mResultData = intent.getParcelableExtra("data"); mScreenWidth = intent.getIntExtra("width", 720); mScreenHeight = intent.getIntExtra("height", 1280); mScreenDensity = intent.getIntExtra("density", 1); isVideoSd = intent.getBooleanExtra("quality", true); isAudio = intent.getBooleanExtra("audio", true); mMediaProjection = createMediaProjection(); mMediaRecorder = createMediaRecorder(); mVirtualDisplay = createVirtualDisplay(); // 必须在mediaRecorder.prepare() 之后调用,否则报错"fail to get surface" mMediaRecorder.start(); return Service.START_NOT_STICKY; } private MediaProjection createMediaProjection() { Log.i(TAG, "Create MediaProjection"); return ((MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE)).getMediaProjection(mResultCode, mResultData); } private MediaRecorder createMediaRecorder() { SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); Date curDate = new Date(System.currentTimeMillis()); String curTime = formatter.format(curDate).replace(" ", ""); String videoQuality = "HD"; if(isVideoSd) videoQuality = "SD"; Log.i(TAG, "Create MediaRecorder"); MediaRecorder mediaRecorder = new MediaRecorder(); // if(isAudio) mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE); mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); mediaRecorder.setOutputFile(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES) + "/" + videoQuality + curTime + ".mp4"); mediaRecorder.setVideoSize(mScreenWidth, mScreenHeight); //after setVideoSource(), setOutFormat() mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); //after setOutputFormat() // if(isAudio) mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); //after setOutputFormat() int bitRate; if(isVideoSd) { mediaRecorder.setVideoEncodingBitRate(mScreenWidth * mScreenHeight); mediaRecorder.setVideoFrameRate(30); bitRate = mScreenWidth * mScreenHeight / 1000; } else { mediaRecorder.setVideoEncodingBitRate(5 * mScreenWidth * mScreenHeight); mediaRecorder.setVideoFrameRate(60); //after setVideoSource(), setOutFormat() bitRate = 5 * mScreenWidth * mScreenHeight / 1000; } try { mediaRecorder.prepare(); } catch (IllegalStateException | IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } Log.i(TAG, "Audio: " + isAudio + ", SD video: " + isVideoSd + ", BitRate: " + bitRate + "kbps"); return mediaRecorder; } private VirtualDisplay createVirtualDisplay() { Log.i(TAG, "Create VirtualDisplay"); return mMediaProjection.createVirtualDisplay(TAG, mScreenWidth, mScreenHeight, mScreenDensity, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mMediaRecorder.getSurface(), null, null); } @Override public void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); Log.i(TAG, "Service onDestroy"); if(mVirtualDisplay != null) { mVirtualDisplay.release(); mVirtualDisplay = null; } if(mMediaRecorder != null) { mMediaRecorder.setOnErrorListener(null); mMediaProjection.stop(); mMediaRecorder.reset(); } if(mMediaProjection != null) { mMediaProjection.stop(); mMediaProjection = null; } } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } }
3、androidManifest.xml权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.RECORD_AUDIO" />
4、service的注册
<service android:name=".ScreenRecordService"/>