Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/116.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 收到远程通知时,如何播放声音?_Ios_Objective C_Ios7_Core Audio_Avaudioplayer - Fatal编程技术网

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

Ios 收到远程通知时,如何播放声音?,ios,objective-c,ios7,core-audio,avaudioplayer,Ios,Objective C,Ios7,Core Audio,Avaudioplayer,我正在尝试在收到远程通知时自动播放声音文件(它不是我的应用程序包的一部分,也不是通知声音)。我希望在收到通知时,无论应用程序位于前台还是后台,都会发生这种情况 我使用惊人的音频引擎作为核心音频库的包装器。在我的应用程序代理的didReceiveMemotentification中,我创建了一个音频控制器,并向其添加AEAudioFilePlayer,如下所示: NSURL *file = [NSURL fileURLWithPath:sourceFilePath]; AEAu

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

我使用惊人的音频引擎作为核心音频库的包装器。在我的应用程序代理的
didReceiveMemotentification
中,我创建了一个音频控制器,并向其添加
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>)
2014-08-18 06:21:28.003 MyApp[394:60b]TAAE:将音频会话类别设置为AVAudioSessionCategoryPlayback
2014-08-18 06:21:28.019 MyApp[394:60b]无法激活音频会话:错误域=NSOSStatusErrorDomain代码=561015905“操作无法完成。(OSStatus错误561015905)。”
2014-08-18 06:21:28.024 MyApp[394:60b]TAAE:音频会话已初始化(音频路由'

这表示如果应用程序的信息属性列表不允许使用音频,或者如果应用程序位于后台且使用的类别不允许使用背景音频,则可能发生此错误类型

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


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

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

这是有道理的,因为如果用户没有使用,甚至可能没有意识到的应用程序可能会突然发出噪音,那就太糟糕了


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

如果您在进入后台之前调用
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:
UIApplicationExitsOnSuspend

),当它收到“通知”(本地或远程)时您已经激活了一个音频会话,就像上面的代码一样,它将在通知负载中播放声音,无论应用程序是否设置为静默或振动模式,这实际上是报警的方式。当然,如果您需要轮询服务器以响应远程通知,这将不起作用。

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