如果没有启用 kAudioSessionProperty_OverrideCategoryMixWithOthers,iOS 5 音频警报不会响起
我有一个 音频应用,它在 iOS 5 更改音频行为的方式方面存在一些问题。当我的应用程序的音频正在播放 (AVAudioSessionCategoryPlayback
),并且从操作系统触发 Clock.app 闹钟或计时器时,会弹出 UIAlertView 通知,但没有音频警报。我的应用程序声音很好,可以避开音频警报,但警报应用程序的音频警报不会响起。
自然,大量的支持请求因 iOS 5 的变化而涌入。我已经通过设置 kAudioSessionProperty_OverrideCategoryMixWithOthers
暂时解决了这个问题,这让警报音频通过,但是这样做时会产生一些非常不良的副作用:
- 其他应用程序的音频可以播放/在我的上方。
- 远程控制事件不会路由到我的应用程序,而是路由到 iPod.app。
对于我的应用程序的要求来说,上述缺点都是不可接受的。我已经研究这个问题有一段时间了,但一直没能破解它。如何设置我的音频,以便:
- 我的应用程序的音频仍然使用
AVAudioSessionCategoryPlayback
类别作为背景音频。 - Clock.app 闹钟仍然发出音频警报
- 该应用程序仍然响应远程控制通知
I have an audio app that is having some problems with the way iOS 5 has changed audio behaviors. When my app's audio is playing (AVAudioSessionCategoryPlayback
), and a Clock.app alarm or timer is fired from the OS, the UIAlertView notification pops up, but without the audio alert. My application sound ducks fine to get out of the way of the audio alert, but the alarm app's audio alert does not sound.
Naturally, tons of support requests poured in over the iOS 5 change. I have solved this temporarily by setting kAudioSessionProperty_OverrideCategoryMixWithOthers
which lets the alarm audio come through, but there are a few very undesirable side-effects when doing this:
- Other app's audio can play with/over mine.
- The remote control events are not routed to my app, but to iPod.app.
None of the above drawbacks are acceptable for my app's requirements. I have been hacking away at this for some time now but haven't been able to crack it. How can I setup my audio such that:
- My app's audio still uses the
AVAudioSessionCategoryPlayback
category for background audio. - The Clock.app alarms still have their audio alerts make sound
- The app still responds to remote control notifications
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
写完这个问题后,我就提交了一份错误报告。我创建了一个小型 示例项目,我认为它可以复制该问题,但我无法复制它!这让我再次深入挖掘,试图找出这里发生了什么……
我启动了一个 iOS 警报,然后我在
audioPlayerBeginInterruption:
中放置了一个断点,并逐行跟踪我的代码在调试器中。我注意到在我的代码运行之前(当我在调试器中暂停时),iOS 5 警报响起了!幸运的是,即使当我单步执行我的应用程序时,它仍然听起来,所以我能够找出哪些代码片段专门导致它停止发声。我的中断处理程序的一部分是(显然)停止我的应用程序的内部音频以让中断通过。我以前从未想过检查这个方法,但结果发现问题就在那里。我的停止方法会在停止后立即调用
prepareToPlay
,以使下次恢复速度更快。docs 说明了
prepareToPlay
方法听起来很合理,而且这适用于较小的 iOS 版本。我的假设是, 一定对 Clock.app 闹钟系统进行了更改,以便新的闹钟声音使用硬件,而之前使用软件。我认为这就是导致 iOS 5 闹钟在某些应用程序中静音的原因。
删除
prepareToPlay
行会导致警报在不使用kAudioSessionProperty_OverrideCategoryMixWithOthers
的情况下响起,从而解决了我在这个问题中提出的所有问题。TL;DR
从
stop
声音代码逻辑中删除prepareToPlay
调用。稍后启动将花费一微秒的时间,但允许声音中断。After writing this question I went to file a bug report on this. I created a small sample project that I thought would replicate the issue, but I could not replicate it! This caused me to dig in deep once again and try to figure out what was up here…
I fired up an iOS alarm, then I placed a break point in
audioPlayerBeginInterruption:
and traced through my code line by line in the debugger. I noticed that before my code ran (while I was paused in the debugger), the iOS 5 alarm was sounding! Luckily it still sounded even as I was stepping through my app, so I was able to figure out which pieces of code specifically caused it to stop sounding.Part of my interruptionHandler is to (obviously) stop the internal audio of my app to let the interruption come through. I never thought to inspect this method before, but turns out the problem existed in there. My stop method would call
prepareToPlay
immediately after stopping to make resuming faster the next time.The docs state the
prepareToPlay
methodSounds reasonable, and this worked for lesser iOS versions. My hypothesis is that must have made a change to the Clock.app alarm system such that the new alarm sounds use the hardware, whereas before it used the software. This is what I think is causing the iOS 5 alarms to be silent in some apps.
Removing the
prepareToPlay
lines caused the alarm to sound without usingkAudioSessionProperty_OverrideCategoryMixWithOthers
, thus solving all my issues laid out in this question.TL;DR
Remove the
prepareToPlay
calls from yourstop
sound code logic. It will take a microsecond longer to start later, but will allow interruptions to sound.