16

我目前正在尝试的是在应用程序在后台(或可能从挂起状态唤醒)收到远程通知时播放消息。

应用程序从挂起模式唤醒后根本不播放声音。

didReceiveRemoteNotification:当应用程序在前台时,调用方法后立即播放声音。

didReceiveRemoteNotification:当应用程序从挂起模式唤醒时调用方法时立即播放声音的合适方法是什么?

这是一些代码(语音管理器类):

-(void)textToSpeechWithMessage:(NSString*)message andLanguageCode:(NSString*)languageCode{

AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *error = nil;
DLog(@"Activating audio session");
if (![audioSession setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker | AVAudioSessionCategoryOptionMixWithOthers error:&error]) {
    DLog(@"Unable to set audio session category: %@", error);
}
BOOL result = [audioSession setActive:YES error:&error];
if (!result) {
    DLog(@"Error activating audio session: %@", error);

}else{
    AVSpeechUtterance *utterance = [AVSpeechUtterance speechUtteranceWithString:message];

    [utterance setRate:0.5f];

    [utterance setVolume:0.8f];

    utterance.voice = [AVSpeechSynthesisVoice voiceWithLanguage:languageCode];

    [self.synthesizer speakUtterance:utterance];
}

}

-(void)textToSpeechWithMessage:(NSString*)message{

[self textToSpeechWithMessage:message andLanguageCode:[[NSLocale preferredLanguages] objectAtIndex:0]];

}

后来在AppDelegate

[[MCSpeechManager sharedInstance] textToSpeechWithMessage:messageText];

我在 Capabilities->Background Modes 部分启用了音频、AirPlay 和画中画选项。

编辑:

如果需要,也许我应该启动一个后台任务并运行过期处理程序?我想这可能有效,但我也想听听解决这种情况的常用方法。

同样使用此代码,当我在后台收到通知时,我会收到下一个错误:

激活音频会话时出错:Error Domain=NSOSStatusErrorDomain Code=561015905 "(null)"

代码 561015905 适用于:

AVAudioSessionErrorCodeCannotStartPlaying = '!pla', /* 0x21706C61, 561015905

它被描述为:

如果应用程序的信息属性列表不允许使用音频,或者应用程序在后台并使用不允许背景音频的类别,则可能会出现此错误类型。

但我在其他类别(AVAudioSessionCategoryAmbientAVAudioSessionCategorySoloAmbient)中遇到同样的错误

4

2 回答 2

5

由于我无法重现您所描述的错误,让我提供一些指针和一些代码。

  • 您是否正在针对最新的 SDK 构建/测试/运行?iOS X 中的通知机制发生了重大变化
  • 我必须假设调用didReceiveRemoteNotification必须响应来自所述通知的用户操作,例如点击通知消息。
  • 无需设置任何后台模式保存应用程序下载内容以响应推送通知

如果上述所有陈述都是正确的,那么当前的答案将集中在通知到达时会发生什么。

  1. 设备收到通知
    偏僻的
  2. 用户点击消息
  3. 应用程序启动
  4. didReceiveRemoteNotification被调用

在第 4 步,textToSpeechWithMessage按预期工作:

func application(_ application: UIApplication,
                 didReceiveRemoteNotification
                 userInfo: [AnyHashable : Any],
                 fetchCompletionHandler completionHandler:
                 @escaping (UIBackgroundFetchResult) -> Void) {
    textToSpeechWithMessage(message: "Speak up", "en-US")
}

为简单起见,我使用OneSignal连接通知:

import OneSignal
...
_ = OneSignal.init(launchOptions: launchOptions,
                   appId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")
// or
_ = OneSignal.init(launchOptions: launchOptions,
                   appId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")
                   {
                       (s:String?, t:[AnyHashable : Any]?, u:Bool) in
                       self.textToSpeechWithMessage(message: "OneDignal", "en-US")
                   }

textToSpeechWithMessage大部分未受影响,为了完整起见,它在Swift 3中:

import AVFoundation
...
let synthesizer = AVSpeechSynthesizer()
func textToSpeechWithMessage(message:String, _ languageCode:String)
{
    let audioSession = AVAudioSession.sharedInstance()

    print("Activating audio session")
    do {
        try audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord,
                                     with: [AVAudioSessionCategoryOptions.defaultToSpeaker,
                                            AVAudioSessionCategoryOptions.mixWithOthers]
        )
        try audioSession.setActive(true)

        let utterance = AVSpeechUtterance(string:message)
        utterance.rate = 0.5
        utterance.volume = 0.8
        utterance.voice = AVSpeechSynthesisVoice(language: languageCode)
        self.synthesizer.speak(utterance)

    } catch {
        print("Unable to set audio session category: %@", error);
    }
}
于 2017-01-04T01:47:50.180 回答
0

请执行

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler; 

方法。您将在后台获得回调以播放音频。

于 2017-01-17T06:20:42.147 回答