Android辅助显示 - 跨活动调用的持久性

时间:2013-02-26 14:02:28

标签: android multithreading android-activity hdmi

我正在使用Android MediaRouter(API 16)和Presentation(API 17)类生成&管理辅助显示。我按照ApiDemos中的示例创建了独特的非镜像输出,到目前为止它工作正常(使用通过HDMI线连接到HDTV的Nexus 10进行测试)。

现在,我希望在Activity X中创建的Presentation对象继续在辅助显示器上运行,即使Activity X调用另一个Activity Y。在这种情况下,Activity X仍在堆叠中,但Activity Y现在位于其上。

问题是当Activity Y启动时,物理辅助显示会恢复为镜像。当我退出Activity Y时,Activity X's演示文稿的内容会返回(因为我从未在其上调用dismiss())。

所以问题是:如果将演示文稿附加到该显示器上运行的辅助显示器上,即使本地设备上正在运行从属活动,该怎么办?

更新:我想到的一种方法是从后台线程实例化Presentation对象;然后,另一个Activity的后续创建不应该干扰后台线程写入其Presentation对象的内容。但我不确定这是否可行,因为通常不允许从后台线程更新UI。

另一种方法是尽可能禁用下级Activity使用辅助显示,从而防止它在新Activity变为活动状态时将辅助显示恢复为镜像。但我也没有办法做到这一点。再次感谢您的任何建议。

2 个答案:

答案 0 :(得分:2)

我实施了@CommonsWare建议的一种方法(由Mark Allison独立回答我关于his blog的问题)。谢谢你的建议!

在审核中,问题是我无法在本地设备上的Activity次调用中在后台运行第二个屏幕演示文稿。这是因为Presentation类是作为Dialog的子类实现的,因此绑定到Activity实例。因此,当一个新的Activity启动时,第二个屏幕又回到了镜像状态(而不是显示我专门为其生成的其他内容)。

解决方案是将所有“下级”Activities重构为原始Fragments的{​​{1}}(即启动第二个屏幕的那个)。然后,我使用Activity开始/停止新的startActivity(),而不是调用Fragments。最终效果是启动演示文稿的活动仍在运行,因此当新活动开始时,辅助显示不再中断。

我的情况更加复杂,因为顶级FragmentTransactions(启动第二个屏幕)实际上是使用ActivitySherlockFragmentActivity的{​​{1}} - - 所以我不得不把这一切塞进ViewPager。它还需要明确管理FragmentStatePagerAdapter选项卡,菜单项和主页图标。

总的来说,我认为代码的透明度稍差......但它确实有效!

注意: Google实施了辅助屏幕界面是件好事。但我不确定他们为什么这样做。如果他们提供了一个可以在后台轻松运行的更通用的解决方案,即不管前景Fragment如何,那么将ActionBar类变为Presentation而不是将其变为笨蛋。装置。如上所述,像这样的解决方案可以使我免于大量的代码重构。

答案 1 :(得分:0)

从死者身上带回这个问题,愿意在某个时间帮助有同样问题的人,

我最近遇到了一个更深刻但更相似的问题:我必须在系统的任何地方显示演示文稿(我使用嵌入式android),并且在主屏幕中可以使用任何应用程序。

我首先考虑创建一个管理演示文稿显示的服务,并在应用程序启动时进行初始化。但问题是我无法显示演示文稿,因为正如您所提到的,它继承自Dialog,并且在构建对话框时调用 getApplicationContext()时会发生同样的问题。 / p>

我的解决方案是:  WindowManager.LayoutParam名为TYPE_SYSTEM_ALERT,用于显示低电量警报对话框等警报。使用此属性,您可以从服务创建一个Dialog并正确显示它,并且由于Presentation类是Dialog的子类,只需设置此属性即可使用。

魔术发生在这里:

 WindowManager.LayoutParams l = mPresentation.getWindow()
                    .getAttributes();
 l.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
 mPresentation.show();

只是提醒一下,为了实现这一点,应用程序XML应具有SYSTEM_ALERT_WINDOW权限。

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

我认为这也应该解决你的问题,但它有点熟悉,你需要一个适当的治疗方法,以便在你需要时尽快停止演示。