我正在开发一个我想要的应用程序:
在播放音频时尊重铃声/静音开关,
显示一个图标,表示当响铃/静音开关设置为静音时声音被静音。
要求1很简单:我使用AVAudioSessionSoloAmbient
作为我应用的音频会话类别,以便当响铃/静音开关关闭时,我的音频会话将自动静音。
要求2似乎相当困难,因为我需要某种回调,通知或KVO,这将允许我监控交换机的位置,但Apple明确表示它不愿意提供正式暴露的方式这样做。也就是说,如果我能找到一种非侵入性的方式来监控交换机的位置,即使是技术上被禁止的方式(例如,内部NSNotification
),我也愿意由Apple运行它。
此外,我宁愿不实施我在其他地方找到的一些民意调查解决方案。有关示例,请参阅“相关问题”部分。
至少在iOS版本4和5中,有一个技巧可用于通过watching the route property of the current audio session获取交换机的位置。除了被AVAudioSession
类弃用之外,我还可以确认这个技巧不再是一个选项。当切换振铃/静音开关时,包含已弃用的Audio Session
API和当前AVAudioSession
类的C函数报告的当前路由不会更改。
AVSystemController
is an internal class似乎有很多希望。在- (BOOL)toggleActiveCategoryMuted
上调用sharedAVSystemController
确实会使我应用的音频静音。此外,当通过音量按钮更改系统音量时,共享单例会发布AVSystemController_SystemVolumeDidChangeNotification
通知。遗憾的是,此通知未发布以响应对响铃/静音开关的更改(尽管this dubiously attributed source says it should)。
据我所知,任何对象发布 no NSNotification
以响应响铃/静音开关位置的变化。在将自己添加为默认中心的所有通知的观察者后,我得出了这个结论:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNotification:) name:nil object:nil];
然后切换响铃/静音开关。什么都没有。
AVSystemController
类有一个很有前途的签名方法:
- (BOOL)getActiveCategoryMuted:(BOOL*)arg1;
然而,这有两个问题:
BOOL
指向的返回值和arg1
似乎都没有响应切换响铃/静音开关而改变。的
我怀疑某个对象在更改静音开关时会发送一些其他对象GSEventRef
,因为我在事件类型声明中看到以下内容:
kGSEventRingerOff = 1012,
kGSEventRingerOn = 1013,
然而,我非常确定我无法拦截这些消息,即使我可以,也可能会超过"一点点"侵入性的。
简单地说:Instagram应用程序基本上表现出这种行为。观看视频时,它会考虑铃声/静音开关的设置,但在开关关闭时会显示一个图标。图标消失并在移动开关后立即重新出现,我认为它必须是基于事件的,而不是轮询。