Android added Presentation
in API Level 17 (Android 4.2) to support displaying content on an external Display
, such as as TV or monitor connected via HDMI, MHL, Miracast, or SlimPort. However, Presentation
extends Dialog
, and so it is only usable from an Activity
.
And, as far as I knew, that was the end of the story.
However, this StackOverflow answer hints at a possible way to use an external Display
from a Service
, by means of createDisplayContext()
and WindowManager
created from that Context
. Then, the addView()
method on that WindowManager
should render the View
onto the indicated Display
. If this can be made to work, it really opens the door for interesting uses of external displays, such as playing a video on a TV while being able to use unrelated apps (e.g., a Web browser) on the device's own touchscreen.
However, that answer glosses over a key detail: how to set up the WindowManager.LayoutParams
for the addView()
call. In particular, there are a dizzying array of possible TYPE_
values for the type
field. I have crashed in two attempts, though with different messages:
TYPE_APPLICATION
results in android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
TYPE_APPLICATION_MEDIA
results in android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
For example, here is my WindowManager.LayoutParams
for the second scenario above:
WindowManager.LayoutParams p=
new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
0,
0,
WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA,
0, PixelFormat.OPAQUE);
Reading through the docs for type
suggest that none of the TYPE_APPLICATION
will be correct, as I do not have a token
. Moreover, the point behind this exercise is to not have a token
, as least as far as I can tell, as the Service
is supposed to run independently from any UI.
If you look at the source to Presentation
, it defers the WindowManager
work to Dialog
, which uses com.android.internal.policy.PolicyManager
, which quickly dead-ends in an IPolicy
. An SDK app does not have access to PolicyManager
, anyway.
Has anyone gotten the createDisplayContext()
approach to work from a Service
? If so, what did you use for the type
(or, more generally, for the WindowManager.LayoutParams
in general)? Bonus points for a solution that does not involve some icky permission. :-)
Thanks!
Turn the monitor on. Right-click the Windows desktop and select Display Settings from the drop-down list. If two monitors are not displayed normally, click Detect. Select Show only on 2 from the drop-down list.
Split screen on one monitorPress and hold the Windows key . Press the left or right arrow key. If you press the left arrow key, the active program window shows on the left side of the split screen. If you press the right arrow key, it shows on the right side of the split screen.
TYPE_SYSTEM_ALERT type used conjunctly with the SYSTEM_ALERT_WINDOW permission should work.
It makes sense that launching a dialog from a service requires "icky" permissions, it basically allows you to draw over other apps :)
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