android听筒+扬声器自动切换,Android VOIP中的扬声器、听筒切换

时间:2024-10-01 08:18:23

在做voip通话的过程中,会频繁使用到免提播放和听筒接听的功能,而如何正确的切换,和AudioManager的调度是分不开的,直接上代码:

//获取AudioManager服务

private val audioManager =

().getSystemService(Context.AUDIO_SERVICE) as AudioManager

/**

* 扬声器切换

* true: 打开

*/

fun setSpeakerPhoneOn(on: Boolean) {

if (on) {

//设置mode

= AudioManager.MODE_IN_COMMUNICATION

//设置音量,解决有些机型切换后没声音或者声音突然变大的问题

(

AudioManager.STREAM_VOICE_CALL,

(AudioManager.STREAM_VOICE_CALL),

AudioManager.FX_KEY_CLICK

)

//扬声器开启,此方法调用之前需要先设置好mode

= true

} else {

//5.0以上

if (.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

//设置mode

= AudioManager.MODE_IN_COMMUNICATION

//设置音量,解决有些机型切换后没声音或者声音突然变大的问题

(

AudioManager.STREAM_VOICE_CALL,

(AudioManager.STREAM_VOICE_CALL),

AudioManager.FX_KEY_CLICK

)

} else {

//设置mode

= AudioManager.MODE_IN_CALL

(

AudioManager.STREAM_VOICE_CALL,

(AudioManager.STREAM_VOICE_CALL),

AudioManager.FX_KEY_CLICK

)

}

//扬声器关闭,此方法调用之前需要先设置好mode

= false

}

}

/**

* 麦克风开关

* RINGER_MODE_SILENT 静音,且无振动

* RINGER_MODE_VIBRATE 静音,但有振动

* RINGER_MODE_NORMAL 正常声音,振动开关由setVibrateSetting决定.

* true:静音

*/

fun setVoiceOn(on: Boolean) {

= on

// (if (on) "麦克风已关闭" else "麦克风已启用")

}

/**

* 重设audioManager状态

* 扬声器切换为NORMAL && 打开麦克风

*/

fun resetAudioState() {

//设置mode 为喇叭播放

= AudioManager.MODE_NORMAL

//设置音量,解决有些机型切换后没声音或者声音突然变大的问题

(

AudioManager.STREAM_MUSIC,

(AudioManager.STREAM_MUSIC),

AudioManager.FX_KEY_CLICK

)

= true

setVoiceOn(false)

}

方法调用代码如上,下面来分析一下使用中要重点注意的元素:

AudioManager中给出了如下mode种类,正确的选择mode进行配置,才能提升用户体验;

/**

* Invalid audio mode.

*/

public static final int MODE_INVALID = AudioSystem.MODE_INVALID;

/**

* Current audio mode. Used to apply audio routing to current mode.

*/

public static final int MODE_CURRENT = AudioSystem.MODE_CURRENT;

/**

* Normal audio mode: not ringing and no call established.

*/

public static final int MODE_NORMAL = AudioSystem.MODE_NORMAL;

/**

* Ringing audio mode. An incoming is being signaled.

*/

public static final int MODE_RINGTONE = AudioSystem.MODE_RINGTONE;

/**

* In call audio mode. A telephony call is established.

*/

public static final int MODE_IN_CALL = AudioSystem.MODE_IN_CALL;

/**

* In communication audio mode. An audio/video chat or VoIP call is established.

*/

public static final int MODE_IN_COMMUNICATION = AudioSystem.MODE_IN_COMMUNICATION;

在VOIP场景中,主要就是为了通话服务,所以选择mode的时候,设置为MODE_IN_COMMUNICATION 就比较合适,如果设置为MODE_NORMAL 去开启扬声器,就可能会出现和其他音频播放声音混杂,甚至互相干扰啸叫严重的问题。