同一应用内VirtualDisplay无法启动Activity的问题排查
问题根源
Android系统对非默认Display启动Activity有严格的权限校验,即使是同应用内的操作,若缺少正确的配置或权限上下文,也会触发SecurityException。
具体解决步骤
正确创建VirtualDisplay
必须通过MediaProjection实例创建VirtualDisplay,不能直接使用DisplayManager的createVirtualDisplay方法。结合以下标志组合:// 先通过MediaProjectionManager获取用户授权的MediaProjection实例 MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data); // 创建VirtualDisplay mVirtualDisplay = mediaProjection.createVirtualDisplay( "MyVirtualDisplay", screenWidth, screenHeight, screenDensity, DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION | DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY, surface, null, null );VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY会限制只有本应用的内容能显示在该虚拟屏上,降低权限校验的严格程度。通过ActivityOptions指定启动Display
启动Activity时,必须用ActivityOptions明确设置目标Display ID,不能通过Intent额外参数传递:Intent intent = new Intent(MainActivity.this, Activity2.class); ActivityOptions options = ActivityOptions.makeBasic(); options.setLaunchDisplayId(mVirtualDisplay.getDisplay().getDisplayId()); startActivity(intent, options.toBundle());确保MediaProjection权限有效
必须通过MediaProjectionManager.createScreenCaptureIntent()引导用户完成授权流程,获取合法的MediaProjection实例。如果授权过期或未获取,系统会拒绝虚拟屏上的Activity启动请求。适配Android版本
Android 10(API 29)及以上版本对虚拟屏权限控制更严格,需确保:- targetSdkVersion适配对应版本的行为规范
- 避免在后台创建VirtualDisplay(需在前台生命周期内操作)
为什么之前的尝试无效
仅添加VIRTUAL_DISPLAY_FLAG_PRESENTATION标志但未结合MediaProjection创建VirtualDisplay,或启动Activity时未通过ActivityOptions正确指定Display ID,都会导致系统判定为非法跨Display启动请求,触发权限拒绝。
内容的提问来源于stack exchange,提问作者Igor Trud

