MediaProjectionManager 是 Android 系统中实现屏幕录制和截屏功能的管理器,允许应用请求用户授权并获取屏幕投影,进而实现屏幕内容的录制或截图 。
使用步骤
- 获取 MediaProjectionManager 实例:
通过 getSystemService(Context.MEDIA_PROJECTION_SERVICE) 获取 。
- 请求权限:
使用 createScreenCaptureIntent() 创建用于请求屏幕捕获权限的 Intent,并通过 startActivityForResult() 启动该 Intent 。此时系统会显示请求授权的弹窗。
- 处理授权结果:
在 onActivityResult() 中,判断弹窗成功授权后启动服务。若结果码为 RESULT_OK,则通过 getMediaProjection(resultCode, data) 获取 MediaProjection 对象 。
- 创建 VirtualDisplay:
使用 MediaProjection.createVirtualDisplay() 创建虚拟显示,传入屏幕宽度、高度、密度等参数,并指定一个 Surface(如 ImageReader 或 SurfaceView 的 Surface)以捕获屏幕内容 。
createVirtualDisplay 说明
参数详解
参数名 |
含义说明 |
|
虚拟显示的名称,不能为空字符串。 |
|
虚拟屏幕的宽度(像素),必须 > 0。 |
|
虚拟屏幕的高度(像素),必须 > 0。 |
|
屏幕密度(dpi),建议与真实屏幕一致,可通过 |
|
控制虚拟显示行为的标志位,如 |
|
渲染目标,通常是 |
|
监听虚拟显示状态变化的回调,可为 |
|
指定回调线程的 |
常用 Flags
Flag 名称 |
含义说明 |
|
公共显示,允许其他应用在此显示上打开窗口。默认是私有的。 |
|
设置为演示显示,常用于双屏展示场景。 |
|
安全显示,防止内容被截屏/录制(需系统权限)。 |
|
仅显示自己的内容,不镜像其他屏幕内容。 |
|
自动镜像主屏幕内容(常用于录屏)。需要 |
示例代码:
val mediaProjectionManager = getSystemService(MediaProjectionManager::class.java)
val startMediaProjection = registerForActivityResult(StartActivityForResult()) { result ->
if (result.resultCode == RESULT_OK) {
val mediaProjection = mediaProjectionManager.getMediaProjection(result.resultCode, result.data!!)
val displayMetrics = resources.displayMetrics
val surface = mediaRecorder.surface // 也可以是 ImageReader.getSurface()
val virtualDisplay = mediaProjection.createVirtualDisplay(
"ScreenCapture",
displayMetrics.widthPixels,
displayMetrics.heightPixels,
displayMetrics.densityDpi,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
surface,
null,
null
)
}
}
startMediaProjection.launch(mediaProjectionManager.createScreenCaptureIntent())
如需进一步处理画面(如截图或编码),可将 Surface 替换为 ImageReader 或 MediaCodec 的输入 Surface,灵活适配不同使用场景。
注意事项
Android 5.0 及以上版本支持
MediaProjection
功能 。需处理用户拒绝授权的情况,确保良好的用户体验 。
在 Android 10 及以上版本中,注意存储权限等适配问题 。
权限要求:必须在每次使用前通过
createScreenCaptureIntent()
获取用户授权。一次性使用:Android 14+ 中,
MediaProjection
令牌只能用于一次createVirtualDisplay()
调用。资源释放:使用完后必须调用
virtualDisplay.release()
和mediaProjection.stop()
,避免内存泄漏。