MediaProjectionManager
和MediaCodec
等api。通过MediaProjectionManager
获取屏幕共享权限,然后使用MediaCodec
进行视频编码,最后将编码后的数据保存为视频文件。Android实现录屏小功能
一、背景介绍
在现代移动应用开发中,录屏功能已成为许多应用场景的重要组成部分,无论是为了记录游戏玩法、创建教学视频,还是进行远程技术支持,录屏功能都显得尤为重要,本文将详细介绍如何在Android平台上实现一个简单而有效的录屏功能。
二、工具类
MediaProjection
用于屏幕采集。
2. MediaProjectionManager
用于创建MediaProjection实例。
MediaRecoder
用于屏幕录制。
VirtualDisplay
用于创建虚拟屏幕。
DisplayMetrics
用于获取屏幕参数。
三、权限申请
要使用录屏功能,必须请求读写和录像录音权限,以下是在AndroidManifest.xml
中的静态权限申请:
<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"/>
对于Android 6.0及以上版本,还需要动态申请权限:
public void checkPermission() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO}, PERMISSION_REQUEST_CODE); } else { connectService(); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == PERMISSION_REQUEST_CODE) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) { connectService(); } else { Toast.makeText(this, "请同意必须的应用权限,否则无法正常使用该功能!", Toast.LENGTH_SHORT).show(); } } }
四、连接服务
在MainActivity
中连接服务并进行录屏操作:
private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { // 获取到绑定的服务,通过Binder通信 ScreenRecordService.ScreenRecordBinder binder = (ScreenRecordService.ScreenRecordBinder) service; binder.getService().startRecording(); } @Override public void onServiceDisconnected(ComponentName name) { Log.e("TAG", "服务断开连接"); } }; public void connectService() { Intent intent = new Intent(this, ScreenRecordService.class); bindService(intent, serviceConnection, BIN_AUTO_CREATE); }
五、录屏服务实现
创建一个自定义的录屏服务ScreenRecordService
:
public class ScreenRecordService extends Service { private static final String TAG = "ScreenRecordService"; private static final int VIRBAN_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC | DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_OWNER_COMPATIBLE; private MediaProjection mediaProjection; private VirtualDisplay virtualDisplay; private MediaRecoder mediaRecoder; private Surface surface; private int mWidth, mHeight, mDpi; private boolean isRecording = false; private static final Object lock = new Object(); public class ScreenRecordBinder extends Binder { public ScreenRecordService getService() { return ScreenRecordService.this; } } @Nullable @Override public IBinder onBind(Intent intent) { return new ScreenRecordBinder(); } public void startRecording() { synchronized (lock) { if (!isRecording) { initRecorder(); isRecording = true; } } } private void initRecorder() { DisplayMetrics metrics = getResources().getDisplayMetrics(); mWidth = metrics.widthPixels; mHeight = metrics.heightPixels; mDpi = metrics.densityDpi; mediaProjection = MediaProjectionManager.from(this).createScreenCaptureIntent(); surface = MediaCodec.createPersistentInputSurface(); mediaRecoder = new MediaRecoder(); mediaRecoder.setAudioSource(MediaRecoder.AudioSource.MIC); mediaRecoder.setVideoFrameRate(30); mediaRecoder.setVideoSize(mWidth, mHeight); mediaRecoder.setOutputFormat(MediaRecoder.OutputFormat.MPEG_4); mediaRecoder.setVideoEncoder(MediaRecoder.VideoEncoder.H264); mediaRecoder.setAudioEncoder(MediaRecoder.AudioEncoder.AAC); mediaRecoder.setOutputFile("/sdcard/screenrecord.mp4"); try { mediaRecoder.prepare(); } catch (IOException e) { e.printStackTrace(); } virtualDisplay = mediaProjection.createVirtualDisplay("screen-record", mWidth, mHeight, mDpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC); mediaRecoder.start(); } public void stopRecording() { synchronized (lock) { if (isRecording) { mediaRecoder.stop(); mediaRecoder.reset(); isRecording = false; } } } }
六、录屏过程归纳
1、权限申请:确保应用具有必要的权限。
2、连接服务:通过bindService
方法连接到录屏服务。
3、开始录制:调用服务的startRecording
方法进行录屏。
4、停止录制:调用服务的stopRecording
方法停止录屏。
5、保存与分享:将录制的视频文件保存到本地或分享给其他应用。
七、参考资料与扩展阅读
1、[Android官方文档 MediaProjection](https://developer.android.com/reference/android/media/projection/MediaProjection)
2、[CSDN博客 Android录屏功能实现](https://blog.csdn.net/zhangzaihua/article/details/80799897)
以上就是关于“android实现录屏小功能”的问题,朋友们可以点击主页了解更多内容,希望可以够帮助大家!