android实现录屏功能
作者:jian11058 发布时间:2022-04-18 05:11:22
标签: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"/>
来源:https://blog.csdn.net/jian11058/article/details/83587886


猜你喜欢
- 本文实例讲述了Android编程实现状态保存的方法。分享给大家供大家参考,具体如下:1、当我们正在发短信的时候,已经写了几百字了,这时突然来
- 简要介绍Retrofit是当前应用非常广泛的网络请求框架,通常结合RxJava来进行网络请求,本文将展示一个采用RxJava+Retrofi
- 有关android的弹窗界面相信大家见过不少了,手机上很多应用软件都涉及到弹窗控件,比如典型的每次删除一个图片或者卸载一个等都会弹出一个窗口
- 详细步骤首先在pom.xml文件中做一些修改:之前打war包需要修改打包方式,这次不需要了,因为默认就是 jar 包指定最终打成jar包的名
- 在java开发中,类、接口、方法,都需要进行注释,注释内容如图:注释中的基本元素有:描述、作者、创建日期。可增加元素有:修改日期、修改内容、
- RestTemplate 是由 Spring 提供的一个 HTTP 请求工具,它提供了常见的REST请求方案的模版,例如 GET 请求、PO
- 本文介绍了使用C#创建Windows服务的实例代码,分享给大家一、开发环境操作系统:Windows 10 X64开发环境:VS2015编程语
- DataHub 类似于传统大数据解决方案中 Kafka 的角色,提供了一个数据队列功能。DataHub 除了供了一个缓冲的队列作用。同时由于
- 本文实例为大家分享了Android屏幕适配工具类的具体代码,供大家参考,具体内容如下DimenToolgithub地址Android 屏幕适
- 刚刚学习Android,用Gallery作了一个小demo,用来记录一下。package com.example.galleryex02;i
- Android中实现沉浸式状态栏的功能,供大家参考,具体内容如下1. 先上效果图,实现沉浸式状态栏有两种方式,一种是通过写Theme主题的方
- 在注册表启动项里添加一项,路径:SOFTWARE\Microsoft\Windows\CurrentVersion\Run或者直接:运行-&
- java 算法之快速排序实现代码摘要: 常用算法之一的快速排序算法的java实现原理:选择一个基准元素,通常选择第一个元素或者最后一个元素,
- 前言本文主要跟大家介绍了关于Java用gson解析Json的相关内容,分享出来供大家参考学习,需要的朋友们下面来一起看看吧。json数据{&
- springboot 统一设置时区控制springboot服务的时区为东八区@SpringBootApplicationpublic cla
- 安装完,或者绿色版解压完,先别打开Android Stduio。要先配置下Android Studio 的缓存路径。这个缓存文件主要是存放一
- RabbitMQ的一些基本组件Producer:消息的生产者Consumer:消息的消费者Broker:MQ服务器,管理队列、消息Messa
- 本文实例讲述了C#基于正则表达式删除字符串中数字或非数字的方法。分享给大家供大家参考,具体如下:/// 去掉字符串中的数字public st
- Unity中的RegisterPlugins实用案例在Unity游戏开发中,我们经常需要使用第三方插件来实现一些特定的功能。为了让这些插件能
- 1.查询(get)-调用的时候记得开线程GET一般用于获取/查询资源信息val sb = StringBuffer() try { &nbs