我的要求是根据用户选择在蓝牙和手机扬声器之间切换音频。 以下是代码段:
//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
有没有人遇到类似的行为?
谢谢!
答案 0 :(得分:9)
我得到了音频路由不一致的原因,那是因为我设置了手机扬声器假,我也使用了不合适的模式... 以下组合为我工作:
//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
谢谢!
答案 1 :(得分:1)
如果它仍然与某人有关,这是我的解决方案:
(在samsung 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);
}
}
}
答案 2 :(得分:0)
为此使用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。