Android 使用MediaProjectionManager 完成录屏功能
关于Android 视频录制功能,下文只介绍录制本机屏幕(不是使用摄像头来进行拍摄)
在Android5.0版本之后,系统给我们提供了**MediaProjectionManager** 和**MediaProjection** 来实现录制视频功能,目前市面的真机基本上都到Android6.0的阶段,所以该功能大家可以放心使用,下面就是具体步骤:1.配置权限以及请求权限(Android6.0)
录屏一般需要两个权限,读写文件权限以及录音权限(视情况而定)
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
2.进行请求系统录屏的回调
如果需要录制的内容就在本页面Activity(Fragment)中可以直接请求录屏,如果需要录制的内容是整个App进程中,就需要做些特别的处理,先有一个空白的Activity进行录屏请求,得到回调之后使用WindowManger添加一个View(方便进行交互),我介绍的就是后面一种:1.空白页面进行录屏请求:
/**
* 实现录屏功能
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class ScreenRecordingActivity extends Activity {
public static final String TAG = "ScreenRecordingActivity";
private static final int STORAGE_REQUEST_CODE = 101;
private static final int RECORD_REQUEST_CODE = 201;
private MediaProjectionManager projectionManager;
private MediaProjection mediaProjection;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
projectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
requestPermission();
}
/**
* 请求录屏权限
*/
private void requestPermission() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { //
ToastUtil.toastLong(this,getString(AFResourceUtil.getStringId(this,"screen_fail_hint")));
LogUtil.e(TAG,"该设配为Android5.0以下接口");
finish();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { //
boolean isSdCard = AppUtil.checkPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE, getString(AFResourceUtil.getStringId(this, "missing_sd_permssion")));
boolean isRecord = AppUtil.checkPermission(this, Manifest.permission.RECORD_AUDIO, "");
if (isSdCard && isRecord) { // 有权限启动录屏
screenRecording();
} else {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO}, STORAGE_REQUEST_CODE);
}
} else { // 5.0 和 5.1 进行录屏
screenRecording();
}
}
private void screenRecording() {
Intent captureIntent = projectionManager.createScreenCaptureIntent();
startActivityForResult(captureIntent, RECORD_REQUEST_CODE);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RECORD_REQUEST_CODE && resultCode == RESULT_OK) {
LogUtil.e(TAG,"可以进行录屏");
mediaProjection = projectionManager.getMediaProjection(resultCode, data);
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int orientation = getResources().getConfiguration().orientation;
RecorderView.Companion.getInstance().showRecord().setRecorderConfig(mediaProjection,metrics,orientation).startRecorder();
finish();
}else { //
LogUtil.e(TAG,"用户取消了录屏");
finish();
}
}
@TargetApi(Build.VERSION_CODES.M)
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {//
switch (requestCode) {
case STORAGE_REQUEST_CODE:
LogUtil.e(TAG, "permissions:" + permissions);
LogUtil.e(TAG, "results:" + grantResults);
// 只要不授权就返回
/**
* 实现录屏功能
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class ScreenRecordingActivity extends Activity {
public static final String TAG = "ScreenRecordingActivity";
private static final int STORAGE_REQUEST_CODE = 101;
private static final int RECORD_REQUEST_CODE = 201;
private MediaProjectionManager projectionManager;
private MediaProjection mediaProjection;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
projectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
requestPermission();
}
/**
* 请求录屏权限
*/
private void requestPermission() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { //
ToastUtil.toastLong(this,getString(AFResourceUtil.getStringId(this,"screen_fail_hint")));
LogUtil.e(TAG,"该设配为Android5.0以下接口");
finish();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { //
boolean isSdCard = AppUtil.checkPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE, getString(AFResourceUtil.getStringId(this, "missing_sd_permssion")));
boolean isRecord = AppUtil.checkPermission(this, Manifest.permission.RECORD_AUDIO, "");
if (isSdCard && isRecord) { // 有权限启动录屏
screenRecording();
} else {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO}, STORAGE_REQUEST_CODE);
}
} else { // 5.0 和 5.1 进行录屏
screenRecording();
}
}
private void screenRecording() {
Intent captureIntent = projectionManager.createScreenCaptureIntent();
startActivityForResult(captureIntent, RECORD_REQUEST_CODE);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RECORD_REQUEST_CODE && resultCode == RESULT_OK) {
LogUtil.e(TAG,"可以进行录屏");
mediaProjection = projectionManager.getMediaProjection(resultCode, data);
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int orientation = getResources().getConfiguration().orientation;
RecorderView.Companion.getInstance().showRecord().setRecorderConfig(mediaProjection,metrics,orientation).startRecorder();
finish();
}else { //
LogUtil.e(TAG,"用户取消了录屏");
finish();
}
}
@TargetApi(Build.VERSION_CODES.M)
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {//
switch (requestCode) {
case STORAGE_REQUEST_CODE:
LogUtil.e(TAG, "permissions:" + permissions);
LogUtil.e(TAG, "results:" + grantResults);
// 只要不授权就返回