检测iOS设备上的活动AVAudioSessions

我想弄清楚这是否可能 – 我的应用程序激活一个audio会话,初始化为:

[[[AVAudioSession alloc] init] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:&error]; 

我希望能够理解何时来自另一个应用程序或操作系统的附加audio会话正在播放。

我知道实现委托方法beginInterruption:endInterruption的能力,但是由于我使用的是AVAudioSessionCategoryOptionMixWithOthers选项,所以不会被调用。

有没有办法实现这一点,而不使用私人API?

提前致谢。

iOS 6.0开始 ,pipe理应用程序audio会话的方式已经发生了一些重大变化,首先应该简单地提一下。 在iOS 6.0之前,您将使用AVAudioSessionAudioSessionServices类,分别包含委派和属性侦听。 从iOS 6.0开始,使用AVAudioSession类并合并通知。

以下是iOS 6.0以上的版本。

要知道应用程序沙箱外的其他audio是否正在播放使用 –

 // query if other audio is playing BOOL isPlayingWithOthers = [[AVAudioSession sharedInstance] isOtherAudioPlaying]; // test it with... (isPlayingWithOthers) ? NSLog(@"other audio is playing") : NSLog(@"no other audio is playing"); 

至于中断处理,你需要观察AVAudioSessionInterruptionNotificationAVAudioSessionRouteChangeNotification 。 因此,在pipe理audio会话的类中,可以使用类似于以下内容的类 – 在应用程序生命周期开始时应该调用一次,并且不要忘记在同一个类的dealloc方法中删除观察者。

 // ensure we already have a singleton object [AVAudioSession sharedInstance]; // register for notifications [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(interruption:) name:AVAudioSessionInterruptionNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(routeChange:) name:AVAudioSessionRouteChangeNotification object:nil]; 

最后添加下面的select器interruption:routeChange: – 这些将会收到一个NSNotification对象,该对象具有一个名为userInfo的NSDictionarytypes的属性,您可以阅读该对象来协助您的应用程序具有的任何条件。

 - (void)interruption:(NSNotification*)notification { // get the user info dictionary NSDictionary *interuptionDict = notification.userInfo; // get the AVAudioSessionInterruptionTypeKey enum from the dictionary NSInteger interuptionType = [[interuptionDict valueForKey:AVAudioSessionInterruptionTypeKey] integerValue]; // decide what to do based on interruption type here... switch (interuptionType) { case AVAudioSessionInterruptionTypeBegan: NSLog(@"Audio Session Interruption case started."); // fork to handling method here... // EG:[self handleInterruptionStarted]; break; case AVAudioSessionInterruptionTypeEnded: NSLog(@"Audio Session Interruption case ended."); // fork to handling method here... // EG:[self handleInterruptionEnded]; break; default: NSLog(@"Audio Session Interruption Notification case default."); break; } } 

同样…

 - (void)routeChange:(NSNotification*)notification { NSDictionary *interuptionDict = notification.userInfo; NSInteger routeChangeReason = [[interuptionDict valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue]; switch (routeChangeReason) { case AVAudioSessionRouteChangeReasonUnknown: NSLog(@"routeChangeReason : AVAudioSessionRouteChangeReasonUnknown"); break; case AVAudioSessionRouteChangeReasonNewDeviceAvailable: // a headset was added or removed NSLog(@"routeChangeReason : AVAudioSessionRouteChangeReasonNewDeviceAvailable"); break; case AVAudioSessionRouteChangeReasonOldDeviceUnavailable: // a headset was added or removed NSLog(@"routeChangeReason : AVAudioSessionRouteChangeReasonOldDeviceUnavailable"); break; case AVAudioSessionRouteChangeReasonCategoryChange: // called at start - also when other audio wants to play NSLog(@"routeChangeReason : AVAudioSessionRouteChangeReasonCategoryChange");//AVAudioSessionRouteChangeReasonCategoryChange break; case AVAudioSessionRouteChangeReasonOverride: NSLog(@"routeChangeReason : AVAudioSessionRouteChangeReasonOverride"); break; case AVAudioSessionRouteChangeReasonWakeFromSleep: NSLog(@"routeChangeReason : AVAudioSessionRouteChangeReasonWakeFromSleep"); break; case AVAudioSessionRouteChangeReasonNoSuitableRouteForCategory: NSLog(@"routeChangeReason : AVAudioSessionRouteChangeReasonNoSuitableRouteForCategory"); break; default: break; } } 

只要您在应用程序生命周期开始时检查应用程序audio会话的状态,例如在根视图控制器的viewDidLoad ,就不需要轮询任何内容。 通过这两个主要通知可以知道从那里开始到应用程序audio会话的任何更改。 根据交换机中包含的情况,将NSLog语句replace为您的代码需要执行的操作。

您可以在AVAudioSession类参考文档中find有关AVAudioSessionInterruptionTypeKeyAVAudioSessionRouteChangeReasonKey更多信息。

我对长时间的答复表示歉意,但我认为iOS中的audio会话pipe理相当复杂,而在撰写本文时,Apple的audio会话编程指南不包括使用中断处理通知的代码示例。

您可以检查其他audio是否正在播放,如下所示:

 UInt32 otherAudioIsPlaying; UInt32 propertySize = sizeof (otherAudioIsPlaying); AudioSessionGetProperty (kAudioSessionProperty_OtherAudioIsPlaying, &propertySize, &otherAudioIsPlaying ); [self handleIfAudioIsPlaying: otherAudioIsPlaying]; 

然后你可以添加一个循环,并检查每一个X秒,如果有什么改变。