【问题标题】:How to detect iphone is on silent mode如何检测iphone是否处于静音模式
【发布时间】:2010-10-24 09:57:38
【问题描述】:

我正在开发一个应用程序。在那我想通过编码检测“iPhone是否处于静音模式?”。我正在使用可可和 Objective-C 来开发它。

如果有人知道,请回复。

【问题讨论】:

    标签: ios objective-c iphone cocoa-touch audio


    【解决方案1】:

    Pirrpli的代码不起作用的原因是模拟器不支持测试,代码不检查错误。更正后的代码如下所示:

    CFStringRef state = nil;
    UInt32 propertySize = sizeof(CFStringRef);
    AudioSessionInitialize(NULL, NULL, NULL, NULL);
    OSStatus status = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &state);
    
    if (status == kAudioSessionNoError)
    {
        return (CFStringGetLength(state) == 0);   // YES = silent
    }
    return NO;
    

    【讨论】:

    • 不适用于 iPhone 4 iOS 5 :( .. state = "speaker",我认为
    • 正确,在 iOS 5 上不起作用,事实证明 Apple 从未打算以这种方式使用它。我的应用不再尝试找出静音开关的状态。该应用程序输出音频,如果用户打开静音开关,则音频不会响起。该应用程序还具有振动偏好,如果用户打开了它,那么该应用程序除了音频之外还会振动。所以用户拥有完全的控制权,app不需要知道开关的状态。
    • @Neil,您说您的应用“不再尝试找出静音开关的状态”,而是“如果用户打开了静音开关,则音频不会响起”。这不是说你在监控静音开关吗?您使用的是哪个(或多个)类别?
    • @ari gold,我不监控静音开关。如果用户打开了静音,则没有声音出现,如果关闭,我的应用不在乎。
    【解决方案2】:

    可以通过使用 AudioToolBox 测试 NULL 音频路由:

    UInt32 routeSize = sizeof (CFStringRef);
    CFStringRef route;
    
    AudioSessionGetProperty (
                             kAudioSessionProperty_AudioRoute,
                             &routeSize,
                             &route
                            );
    
    if (route == NULL) {
        NSLog(@"Silent switch is on");
    }
    

    如果 route 为 NULL,则没有可用的音频输出。如果它是“耳机”或“耳机”,那么静音铃声开关仍可以打开。但是,当它设置为“扬声器”时,它永远不会开启。

    您最好在音频路由更改属性侦听器中对此进行测试,该侦听器设置如下:

    AudioSessionAddPropertyListener (
                                     kAudioSessionProperty_AudioRouteChange,
                                     audioRouteChangeListenerCallback,
                                     self
                                     );
    

    注意:如果你正在做一些时髦的事情,比如覆盖音频路由,那么这个答案可能不适用。

    完全设置和拆除音频会话可能超出了此答案的范围。

    【讨论】:

    • 非常感谢你。我会检查并通知您。
    • 它不工作 AudioSessionAddPropertyListener 在 ios-7 中也已弃用
    【解决方案3】:

    为了完整起见,基于 Dan Bon 的 this link,我在我的应用程序中实现了以下方法来解决这个问题。需要注意的一点是代码首先检查 iPhone 模拟器 - 执行以下代码会使模拟器崩溃。有人知道为什么吗?

    -(BOOL)silenced {
         #if TARGET_IPHONE_SIMULATOR
             // return NO in simulator. Code causes crashes for some reason.
         return NO;
         #endif
    
        CFStringRef state;
        UInt32 propertySize = sizeof(CFStringRef);
        AudioSessionInitialize(NULL, NULL, NULL, NULL);
        AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &state);
        if(CFStringGetLength(state) > 0)
            return NO;
        else
            return YES;
    
    }
    

    在视图控制器中声明此权限,您只需检查

    if ([self silenced]) {
         NSLog(@"silenced");
    
    else {
         NSLog(@"not silenced");
    }
    

    或者,很明显,您可以在某种辅助类中声明它。更优雅的解决方案可能是在 UIApplication 或其他类似的类上添加类别...

    【讨论】:

    • AudioSessionGetProperty 现在已弃用。有 [AVAudioSession sharedInstance].currentRoute 来获取 currentRoute,但即使使用 AVAudioSessionCategoryAmbient 也不允许获取硬件静音开关的状态。
    【解决方案4】:

    您可以按照先前答案的建议使用 Audio Route 属性,但请记住: - 仅当音频类别为 AmbientSound 时才有效 - 您不应在您的应用程序中多次初始化音频会话(请参阅音频会话编程指南) - 你应该释放那些 CFStringRef 以避免内存泄漏

    如果当前的音频类别不是 AmbientSound,可以考虑暂时改变它,检查 Audio Route 属性,然后恢复原来的音频类别。

    请注意,在给定当前硬件配置(即是否插入耳机等)的情况下,更改音频类别将恢复该类别的默认音频路由。

    【讨论】:

      猜你喜欢
      • 2012-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多