In my scenario, I want to mirror another app in my app.
I use DisplayManager
to createVirtualDisplay
for my SurfaceView
. Then I set DisplayId
as this VirtualDisplay
in AcitivityOptions
when I start activity.
By this process, another app can be launched successfully in my surfaceview. But there are some display problems. According to my test, only image, background color and GLSurfaceView.Renderer
are rendered correctly. The ui-component such as TextView
and Button
are not rendered in SurfaceView
.
From the above test result, I guess it may be related to the depth or order of rendering.
The example code is as followed:
SurfaceView surfaceView = findViewById(R.id.surface_view);
int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION |
DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
DisplayManager displayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
VirtualDisplay virtualDisplay = displayManager.createVirtualDisplay("MyVirtualDisplay",
surfaceView.getWidth(), surfaceView.getHeight(), 1, surfaceView.getHolder().getSurface(),
flags);
int displayId = virtualDisplay.getDisplay().getDisplayId();
ActivityOptions options = ActivityOptions.makeBasic().setLaunchDisplayId(displayId);
Intent intent = getPackageManager().getLaunchIntentForPackage(appName);
intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent, options.toBundle());
By contrast, if I mirror same activity to a Display
instead of VirtualDisplay
, which can be captured by MediaRouter
or DisplayManager
. In this way, everything displays correctly (In my test, I simulate the second monitor by "Developer Options" -> "Simulate Secondary Displays"):
MediaRouter mediaRouter = (MediaRouter)getSystemService(Context.MEDIA_ROUTER_SERVICE);
MediaRouter.RouteInfo route = mediaRouter.getSelectedRoute(MediaRouter.ROUTE_TYPE_LIVE_VIDEO);
Display presentationDisplay = route.getPresentationDisplay();
int displayId = presentationDisplay.getDisplayId();
Intent intent = getPackageManager().getLaunchIntentForPackage(appName);
intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT | Intent.FLAG_ACTIVITY_NEW_TASK);
ActivityOptions options = ActivityOptions.makeBasic().setLaunchDisplayId(displayId);
startActivity(intent, options.toBundle());
Is there any process I miss or any flags I misconfigure in virtual display mode? Thanks for any help.
P.S. To mirror another app, I have rooted and launched as system app.
Your problem was calling createVirtualDisplay with wrong densityDpi, it should be more large numbers, such as 480, 560.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With