[英]Android - playback audio on internal phone speaker with bluetooth speaker connected
[英]Android : Switching audio between Bluetooth and Phone Speaker is inconsistent
我的要求是根據用戶選擇在藍牙和電話揚聲器之間切換音頻。 以下是代碼段:
//AudioTrack for incoming audio to play as below:
int mMaxJitter = AudioTrack.getMinBufferSize(8000, AudioFormat.CHANNEL_OUT_MONO,AudioFormat.ENCODING_PCM_16BIT);
new AudioTrack(AudioManager.STREAM_VOICE_CALL,8000,
AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT,
mMaxJitter, AudioTrack.MODE_STREAM);
//To register broadcast receiver for bluetooth audio routing
IntentFilter ifil = new IntentFilter();
ifil.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED);
this.registerReceiver(<receiver instance>,ifil);
//To get AudioManager service
AudioManager mAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
//Whenever user select to route audio to Bluetooth
mAudioManager.setMode(AudioManager.MODE_IN_CALL);//tried setting with other mode also viz. MODE_NORMAL, MODE_IN_COMMUNICATION but no luck
mAudioManager.startBluetoothSco();//after this I get AudioManager.SCO_AUDIO_STATE_CONNECTED state in the receiver
mAudioManager.setBluetoothScoOn(true);
mAudioManager.setSpeakerphoneOn(false);
//Whenever user select to route audio to Phone Speaker
mAudioManager.setMode(AudioManager.MODE_NORMAL);
mAudioManager.stopBluetoothSco();//after this I get AudioManager.SCO_AUDIO_STATE_DISCONNECTED state in the receiver
mAudioManager.setBluetoothScoOn(false);
mAudioManager.setSpeakerphoneOn(true);
問題:1。我能夠路由音頻,但行為不一致,有時它會路由到手機揚聲器,即使用戶選擇路由到藍牙(藍牙連接)2。如果音頻路由到手機揚聲器,音量會變低(請不要說檢查手機音量)3。根據我的選擇,我只能觀察幾次音頻路由是否合適,如果我重復它就像我上面提到的那樣變得怪異。
Android版:Jellybean 4.3
有沒有人遇到類似的行為?
謝謝!
我得到了音頻路由不一致的原因,這是因為我設置了手機揚聲器假,我也使用了不合適的模式...下面的組合對我有用:
//For BT
mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
mAudioManager.startBluetoothSco();
mAudioManager.setBluetoothScoOn(true);
//For phone ear piece
mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
mAudioManager.stopBluetoothSco();
mAudioManager.setBluetoothScoOn(false);
mAudioManager.setSpeakerphoneOn(false);
//For phone speaker(loadspeaker)
mAudioManager.setMode(AudioManager.MODE_NORMAL);
mAudioManager.stopBluetoothSco();
mAudioManager.setBluetoothScoOn(false);
mAudioManager.setSpeakerphoneOn(true);
Android版:4.3
謝謝!
如果它仍然與某人相關,這是我的解決方案:
(在三星s7 sm-g9307上測試,安卓版6.0.1)
public class AudioSourceUtil {
private static void reset(AudioManager audioManager) {
if (audioManager != null) {
audioManager.setMode(AudioManager.MODE_NORMAL);
audioManager.stopBluetoothSco();
audioManager.setBluetoothScoOn(false);
audioManager.setSpeakerphoneOn(false);
audioManager.setWiredHeadsetOn(false);
}
}
public static void connectEarpiece(AudioManager audioManager) {
reset(audioManager);
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
}
public static void connectSpeaker(AudioManager audioManager) {
reset(audioManager);
audioManager.setSpeakerphoneOn(true);
}
public static void connectHeadphones(AudioManager audioManager) {
reset(audioManager);
audioManager.setWiredHeadsetOn(true);
}
public static void connectBluetooth(AudioManager audioManager) {
reset(audioManager);
}
}
通過單擊按鈕(標簽布局中的選項卡)進行使用:
/**
* There are 3 scenarios for the audio source:
* 1. No headphones and no bluetooth device: toggle phone/ speaker
* 2. Headphones connected: toggle headphones/ speaker
* 3. Bluetooth connected: toggle phone/ speaker/ bluetooth
*
* @param tab
*/
private void handleTabAudioSourceClick(TabLayout.Tab tab) {
View view = tab.getCustomView();
ImageView icon = (ImageView) view.findViewById(R.id.imageViewIcon);
int currentAudioSourceIdentifier = (Integer) view.getTag();
if (audioManager.isWiredHeadsetOn() == false && BluetoothManager.isBluetoothHeadsetConnected() == false) {
// No headphones and no bluetooth device: toggle phone/ speaker.
if (currentAudioSourceIdentifier == R.drawable.tab_speaker) {
// Current audio source is earpiece, moving to speaker.
view.setTag(android.R.drawable.stat_sys_speakerphone);
icon.setImageResource(android.R.drawable.stat_sys_speakerphone);
AudioSourceUtil.connectSpeaker(audioManager);
} else {
// Current audio source is speaker, moving to earpiece.
view.setTag(R.drawable.tab_speaker);
icon.setImageResource(R.drawable.tab_speaker);
AudioSourceUtil.connectEarpiece(audioManager);
}
} else if (audioManager.isWiredHeadsetOn()) {
// Headphones connected: toggle headphones/ speaker.
if (currentAudioSourceIdentifier == android.R.drawable.stat_sys_speakerphone) {
// Current audio source is speaker, moving to headphones.
view.setTag(android.R.drawable.stat_sys_headset);
icon.setImageResource(android.R.drawable.stat_sys_headset);
AudioSourceUtil.connectHeadphones(audioManager);
} else {
// Current audio source is headphones, moving to speaker.
view.setTag(android.R.drawable.stat_sys_speakerphone);
icon.setImageResource(android.R.drawable.stat_sys_speakerphone);
AudioSourceUtil.connectSpeaker(audioManager);
}
} else if (BluetoothManager.isBluetoothHeadsetConnected()) {
// Bluetooth connected: toggle phone/ speaker/ bluetooth.
if (currentAudioSourceIdentifier == R.drawable.tab_speaker) {
// Current audio source is earpiece, moving to speaker.
view.setTag(android.R.drawable.stat_sys_speakerphone);
icon.setImageResource(android.R.drawable.stat_sys_speakerphone);
AudioSourceUtil.connectSpeaker(audioManager);
} else if (currentAudioSourceIdentifier == android.R.drawable.stat_sys_speakerphone) {
// Current audio source is speaker, moving to bluetooth.
view.setTag(android.R.drawable.stat_sys_data_bluetooth);
icon.setImageResource(android.R.drawable.stat_sys_data_bluetooth);
AudioSourceUtil.connectBluetooth(audioManager);
} else {
// Current audio source is bluetooth, moving to earpiece.
view.setTag(R.drawable.tab_speaker);
icon.setImageResource(R.drawable.tab_speaker);
AudioSourceUtil.connectEarpiece(audioManager);
}
}
}
使用MediaRouter api: https : //developer.android.com/guide/topics/media/mediarouter
它專為此而設計。 像這樣的東西:
mediaRouter = MediaRouter.getInstance(VideoCallingApp.getContext());
mediaRouteSelector = new MediaRouteSelector.Builder()
.addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO)
.build();
....
public void onStart() {
mediaRouter.addCallback(mediaRouteSelector, mMediaRouterCallback,
MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
super.onStart();
}
@Override
public void onStop() {
mediaRouter.removeCallback(mMediaRouterCallback);
super.onStop();
}
...當你想切換音頻設備時,請使用mediaRouter.getRoutes()和mediaRouter.selectRoute(route)API。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.