安卓如何接收音频焦点变化的广播?

8
我正在尝试编写一个应用程序,检测设备上的任何应用程序何时开始或停止播放音乐。我的应用程序不是媒体播放器,更像是仪表板功能,因此我不需要请求音频焦点,但我想知道其他应用程序何时这样做,以便我可以相应地更新我的状态文本。
基本上,我认为函数AudioManager.isMusicActive()将提供我所需了解的几乎所有信息,但由于我正在编写一个始终运行的服务,因此我希望避免需要在持续不断地轮询该函数。我需要实时获取信息,因此它将永久进行1秒轮询。
我正在寻找一种方法来检测STREAM_MUSIC是否被其他应用程序使用。
我考虑过的一些方法:
(1)再次使用Timer或Handler进行永久轮询,以不断轮询isMusicActive()函数。从电池或处理器管理的角度来看并不理想。我可以在UI Activity中使用标志变量来控制何时运行轮询(在UI不在前台时并不真正必要),但我仍然认为我使用的处理器/电池时间比我需要的多。
(2)监听某种广播,但是没有Android音频广播似乎真正符合要求。(至少我没找到)
(3)我可以请求音频焦点,但从不播放任何音频并永远不放弃它。理论上,由于我在始终运行的服务中启动了这个功能,我相信我的应用程序应该可以坐在LIFO音频焦点堆栈的底部,并且我将通过AudioManager.OnAudioFocusChangeListener机制得到通知,基本上与其预期目的相反(即当我失去音频焦点时打开我的应用程序,并在重新获得音频焦点时关闭它)。然而,我不完全确定像这样做会在实际使用中如何运作。我觉得滥用音频焦点方法来做这样的事情很容易导致负面用户体验,在我甚至没有想到的情况下。
(4)是否有一种方法可以在根本不需要请求音频焦点的情况下使用AudioManager.OnAudioFocusChangeListener(或类似的东西)?
还有其他方法可以做到这一点吗?只要指向正确方向就非常有帮助!

你在这方面有什么进展了吗? - barkside
不幸的是,我最终完全重写了AudioManager代码,以便应用程序不再需要被通知音频焦点。 结果代码在我看来效率要低得多,但是还算是足够有效,并且运行得相当不错... - QuotidianVoid
你有得到可行的解决方案吗?请分享一下,我也遇到了类似的问题。 - gaurav jain
1个回答

2
我需要类似的东西,所以进行了一些研究。不幸的是,除了在您的应用程序中请求音频焦点之外,似乎没有其他方法可以实现此目的。
学习材料: 检查Android源代码,在frameworks\base\media\java\android\media\中,您可以找到MediaFocusControl类中requestAudioFocus的实际代码。
此文件夹中的其他类显示了它们如何发送广播事件以更改音量、打开/关闭蓝牙等,但与启用/禁用音频相关的广播事件均没有。
有关此主题的其他信息: 除此之外,似乎没有任何记录的方法可以知道音频硬件何时开始/停止播放。
我相信请求音频焦点而实际上不播放音频不会消耗任何电池。唯一的一个丑陋的副作用是停止当前播放的音频。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接