3.17版本IOS游戏中接电话后会卡主怎么解决

如果卡住后 切下后台回来就好了 这个是什么问题 有遇到过吗

我也遇到这个问题,具体表现为游戏在前台,电话接入,几秒后主动拒绝来电,自动回到游戏并卡死。

根据调试log,原因是AudioEngine内部主动调用了Director::getInstance()->pause();
官方解释在https://forum.cocos.org/t/1-5-1-cc-audioengine/51019和https://forum.cocos.org/t/1-6-0-beta3/49414可以参考。

主要原因是来电接入会触发IOS的音频中断开始通知AVAudioSessionInterruptionTypeBegan,使当前游戏音频处于非激活状态,而当来电结束后游戏回到前台,理论上会收到音频中断结束通知AVAudioSessionInterruptionTypeEnded,当前游戏音频重新激活,正常恢复游戏。
当问题是,IOS这个AVAudioSessionInterruptionTypeEnded经常收不到,导致cocos判断游戏音频还未激活,主动暂停了游戏,我尝试过注释了pause代码,结果就是完全没有声音,log报各种openAL 0xa003的错误。
不知道算不算IOS系统本身的bug,希望官方能提供一个解决方案吧。

表现跟你类似,但不是电话接入,我这边出现该问题是iPhone X 在 iOS 15 上从前台切换到后台,再从后台切回来时,只收到了AVAudioSessionInterruptionTypeBegan事件,没有收到AVAudioSessionInterruptionTypeEnded事件导致游戏被pause,不清楚是不是iOS 15的bug,但在iOS 15以下就没有出现该问题,查阅了很多文档,发现一个iOS 10.3新增的key(AVAudioSessionInterruptionReasonAppWasSuspended),苹果的解释是从 iOS 10开始,前台切后台再切前台,就会有这么一个key(只在AVAudioSessionInterruptionTypeBegan事件中出现,值为true表示中断是由于系统挂起应用程序,而不是被另一个音频会话中断),所以针对这种情况(只收到AVAudioSessionInterruptionTypeBegan事件),我对AudioEngine-inl.mm的handleInterruption函数做了一些修改发现这个问题被解决了,代码如下(注释区域内是我新加的,因为AVAudioSessionInterruptionReasonAppWasSuspended在iOS 14.5以上被标记为已弃用,所以换了新的API):

static bool isAudioSessionInterrupted = false;
static bool resumeOnBecomingActive = false;
static bool pauseOnResignActive = false;
if ([notification.name isEqualToString:AVAudioSessionInterruptionNotification])
{
    // ------新加的代码------
    if (@available(iOS 14.5, *)) {
        NSInteger _reason = [[[notification userInfo] objectForKey:AVAudioSessionInterruptionReasonKey] integerValue];
        if (_reason == AVAudioSessionInterruptionReasonAppWasSuspended){
            ALOGD("AVAudioSessionInterruptionReasonAppWasSuspended");
            return;
        }
    } else if (@available(iOS 10.3, *)) {
        BOOL isSuspend = [[[notification userInfo] objectForKey:AVAudioSessionInterruptionWasSuspendedKey] boolValue];
        if (isSuspend) {
            ALOGD("AVAudioSessionInterruptionWasSuspendedKey");
            return;
        }
    }
    // ------新加的代码------
    NSInteger reason = [[[notification userInfo] objectForKey:AVAudioSessionInterruptionTypeKey] integerValue];

参考链接如下:
https://developer.apple.com/documentation/avfaudio/avaudiosession/1616596-interruptionnotification
https://developer.apple.com/documentation/avfaudio/avaudiosessioninterruptionwassuspendedkey
https://blog.csdn.net/shengpeng3344/article/details/83617979

3赞