android实现录屏功能

这篇文章主要为大家详细介绍了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"/>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持得得之家。

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

iOS 和 Android 哪个更利于赚钱?这篇文章为大家揭晓答案,感兴趣的小伙伴们可以参考一下
这篇文章主要介绍了Android Studio 3.5格式化布局代码时错位、错乱bug的解决,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
这篇文章主要介绍了Android Studio中主题样式的使用方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
这篇文章主要介绍了AndroidManifest.xml中含盖的安全问题,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
这篇文章主要介绍了AndroidStudio代码达到指定字符长度时自动换行实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
这篇文章主要介绍了Android自定义流式布局/自动换行布局实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧