app中使用如下代码实现:
/**
- 扬声器通道播放
*/
public static void onSpeakerChannl() {
AudioManager audioManager = (AudioManager) App.getAppContext().getSystemService(Context.AUDIO_SERVICE);
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
audioManager.stopBluetoothSco();
audioManager.setBluetoothScoOn(false);
audioManager.setSpeakerphoneOn(true); // 使用扬声器播放,即使已经插入耳机
}
/**
- 耳机通道播放
*/
public static void onHeadSetChannl() {
AudioManager audioManager = (AudioManager) App.getAppContext().getSystemService(Context.AUDIO_SERVICE);
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
audioManager.stopBluetoothSco();
audioManager.setBluetoothScoOn(false);
audioManager.setSpeakerphoneOn(false); // 使用扬声器播放,即使已经插入耳机
}
app层直接调用系统接口来切换耳机与扬声器来播放声音,在正常的安卓系统中,耳机是通过耳机插入检测与拔出来自动切换这个功能的,所以第一步,把耳机的插入检测功能去掉,
es8323: es8323@10 {
status = "okay";
compatible = "everest,es8323";
reg = <0x10>;
spk-con-gpio = <&gpio7 15 GPIO_ACTIVE_HIGH>;
// hp-det-gpio = <&gpio0 8 GPIO_ACTIVE_LOW>;
clock-names = "mclk";
clocks = <&cru SCLK_I2S0_OUT>;
pinctrl-names = "default";
pinctrl-0 = <&i2s0_mclk>;
#sound-dai-cells = <0>;
};
第二步,看客户app调用的方法是直接调用\frameworks\base\services\core\java\com\android\server\audio\AudioService.java中的setSpeakerphoneOn,
/** @see AudioManager#setSpeakerphoneOn(boolean) */
public void setSpeakerphoneOn(boolean on){
if (!checkAudioSettingsPermission("setSpeakerphoneOn()")) {
return;
}
if (on) {
if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) {
sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE,
AudioSystem.FOR_RECORD, AudioSystem.FORCE_NONE, null, 0);
}
mForcedUseForComm = AudioSystem.FORCE_SPEAKER;
} else if (mForcedUseForComm == AudioSystem.FORCE_SPEAKER){
mForcedUseForComm = AudioSystem.FORCE_NONE;
}
sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE,
AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, null, 0);
}
这个方法默认是切换听筒与扬声器的,现在直接调用已经没有作用,需要在这里做修改,我们知道耳机与扬声器的声音是通过的底层codec的spk-con-gpio控制的,spk-con-gpio打开就是扬声器出声,spk-con-gpio关闭扬声器无声;耳机的声音控制通过另外一个管脚控制,如下图所示,所以我们就在底层驱动中加一个驱动控制这个开关,然后在setSpeakerphoneOn修改如下就行了。
public void setSpeakerphoneOn(boolean on){
if (!checkAudioSettingsPermission("setSpeakerphoneOn()")) {
return;
}
if (on) {
if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) {
sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE,
AudioSystem.FOR_RECORD, AudioSystem.FORCE_NONE, null, 0);
}
mForcedUseForComm = AudioSystem.FORCE_SPEAKER;
set_speack_onoff("spkon");
} else if (mForcedUseForComm == AudioSystem.FORCE_SPEAKER){
mForcedUseForComm = AudioSystem.FORCE_NONE;
set_speack_onoff("spkoff");
}
sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE,
AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, null, 0);
}
第3步,各厂家根据自己的板子去实现set_speack_onoff这个接口就行了,也不是太复杂。