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

Detect ring/silent switch position change

提问人:ravron 提问时间:6/10/2014 最后编辑:Communityravron 更新时间:6/11/2014 访问量:5273

问:

我正在开发一个应用程序,我想为它做:

  1. 播放音频时遵守响铃/静音开关,以及

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

要求 1 很简单:我使用 AVAudioSessionSoloAmbient 作为应用的音频会话类别,以便在响铃/静音开关关闭时,我的音频会话将自行静音。

要求 2 似乎要困难得多,因为我需要某种回调、通知或 KVO 来监控交换机的位置,但 Apple 已经明确表示,它不愿意提供官方公开的方式。也就是说,如果我能找到一种非侵入式方法来监控开关的位置,即使是技术上被禁止的(比如说,内部),我愿意由 Apple 运行它。NSNotification

此外,我宁愿不实施我在其他地方找到的一些轮询解决方案。有关示例,请参阅“相关问题”部分。


我学到了什么(又名什么不起作用)

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

  • AVSystemController 是一个内部类,似乎很有前途。调用确实会使我的应用程序的音频静音。此外,当通过音量按钮更改系统音量时,共享单例会发布通知。不幸的是,此通知并不是为了响应响铃/静音开关的更改而发布的(尽管这个可疑的消息来源说它应该这样做)。- (BOOL)toggleActiveCategoryMutedsharedAVSystemControllerAVSystemController_SystemVolumeDidChangeNotification

  • 据我所知,没有任何对象响应振铃/静音开关位置变化而发布的 s。在将自己添加为默认中心所有通知的观察者后,我得出了这个结论:NSNotification

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNotification:) name:nil object:nil];
    

    然后切换响铃/静音开关。无。

  • 该类有一个很有前途的方法,其签名为:AVSystemController

    - (BOOL)getActiveCategoryMuted:(BOOL*)arg1;
    

    但是,这有两个问题:

    1. 返回值和指向的 by 似乎都不会因切换振铃/静默开关而改变。BOOLarg1
    2. 由于方法签名,此方法(据我所知)不是 KVO 的候选者。

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

    kGSEventRingerOff = 1012,
    kGSEventRingerOn = 1013,
    

    但是,我很确定我无法拦截这些消息,即使我可以,那也不仅仅是“一点点”的侵入性。


为什么我相信这是可能的

简而言之:Instagram 应用程序本质上表现出这种行为。当您观看视频时,它会遵循响铃/静音开关的设置,但在开关关闭时会显示一个图标。该图标在移动开关后立即消失并重新出现,以至于我认为它必须是基于事件的,而不是轮询的。


相关问题

iOS iPhone 音频 AVAudioplayer iOS7.1

评论

0赞 Peter Robert 10/25/2014
你有没有找到任何基于事件的解决方案?
0赞 ravron 10/25/2014
@PeterRobert 不,我没有。我最终通过轮询仔细地实施了一个解决方案。它并不漂亮。
0赞 Avi 4/19/2016
据报道,Instagram使用了这个解决方案,这并不漂亮:sharkfood.com/content/Developers/content/Sound%20Switch
2赞 Mark 12/16/2016
上面的链接看起来已经死了。上面的代码托管在:github.com/moshegottlieb/SoundSwitch(通过 stackoverflow.com/questions/20992452/...)

答: 暂无答案