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

Posted

技术标签:

【中文标题】收到远程通知时如何播放声音?【英文标题】:How do I get my sound to play when a remote notification is received? 【发布时间】:2014-08-16 22:00:15 【问题描述】:

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

我使用 Amazing Audio Engine 作为核心音频库的包装器。在我的 App Delegate 的 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。

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

【问题讨论】:

【参考方案1】:

如果您调用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/>),当它收到“通知”(本地或远程)并且您已激活 AVAudioSession 时,如上面的代码,无论应用程序设置为静音还是振动模式,它都会在通知负载中播放声音,这实际上是警报的方式。当然,如果您需要轮询服务器以响应远程通知,这将不起作用。 See here.

【讨论】:

【参考方案2】:

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

这是有道理的,因为如果用户没有使用甚至可能没有意识到的应用程序可能会突然开始发出噪音,那将是可怕的。

通常的做法是要么进入前台,要么立即向系统发送带有声音的本地通知。

【讨论】:

明白了,这很有道理。当您说“来到前台或立即发送本地通知”时,您能否澄清您的意思。我认为这些路线都不允许我自动播放。这是真的吗? 如果用户没有拒绝此权限,系统将为您播放本地通知声音。这是您在后台可以做的最好的事情。这就是定时器和警报应用程序的工作方式。如果您可以让用户通过将您带到前台来响应本地通知,那么您现在可以做任何您喜欢的事情。 这不是真的:Tile.app 似乎可以做到这一点,许多其他应用程序也是如此。请在下面查看我的答案。 这个答案不正确。现实情况是,后台应用程序无法启动不与前台应用程序的音频会话混合的音频会话,因为这会中断用户当前使用的应用程序的音频。但是您只能使用类别选项在后台激活音频会话:MixWithOthers 或 DuckOthers(这是一种混合方法)。混合类别不需要中断其他应用的音频会话。 很明显,播放音频背景是可能的,因为 GPS 应用正在这样做。

以上是关于收到远程通知时如何播放声音?的主要内容,如果未能解决你的问题,请参考以下文章

远程通知音量级别与应用程序中播放的声音不同

远程通知中的自定义声音 iOS 10,swift 3

iOS 无法为远程通知播放自定义声音

用户收到推送通知时如何播放自定义声音文件? [复制]

配置收到推送通知时播放的声音

APN 自定义通知声音问题