android实现录屏功能

作者:jian11058 时间:2022-04-18 05:11:22 

本文实例为大家分享了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"/>

来源:https://blog.csdn.net/jian11058/article/details/83587886

标签:android,录屏
0
投稿

猜你喜欢

  • Android 用 camera2 API 自定义相机

    2023-04-30 11:29:37
  • 详解Java的位操作符

    2023-06-24 05:31:14
  • C#使用Dispose模式实现手动对资源的释放

    2022-09-21 16:12:14
  • 浅谈两个jar包中包含完全相同的包名和类名的加载问题

    2023-04-13 04:47:02
  • java JVM原理与常识知识点

    2022-06-24 16:26:50
  • Java Hibernate对象(瞬时态,持久态,脱管态)详解

    2022-05-22 20:07:32
  • Java ArrayList实现班级信息管理系统

    2023-09-17 15:15:25
  • 解决springboot启动失败的问题('hibernate.dialect' not set)

    2023-11-09 03:21:21
  • C#模板方法模式(Template Method Pattern)实例教程

    2022-09-12 02:59:23
  • GridView基于pulltorefresh实现下拉刷新 上拉加载更多功能(推荐)

    2022-08-29 23:51:58
  • 一键清除maven仓库中下载失败的jar包的实现方法

    2023-08-13 03:43:59
  • c# split分隔字符串使用方法

    2023-04-12 18:00:54
  • SpringBoot整合SpringTask实现定时任务的流程

    2022-03-28 22:24:40
  • Java源码解析之接口List

    2022-06-13 08:46:44
  • Java双向链表的操作

    2021-07-31 02:54:33
  • java并发JUC工具包AtomicInteger原子整型语法基础

    2023-10-05 14:16:47
  • Mybatis-plus全局id生成策略详解

    2022-11-30 02:41:21
  • unity通过Mesh网格绘制图形(三角形、正方体、圆柱)

    2021-09-27 23:16:12
  • Java获取环境变量(System.getenv)的方法

    2021-10-06 03:23:47
  • 浅谈VS中添加头文件时显示无法找到文件的问题

    2022-05-25 08:13:46
  • asp之家 软件编程 m.aspxhome.com