如何收到远程通知时播放声音?

我试图在接收到远程通知时自动播放声音文件(这不是我的应用程序包的一部分,不是通知声音)。 当收到通知时,无论应用程序处于前台还是后台,我都希望发生这种情况。

我使用惊人的audio引擎作为核心audio库的包装。 在我的App Delegate的AEAudioFilePlayer ,我创build了一个audio控制器并将AEAudioFilePlayer添加到它,如下所示:

  NSURL *file = [NSURL fileURLWithPath:sourceFilePath]; AEAudioFilePlayer *notificationPlayer = [AEAudioFilePlayer audioFilePlayerWithURL:file audioController:_notificationController error:NULL]; notificationPlayer.completionBlock = ^{ // Remove self from channel list after playback is complete [_notificationController removeChannels:[NSArray arrayWithObjects:notificationPlayer,nil]] ; }; [_notificationController addChannels:[NSArray arrayWithObjects:notificationPlayer,nil]]; 

但是,声音不起作用! 我的日志显示以下错误:

  2014-08-18 06:21:28.003 MyApp[394:60b] TAAE: Setting audio session category to AVAudioSessionCategoryPlayback 2014-08-18 06:21:28.019 MyApp[394:60b] Couldn't activate audio session: Error Domain=NSOSStatusErrorDomain Code=561015905 "The operation couldn't be completed. (OSStatus error 561015905.)" 2014-08-18 06:21:28.024 MyApp[394:60b] TAAE: Audio session initialized (audio route '<AVAudioSessionRouteDescription: 0x178006720, inputs = (null); outputs = ( "<AVAudioSessionPortDescription: 0x1780067f0, type = Speaker; name = Speaker; UID = Speaker; selectedDataSource = (null)>" )>') 2014-08-18 06:21:28.034 MyApp[394:60b] 06:21:28.033 ERROR: [0x1938e42a0] >aurioc> 783: failed: '!pla' (enable 2, outf< 2 ch, 44100 Hz, Int16, non-inter> inf< 2 ch, 0 Hz, Float32, non-inter>) 2014-08-18 06:21:28.037 MyApp[394:60b] 06:21:28.037 ERROR: [0x1938e42a0] >aurioc> 783: failed: '!pla' (enable 2, outf< 2 ch, 44100 Hz, Int16, non-inter> inf< 2 ch, 0 Hz, Float32, non-inter>) 

查找!pla错误,我发现这个参考: https : //developer.apple.com/library/ios/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/Reference/Reference.html

这表明如果应用程序的信息属性列表不允许使用audio,或者如果应用程序在后台并使用不允许背景audio的类别,则可能发生此错误types。

但我的plist包含audio作为背景模式,我的audio会话类别是AVAudioSessionCategoryPlayback,我的类别选项设置为AVAudioSessionCategoryOptionMixWithOthers。

如何收到远程通知时播放声音?

您不能在后台激活audio会话,并且无法在后台启动声音播放。 背景audio仅仅意味着您可以在应用程序进入后台时 继续播放; 但是一旦你的背景声音被打断了,或者当你进入后台时你的应用程序没有播放,你就没有能力发出声音。

这是有道理的,因为如果用户没有使用的应用程序,甚至可能不知道的应用程序可能会开始制造噪音。

通常情况下,要么到达前台,要么向系统提交一个有声音的即时本地通知。

如果你调用AVAudioSession:setActive:error:AVAudioSession:setCatagory:withOptions:error:进入后台之前创build你的AVPlayer,然后你可以播放你的声音。 例如:

  // Make sure this is run BEFORE entering background. [[AVAudioSession sharedInstance] setActive:YES error:&error]; if(error != nil){ NSLog(@"ERROR: %@", error.localizedDescription); } else { [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:&error]; if(error != nil){ NSLog(@"ERROR: %@", error.localizedDescription); } else { self._player = [[AVAudioPlayer alloc] initWithContentsOfURL:self.urlOfFileToPlay error:&error]; if(error != nil){ [[AVAudioSession sharedInstance] setActive:NO error:&error]; NSLog(@"ERROR: %@", error.localizedDescription); } } } //You can then do this in application:didReceiveRemoteNotification:fetchCompletionHandler: [backgroundPlayer.player play]; 

当然,我假设你已经有背景模式的能力设置为后台提取和远程通知。

我也会警告,如果你调用AVAudioSession:setActive:error:太早,其他的应用程序可能会改变你的东西。

此外,如果您将应用程序设置为不在后台运行(Info.plist: <key>UIApplicationExitsOnSuspend</key> <true/> ),那么当它接收到“通知”(本地或远程)并且已激活AVAudioSession ,就像上面的代码一样,无论应用程序设置为静音模式还是振动模式,它都会播放通知有效负载中的声音, 实际上这是如何进行报警的。 当然,如果您需要轮询服务器以响应远程通知,这将不起作用。 看这里。