【问题标题】:How to Set Up a Window on an External Display from a Service?如何通过服务在外部显示器上设置窗口?
【发布时间】:2014-03-21 13:32:57
【问题描述】:

Android 在 API 级别 17 (Android 4.2) 中添加了Presentation,以支持在外部Display 上显示内容,例如通过 HDMI、MHL、Miracast 或 SlimPort 连接的电视或显示器。但是,Presentation 扩展了 Dialog,因此它只能在 Activity 中使用。

据我所知,这就是故事的结局。

但是,this StackOverflow answer 暗示了一种可能的方法,即通过从 Context 创建的 createDisplayContext()WindowManagerService 使用外部 Display。然后,该WindowManager 上的addView() 方法应将View 渲染到指示的Display 上。如果这可以发挥作用,它确实为外部显示器的有趣用途打开了大门,例如在电视上播放视频,同时能够在设备自己的触摸屏上使用不相关的应用程序(例如,网络浏览器)。

但是,这个答案掩盖了一个关键细节:如何为addView() 调用设置WindowManager.LayoutParams。特别是,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?

例如,对于上述第二种情况,这是我的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);

通读the docs for type 表明TYPE_APPLICATION 中没有一个是正确的,因为我没有token。此外,这个练习的目的是没有token,至少据我所知,Service 应该独立于任何 UI 运行。

如果您查看Presentation 的源代码,它会将WindowManager 的工作推迟到Dialog,它使用com.android.internal.policy.PolicyManager,很快就会在IPolicy 中陷入死胡同。无论如何,SDK 应用无权访问PolicyManager

有没有人从Service 获得createDisplayContext() 的工作方式?如果是这样,您对type 使用了什么(或者更一般地说,对于WindowManager.LayoutParams)?不涉及一些讨厌的许可的解决方案的奖励积分。 :-)

谢谢!

【问题讨论】:

    标签: android


    【解决方案1】:

    TYPE_SYSTEM_ALERT 类型与 SYSTEM_ALERT_WINDOW 权限结合使用应该可以工作。

    从服务启动对话是有道理的 需要“icky”权限,它基本上可以让你在其他应用程序上绘图:)

    【讨论】:

    • 嗯,它不会爆炸,这是一个改进。但我的内容(例如,ImageView)也没有显示在外部显示器上。外部显示器的反应是不显示镜像,但它没有显示我添加到与显示器Context 绑定的WindowManager 的内容。 LogCat 内容不显着。所以,我认为你在正确的轨道上,但我可能需要在WindowManager.LayoutParams 上配置更多才能让它工作。谢谢!
    • 嗯,我不太清楚我做了什么,但它现在正在工作,至少在有限的基础上。现在开始扩展它。谢谢!
    • 我想您的视图实际上已显示,但存在一些问题。您可以尝试直接显示 Presentation 派生类(仍设置 dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);),而不是创建自己的 DisplayContext 并添加视图,这适用于我的 Asus Fonepad Note FHD 6 (Android 4.2.2):ph0b.com/uploads/videoOnOverlayDisplay.jpg
    • 仅供参考,FWIW,我刚刚更新了my CWAC-Presentation library,它添加了一个PresentationService,它实现了您描述的方法。再次感谢!
    • @CommonsWare ...您的演示文稿库确实是一个很好的参考...谢谢..!!
    猜你喜欢
    • 1970-01-01
    • 2017-02-06
    • 1970-01-01
    • 1970-01-01
    • 2019-09-03
    • 1970-01-01
    • 2020-02-24
    • 1970-01-01
    • 2012-09-01
    相关资源
    最近更新 更多