Android: 如何切換 SCO 鏈路。
阿新 • • 發佈:2018-12-17
最近在做藍芽音箱開發,在 A2DP 和 HFP 來回切換的時候,遇到了手機相容性的問題。最終發現裝置收聲和手機收聲,是因為 soc 切換有問題。原先在網上找了一些資料發現其實還蠻簡單的。就兩句話,當時沒想這麼多就直接寫了,發現還真能從裝置收聲,然後就沒管了。然後客戶反饋很多手機不能從裝置收聲,尤其是三星、華為最為嚴重。好吧,查了很多資料,同時跟嵌入式開發對程式碼。 SOC 都連線上了,還是不行。最終發現手機在切換的時候,需要設定 AudioManager 的模式:
MODE_NORMAL
: 普通模式,既不是鈴聲模式也不是通話模式MODE_RINGTONE
: 鈴聲模式MODE_IN_CALL
MODE_IN_COMMUNICATION
: 通訊模式,包括音/視訊,VoIP通話.(3.0加入的,與通話模式類似)
1、開啟 SCO 錄音
public void startSCO() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { mAudioManager.setMode(AudioManager.MODE_IN_CALL); } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { mAudioManager.setMode(AudioManager.MODE_IN_CALL); } if (mAudioManager.isBluetoothScoOn()) { if (mAliRecorderManager != null) { if (!isStartRecord){ mAliRecorderManager.startTalk(); } } return; } try { mAudioManager.setBluetoothScoOn(true); mAudioManager.startBluetoothSco(); } catch (NullPointerException e) { e.printStackTrace(); } IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED); BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1); if (AudioManager.SCO_AUDIO_STATE_CONNECTED == state) { if (mAliRecorderManager != null) { if (!isStartRecord){ mAliRecorderManager.startTalk(); } } ca.unregisterReceiver(this); } } }; ca.registerReceiver(receiver, intentFilter); }
2、關閉 SOC 錄音
public void stopSCO() {
mAudioManager.setMode(AudioManager.MODE_NORMAL);
if (mAudioManager.isBluetoothScoOn()) {
mAudioManager.setBluetoothScoOn(false);
mAudioManager.stopBluetoothSco();
}
}