Linphone Android 早期媒体断连后下一通通话接通自动进入暂停状态
Linphone Android 外呼接通后自动暂停异常修复
问题基础信息
- 集成基线:基于Linphone官方Android Kotlin外呼示例实现通话能力,使用SDK版本为
org.linphone:linphone-sdk-android:5.1.36 - 复现规则:必须按顺序执行以下操作才会触发异常,杀死应用重启后通话功能恢复正常
- 场景1:拨打不可达号码,触发早期媒体(Early Media)播放运营商提示音(如“您拨打的号码暂时无法接通”)后通话断连,对应状态回调链路:
OutgoingInit->OutgoingProgress->OutgoingEarlyMedia->End - 场景2:前序通话结束后拨打正常可用号码,对端可正常收到来电,接听后仅播放等待提示音,通话双方无法听到实时语音,对应完整状态回调链路:
OutgoingInit->OutgoingProgress->OutgoingEarlyMedia->Connected->StreamsRunning->Pausing->Paused
- 场景1:拨打不可达号码,触发早期媒体(Early Media)播放运营商提示音(如“您拨打的号码暂时无法接通”)后通话断连,对应状态回调链路:
问题根因
该问题为Linphone 5.1.x系列SDK的状态机残留缺陷:第一次Early Media场景的通话释放时,SDK内部的通话暂停标记、音频会话状态没有随通话实例销毁完全重置,第二次通话建立媒体流后,SDK会错误读取残留的暂停标记,主动触发通话暂停流程。
修复方案
- 监听通话
Call.State.End状态回调,在每次通话结束时强制清空SDK残留状态:// 通话结束触发时执行以下逻辑 val core = LinphoneManager.getCore() // 替换为项目中获取Linphone Core实例的方法 // 清空所有残留通话的暂停状态 core.calls.forEach { call -> if (call.state in listOf(Call.State.Paused, Call.State.Pausing)) { call.resume() } } // 强制重置音频路由与采集状态 core.reloadSoundDevices() core.enableMic(true) // 替换为业务默认的音频路由,比如听筒为AudioRoute.RouteEarpiece core.configureAudioRoute(AudioRoute.RouteEarpiece) - 通话状态回调中增加异常兜底逻辑,在通话进入
StreamsRunning状态后做二次校验,发现异常暂停主动恢复:override fun onCallStateChanged(core: Core, call: Call, state: Call.State, message: String) { // 其他原有状态处理逻辑 if (state == Call.State.StreamsRunning) { // 延迟100ms校验,规避状态回调时序差问题 Handler(Looper.getMainLooper()).postDelayed({ if (call.state in listOf(Call.State.Paused, Call.State.Pausing)) { call.resume() } }, 100) } } - 版本兼容方案:如果代码层面修复后仍有偶现,可将SDK升级至
5.2.0+版本,官方已在该版本分支修复Early Media场景下的状态机残留问题,不建议直接升级6.x版本,该大版本API变更较多,适配成本较高。
注意:不要在
OutgoingEarlyMedia状态下主动调用麦克风静音、通话暂停类接口,否则会提升状态标记残留的触发概率。
内容的提问来源于stack exchange,提问作者Parth
相关产品推荐
相关产品推荐

