我有一个单一的活动应用程序设置为使用自我管理的连接服务,因为我们正在使用音频和视频并且希望能够利用该系统。但是,我们关闭连接或更改音频流的方式导致了一个问题,我将在此处尽我所能描述。
当我开始我们的应用程序的呼叫时,一切都按照我们想要的方式工作,它从免提电话开始,但对免提电话按钮的按钮反应很好,而且音频效果很好!但是,当通话结束时,我的手机卡在了一种模式,即任何通知都不会通过扬声器播放,而是通过听筒播放,这意味着我的所有通知都相当安静。我相信这是因为我们没有正确重置音频流。我不确定这是否意味着在 Connection 对象的 destroy() 中发生,或者在我们请求音频焦点等的 Activity 中发生......下面是我认为是罪魁祸首的代码
此方法初始化音频是从单个 Activity 的 onResume() 调用的。我们根据用户设备的 Build 版本走两条不同的请求路径
private fun initializeAudio() {
if (!audioManager.isInCall()) {
volumeControlStream = AudioManager.STREAM_VOICE_CALL
// Request audio focus for playback
val result: Int = if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
audioManager.requestAudioFocus(focusRequest)
} else {
@Suppress("DEPRECATION")
audioManager.requestAudioFocus(
afChangeListener,
AudioManager.STREAM_VOICE_CALL,
AudioManager.AUDIOFOCUS_GAIN
)
}
if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
StreemLog.logError(TAG, "Audio focus request denied", sendBreadcrumb = true)
}
}
}
所以这里是较新版本的 AudioFocusRequest
private val focusRequest: AudioFocusRequest by lazy {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN).run {
setAudioAttributes(
AudioAttributes.Builder().run {
setLegacyStreamType(AudioManager.STREAM_VOICE_CALL)
setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
build()
}
)
setOnAudioFocusChangeListener(afChangeListener)
build()
}
} else throw IllegalStateException("Trying to use AudioFocusRequest below minimum API 26")
}
这是更过时的 OnAudioFocusChangeListener
private val afChangeListener: AudioManager.OnAudioFocusChangeListener =
AudioManager.OnAudioFocusChangeListener { focusChange ->
when (focusChange) {
AudioManager.AUDIOFOCUS_LOSS -> {
tearDownAudio()
}
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> {
// noop
}
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> {
// noop
}
AudioManager.AUDIOFOCUS_GAIN -> {
initializeAudio()
}
}
}
最后,我们有从 Activity 中的 onPause() 调用的 tearDownAudio() 方法
private fun tearDownAudio() {
volumeControlStream = AudioManager.USE_DEFAULT_STREAM_TYPE
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
audioManager.abandonAudioFocusRequest(focusRequest)
} else {
@Suppress("DEPRECATION")
audioManager.abandonAudioFocus(afChangeListener)
}
}
我的猜测是问题出在 tearDownAudio() 方法的某个地方,因为设备上的音频在开始和通话期间工作得很好,但在通话结束后没有返回到正常流。
由于我们使用的是自我管理的连接服务,因此 ConnectionService 实现中也可能存在问题,但我的第一直觉是上面的代码是问题所在。