android视频截屏&手机录屏实现代码
发布时间 - 2026-01-11 02:31:59 点击率:次本文介绍了android视频截屏&手机录屏实现代码,分享给大家,希望对大家有帮助

问题
在android中有时候我们需要对屏幕进行截屏操作,单一的截屏操作好解决可以通过activity的顶层view DecorView获取一个bitmap,得到就是当前activity上面的全部视图。
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap bmp = view.getDrawingCache();
DisplayMetrics dm = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
Bitmap ret = Bitmap.createBitmap(bmp, 0, 0, dm.widthPixels, dm.heightPixels);
view.destroyDrawingCache();
如果activity中包含一些视频播放器比如SurfaceView GLSurfaceView TextureView,在调用截屏代码会发现播放视频的部分是黑屏的,原因是这几种视频渲染的view通过以上代码拿到的是缓冲区不是真正的图像。
解决办法
android5.0以上系统提供了一个 MediaProjectionManager类来对手机进行录屏操作,也支持获取手机的Image图像的操作,知道了这些我们就可以通过提供的api来进行截屏操作了。
这里通过Service来操作截屏和录屏的api
1.绑定截屏的Service
Intent intent = new Intent(this, ScreenService.class);
bindService(intent, mServiceConnection, BIND_AUTO_CREATE);
public void onServiceConnected(ComponentName className, IBinder service) {
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
ScreenService.RecordBinder binder = (ScreenService.RecordBinder) service;
recordService = binder.getRecordService();
recordService.setConfig(metrics.widthPixels, metrics.heightPixels, metrics.densityDpi);
mButton.setEnabled(true);
mButton.setText(recordService.isRunning() ? "结束" : "开始");
}
2.请求权限 onActivityResult 方法中回调。
Intent captureIntent = projectionManager.createScreenCaptureIntent(); startActivityForResult(captureIntent, RECORD_REQUEST_CODE);
成功后
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RECORD_REQUEST_CODE && resultCode == RESULT_OK) {
//######## 截屏逻辑 ########
mediaProjection = projectionManager.getMediaProjection(resultCode, data);
recordService.setMediaProject(mediaProjection);
recordService.initImageReader();
}
}
3. 获取截屏
@Override
public void onClick(View view) {
//######## 截屏逻辑 ########
Bitmap bitmap = recordService.getBitmap();
mImageView.setImageBitmap(bitmap);
}
录屏
录屏需要初始化一些录屏参数,输入麦克风类型视频类型,保存路径等
private void initRecorder() {
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setOutputFile(
getSavePath() + System.currentTimeMillis() + ".mp4");
mediaRecorder.setVideoSize(width, height);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.setVideoEncodingBitRate(5 * 1024 * 1024);
mediaRecorder.setVideoFrameRate(30);
try {
mediaRecorder.prepare();
} catch (IOException e) {
e.printStackTrace();
}
}
开始录屏
mediaRecorder.start();
保存路径
完整Service代码
public class ScreenService extends Service {
private MediaRecorder mediaRecorder;
private VirtualDisplay virtualDisplay;
private boolean running;
private int width = 720;
private int height = 1080;
private int dpi;
private ImageReader mImageReader;
private MediaProjection mediaProjection;
@Override
public IBinder onBind(Intent intent) {
return new RecordBinder();
}
@Override
public void onCreate() {
super.onCreate();
running = false;
mediaRecorder = new MediaRecorder();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
}
public void setMediaProject(MediaProjection project) {
mediaProjection = project;
}
public boolean isRunning() {
return running;
}
public void setConfig(int width, int height, int dpi) {
this.width = width;
this.height = height;
this.dpi = dpi;
}
/**
* 开始录屏
*
* @return true
*/
public boolean startRecord() {
if (mediaProjection == null || running) {
return false;
}
initRecorder();
createVirtualDisplay();
mediaRecorder.start();
running = true;
return true;
}
/**
* 结束录屏
*
* @return true
*/
public boolean stopRecord() {
if (!running) {
return false;
}
running = false;
mediaRecorder.stop();
mediaRecorder.reset();
virtualDisplay.release();
mediaProjection.stop();
return true;
}
public void setMediaProjection(MediaProjection mediaProjection) {
this.mediaProjection = mediaProjection;
}
/**
* 初始化ImageRead参数
*/
public void initImageReader() {
if (mImageReader == null) {
int maxImages = 2;
mImageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, maxImages);
createImageVirtualDisplay();
}
}
/**
* 创建一个录屏 Virtual
*/
private void createVirtualDisplay() {
virtualDisplay = mediaProjection
.createVirtualDisplay("mediaprojection", width, height, dpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mediaRecorder
.getSurface(), null, null);
}
/**
* 创建一个ImageReader Virtual
*/
private void createImageVirtualDisplay() {
virtualDisplay = mediaProjection
.createVirtualDisplay("mediaprojection", width, height, dpi,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mImageReader
.getSurface(), null, null);
}
/**
* 初始化保存屏幕录像的参数
*/
private void initRecorder() {
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setOutputFile(
getSavePath() + System.currentTimeMillis() + ".mp4");
mediaRecorder.setVideoSize(width, height);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.setVideoEncodingBitRate(5 * 1024 * 1024);
mediaRecorder.setVideoFrameRate(30);
try {
mediaRecorder.prepare();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 获取一个保存屏幕录像的路径
*
* @return path
*/
public String getSavePath() {
if (Environment.getExternalStorageState()
.equals(Environment.MEDIA_MOUNTED)) {
String rootDir = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/" +
"ScreenRecord" + "/";
File file = new File(rootDir);
if (!file.exists()) {
if (!file.mkdirs()) {
return null;
}
}
return rootDir;
} else {
return null;
}
}
/**
* 请求完权限后马上获取有可能为null,可以通过判断is null来重复获取。
*/
public Bitmap getBitmap() {
Bitmap bitmap = cutoutFrame();
if (bitmap == null) {
getBitmap();
}
return bitmap;
}
/**
* 通过底层来获取下一帧的图像
*
* @return bitmap
*/
public Bitmap cutoutFrame() {
Image image = mImageReader.acquireLatestImage();
if (image == null) {
return null;
}
int width = image.getWidth();
int height = image.getHeight();
final Image.Plane[] planes = image.getPlanes();
final ByteBuffer buffer = planes[0].getBuffer();
int pixelStride = planes[0].getPixelStride();
int rowStride = planes[0].getRowStride();
int rowPadding = rowStride - pixelStride * width;
Bitmap bitmap = Bitmap.createBitmap(width +
rowPadding / pixelStride, height, Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(buffer);
return Bitmap.createBitmap(bitmap, 0, 0, width, height);
}
public class RecordBinder extends Binder {
public ScreenService getRecordService() {
return ScreenService.this;
}
}
demo下载
github
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# android视频截屏
# android手机录屏
# android
# 截屏录屏
# Android实现截屏方式整理(总结)
# Android截屏保存png图片的实例代码
# android截屏功能实现代码
# 使用python编写android截屏脚本双击运行即可
# android实现手机截屏并保存截图功能
# Android 使用Shell脚本截屏并自动传到电脑上
# Android截屏SurfaceView黑屏问题的解决办法
# Android实现截屏并保存操作功能
# Android 屏幕截屏方法汇总
# Android实现截屏功能
# 可以通过
# 创建一个
# 的是
# 有可能
# 中有
# 作了
# 下一
# 给大家
# 几种
# 解决办法
# 绑定
# 作好
# 回调
# 大家多多
# 就可以
# 黑屏
# 知道了
# 视频播放器
# isRunning
# mButton
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Win11怎么开启自动HDR画质_Windows11显示设置HDR选项
魔方云NAT建站如何实现端口转发?
长沙企业网站制作哪家好,长沙水业集团官方网站?
做企业网站制作流程,企业网站制作基本流程有哪些?
北京的网站制作公司有哪些,哪个视频网站最好?
如何快速生成专业多端适配建站电话?
韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南
如何在 Pandas 中基于一列条件计算另一列的分组均值
Windows10电脑怎么查看硬盘通电时间_Win10使用工具检测磁盘健康
Laravel怎么配置S3云存储驱动_Laravel集成阿里云OSS或AWS S3存储桶【教程】
Laravel队列由Redis驱动怎么配置_Laravel Redis队列使用教程
Laravel API路由如何设计_Laravel构建RESTful API的路由最佳实践
大同网页,大同瑞慈医院官网?
企业在线网站设计制作流程,想建设一个属于自己的企业网站,该如何去做?
如何使用 jQuery 正确渲染 Instagram 风格的标签列表
Laravel怎么做缓存_Laravel Cache系统提升应用速度的策略与技巧
免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?
Laravel如何处理表单验证?(Requests代码示例)
Laravel如何记录日志_Laravel Logging系统配置与自定义日志通道
用yum安装MySQLdb模块的步骤方法
在线ppt制作网站有哪些软件,如何把网页的内容做成ppt?
制作公司内部网站有哪些,内网如何建网站?
Android实现代码画虚线边框背景效果
如何快速选择适合个人网站的云服务器配置?
Laravel PHP版本要求一览_Laravel各版本环境要求对照
Android 常见的图片加载框架详细介绍
如何确保FTP站点访问权限与数据传输安全?
iOS中将个别页面强制横屏其他页面竖屏
如何快速搭建安全的FTP站点?
如何在建站之星绑定自定义域名?
Laravel怎么生成URL_Laravel路由命名与URL生成函数详解
如何选择可靠的免备案建站服务器?
html5如何实现懒加载图片_ intersectionobserver api用法【教程】
Laravel如何使用Spatie Media Library_Laravel图片上传管理与缩略图生成【步骤】
如何批量查询域名的建站时间记录?
Laravel如何使用Collections进行数据处理?(实用方法示例)
Android自定义控件实现温度旋转按钮效果
JavaScript如何操作视频_媒体API怎么控制播放
在线制作视频的网站有哪些,电脑如何制作视频短片?
阿里云高弹*务器配置方案|支持分布式架构与多节点部署
三星网站视频制作教程下载,三星w23网页如何全屏?
Laravel模型关联查询教程_Laravel Eloquent一对多关联写法
郑州企业网站制作公司,郑州招聘网站有哪些?
微信小程序 require机制详解及实例代码
如何实现建站之星域名转发设置?
Laravel如何从数据库删除数据_Laravel destroy和delete方法区别
,交易猫的商品怎么发布到网站上去?
韩国服务器如何优化跨境访问实现高效连接?
如何获取上海专业网站定制建站电话?
Laravel辅助函数有哪些_Laravel Helpers常用助手函数大全

