Android8.0及以上基于系统MediaRecorder实现录屏最基础步骤
Posted 楠之枫雪
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android8.0及以上基于系统MediaRecorder实现录屏最基础步骤相关的知识,希望对你有一定的参考价值。
1.申请到必须的相关权限
- xml配置,另外需要动态获取权限才行
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
- notification权限
private void notificationPermission(Context context) {//判断应用的通知权限是否打开,返回Boolean值
if (!NotificationManagerCompat.from(context).areNotificationsEnabled()) {
Intent localIntent = new Intent();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//8.0及以上
localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
localIntent.setData(Uri.fromParts("package", context.getPackageName(), null));
} else {
localIntent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
localIntent.putExtra("app_package", context.getPackageName());
localIntent.putExtra("app_uid", context.getApplicationInfo().uid);
}
context.startActivity(localIntent);
}
}
2.编写录屏前台服务
- 在绑定时初始化的数据,包括通过传递过来的数据获取到mediaProjection
@Override
public IBinder onBind(Intent intent) {
//创建前台Notification保护
createNotificationChannel();
//初始化MediaProjection
initMediaProjection(intent);
return new RecordBinder();
}
private void initMediaProjection(Intent intent) {
int mResultCode = intent.getIntExtra("code", -1);
Intent mResultData = intent.getParcelableExtra("data");
MediaProjectionManager mMediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
mediaProjection = mMediaProjectionManager.getMediaProjection(mResultCode, Objects.requireNonNull(mResultData));
}
private void createNotificationChannel() {
Notification.Builder builder = new Notification.Builder(this.getApplicationContext());
Intent nfIntent = new Intent(this, MainActivity.class); //点击后跳转的界面,可以设置跳转数据
builder.setContentIntent(PendingIntent.getActivity(this, 0, nfIntent, 0)) // 设置PendingIntent
.setLargeIcon(BitmapFactory.decodeResource(this.getResources(), R.mipmap.ic_launcher)) // 设置下拉列表中的图标(大图标)
.setContentTitle("屏幕录制") // 设置下拉列表里的标题
.setSmallIcon(R.mipmap.ic_launcher) // 设置状态栏内的小图标
.setContentText("当前正在录屏中...") // 设置上下文内容
.setWhen(System.currentTimeMillis()); // 设置该通知发生的时间
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String notification_id = "notification_screenCap_id";
String notification_name = "notification_screenCap_name";
builder.setChannelId(notification_id);
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NotificationChannel channel = new NotificationChannel(notification_id, notification_name, NotificationManager.IMPORTANCE_LOW);
notificationManager.createNotificationChannel(channel);
}
Notification notification = builder.build();
notification.defaults = Notification.DEFAULT_SOUND; //设置为默认的声音
int notification_id1 = 101;
startForeground(notification_id1, notification);
}
- 开启录屏与停止录屏基础方法
public boolean startRecord() {
if (mediaProjection == null || running) {
return false;
} else {
try {
initRecorder();
} catch (IOException e) {
e.printStackTrace();
running = false;
return false;
}
createVirtualDisplay();
mediaRecorder.start();
running = true;
}
return true;
}
public boolean stopRecord() {
if (running) {
mediaRecorder.stop();
mediaRecorder.release();
virtualDisplay.release();
mediaProjection.stop();
mediaRecorder = null;
return true;
}
return false;
}
private void createVirtualDisplay() {
virtualDisplay = mediaProjection.createVirtualDisplay("MainScreen", width, height, dpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mediaRecorder.getSurface(), null, null);
}
private void initRecorder() throws IOException {
mediaRecorder = new MediaRecorder();
mediaRecorder.setAudiosource(MediaRecorder.AudioSource.DEFAULT);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
videoName = System.currentTimeMillis() + ".mp4";
mediaRecorder.setOutputFile(createSaveVideoFile());
mediaRecorder.setVideoSize(width, height);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.setVideoEncodingBitRate(5 * 1024 * 1024);
mediaRecorder.setVideoFrameRate(30);
mediaRecorder.prepare();
}
3.申请录屏服务权限
projectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
Intent captureIntent = projectionManager.createScreenCaptureIntent();
startActivityForResult(captureIntent, RECORD_REQUEST_CODE);
4.成功后绑定录屏服务
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RECORD_REQUEST_CODE && resultCode == RESULT_OK) {
Intent intent = new Intent(this, RecordService.class);
intent.putExtra("code", resultCode);
intent.putExtra("data", data);
bindService(intent, connection, BIND_AUTO_CREATE);
}
}
private final ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
RecordService.RecordBinder binder = (RecordService.RecordBinder) service;
recordService = binder.getRecordService();
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
//设置录屏分辨率
recordService.setConfig(metrics.widthPixels, metrics.heightPixels, metrics.densityDpi);
recordService.startRecord();
startBtn.setEnabled(true);
startBtn.setText(recordService.isRunning() ? "停止录屏" : "开始录屏");
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
}
};
这样后就可以通过ServiceConnection获取到服务的引用了,下面就可以愉快的进行业务逻辑的交互开发吧。
5.初步演示效果
转载注明:https://blog.csdn.net/u014614038/article/details/117699817
以上是关于Android8.0及以上基于系统MediaRecorder实现录屏最基础步骤的主要内容,如果未能解决你的问题,请参考以下文章
Android8.0及以上基于系统MediaRecorder实现录屏最基础步骤
在 Android 8.0 以上。有啥方法可以知道系统中是不是开启了 pip 模式