Как настроить окно на внешнем дисплее из службы?

Android добавила Presentation в API Level 17 (Android 4.2) для поддержки отображения содержимого на внешнем Display , например, телевизора или монитора, подключенного через HDMI, MHL, Miracast или SlimPort. Однако Presentation расширяет Dialog , и поэтому он может использоваться только из Activity .

И, насколько я знаю, это был конец истории.

Тем не менее, этот ответ StackOverflow намекает на возможный способ использования внешнего Display из Service с помощью createDisplayContext() и WindowManager созданного из этого Context . Затем метод addView() в этом WindowManager должен отображать View на указанный Display . Если это можно заставить работать, это действительно открывает двери для интересного использования внешних дисплеев, таких как воспроизведение видео на телевизоре, когда вы можете использовать несвязанные приложения (например, веб-браузер) на собственном сенсорном экране устройства.

Однако этот ответ замалчивает ключевую деталь: как настроить WindowManager.LayoutParams для addView() . В частности, есть головокружительный массив возможных значений TYPE_ для поля type . Я разбился в двух попытках, хотя и с разными сообщениями:

  • Результаты TYPE_APPLICATION в android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application

  • TYPE_APPLICATION_MEDIA приводит к android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running? android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?

Например, вот мой WindowManager.LayoutParams для второго сценария выше:

 WindowManager.LayoutParams p= new WindowManager.LayoutParams( WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT, 0, 0, WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA, 0, PixelFormat.OPAQUE); 

Чтение документов для type предполагает, что ни одна из TYPE_APPLICATION не будет корректной, поскольку у меня нет token . Более того, точка, стоящая за этим упражнением, заключается в том, чтобы не иметь token , насколько я могу судить, поскольку Service должна работать независимо от любого пользовательского интерфейса.

Если вы посмотрите на источник в Presentation , он отменит работу WindowManager на Dialog , в которой используется com.android.internal.policy.PolicyManager , который быстро IPolicy в IPolicy . PolicyManager или иначе, приложение SDK не имеет доступа к PolicyManager .

Кто-нибудь получил метод createDisplayContext() для работы с Service ? Если да, то что вы использовали для type (или, более того, для WindowManager.LayoutParams в целом)? Бонусные баллы за решение, которое не требует какого-либо нехорошего разрешения. 🙂

Благодаря!

Тип TYPE_SYSTEM_ALERT, используемый коннективно с разрешением SYSTEM_ALERT_WINDOW, должен работать.

Имеет смысл, что запуск диалога из службы требует «icky» разрешений, в основном это позволяет вам рисовать другие приложения 🙂