检测振铃/静音开关位置变化

rav*_*ron 12 iphone audio avaudioplayer ios ios7.1

我正在开发一个我想要的应用程序:

  1. 在播放音频时尊重铃声/静音开关,和

  2. 当铃声/静音开关设置为静音时,显示一个图标,表示声音已静音.

要求1很简单:我使用的AVAudioSessionSoloAmbient是我的应用程序的音频会话类别,因此当响铃/静音开关关闭时,我的音频会话将自动静音.

要求2似乎相当困难,因为我需要某种回调,通知或KVO,这将允许我监控交换机的位置,但Apple明确表示它不愿意提供正式公开的方式来做到这一点.也就是说,如果我能找到一种非侵入性的方式来监控交换机的位置,即使是技术上被禁止的方式(例如内部NSNotification),我也愿意由Apple运行它.

此外,我宁愿不实施我在别处找到的一些民意调查解决方案.有关示例,请参阅"相关问题"部分.


我学到了什么(又名什么不行)

  • 至少在iOS版本4和5中,有一个技巧可以通过观察当前音频会话的路由属性来获取交换机的位置.除了被AVAudioSession班级弃用之外,我还可以确认这个技巧不再是一个选择.当切换振铃/静音开关时,当前路由(包括已弃用的Audio SessionAPI和当前AVAudioSession类的C函数报告)都不会更改.

  • AVSystemController是一个似乎有很多承诺的内部类.调用确实- (BOOL)toggleActiveCategoryMuted会使sharedAVSystemController我的应用程序的音频静音.此外,共享单例AVSystemController_SystemVolumeDidChangeNotification在通过音量按钮更改系统音量时发布通知.不幸的是,这个通知不是为响应环/静音开关的变化而发布的(尽管这个可疑的来源说它应该).

  • 据我所知,有没有 NSNotification š张贴由任何对象响应于环/无声开关位置的变化.在将自己添加为默认中心中所有通知的观察者后,我得出了这个结论:

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNotification:) name:nil object:nil];
    
    Run Code Online (Sandbox Code Playgroud)

    然后切换响铃/静音开关.没有.

  • AVSystemController课程有一个很有前途的签名方法:

    - (BOOL)getActiveCategoryMuted:(BOOL*)arg1;
    
    Run Code Online (Sandbox Code Playgroud)

    但是,这有两个问题:

    1. 响应于切换振铃/静音开关,返回值和BOOL指向的值arg1似乎都没有变化.
    2. 由于方法签名,这种方法(据我所知)并不是KVO的候选者.

  • 我怀疑某个对象GSEventRef在更改静音开关时会发送一些其他对象,因为我在事件类型的声明中看到以下内容:

    kGSEventRingerOff = 1012,
    kGSEventRingerOn = 1013,
    
    Run Code Online (Sandbox Code Playgroud)

    但是,我很确定我无法拦截这些消息,即使我可以,这也不仅仅是"一点点"的干扰.


为什么我相信这是可能的

简单地说:Instagram应用程序基本上表现出这种行为.观看视频时,它会考虑铃声/静音开关的设置,但在开关关闭时会显示一个图标.图标消失并在移动开关后立即重新出现,我认为它必须是基于事件的,而不是轮询.


相关问题