收到远程通知后,如何让我的声音播放?

时间:2014-08-16 22:00:16

标签: ios objective-c ios7 core-audio avaudioplayer

我在收到远程通知时尝试自动播放声音文件(不属于我的应用包并且不是通知声音)。我希望在接收到通知时应用程序是在前台还是后台。

我使用Amazing Audio Engine作为核心音频库的包装。在我的应用代表didReceiveRemoteNotification中,我创建了一个音频控制器并向其添加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

表示如果应用程序的“信息”属性列表不允许使用音频,或者应用程序位于后台且使用不允许背景音频的类别,则会出现此错误类型。

但我的plist包含音频作为后台模式,我的音频会话类别是AVAudioSessionCategoryPlayback,我的类别选项设置为AVAudioSessionCategoryOptionMixWithOthers。

收到远程通知后,如何让我的声音播放?

2 个答案:

答案 0 :(得分:4)

您无法在后台激活音频会话,也无法在后台启动声音播放。背景音频只是意味着您可以保持在应用进入后台时播放 ;但是一旦你的背景声音被打断,或者当你进入后台时你的应用没有播放,你就无法发出声音。

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

通常情况是要到达前台或向系统发送有声音的即时本地通知。

答案 1 :(得分:4)

如果您致电AVAudioSession:setActive:error:AVAudioSession:setCatagory:withOptions:error:并在进入后台之前创建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/>),那么当它收到&#34; Notification&#34; (本地或远程)你已经激活AVAudioSession,就像上面的代码一样,无论应用程序是设置为静音还是振动模式,它都会在通知有效负载中播放声音,这实际上是 警报做到了。当然,如果您需要轮询服务器以响应远程通知,这将不起作用。 See here.