Android蓝牙耳机/扬声器音频切换
Posted Androider_Zxg
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android蓝牙耳机/扬声器音频切换相关的知识,希望对你有一定的参考价值。
需求背景
要求某些场景已经插入耳机或连接了蓝牙耳机,需要使用扬声器播放音频
实现调研
有线耳机的情况
排除蓝牙耳机情况,使用有线耳机,切换时只需要打开/关闭扬声器即可。这样就可以实现在插入耳机的情况下,使用扬声器播放。 代码如下:
//切换为扬声器
AudioManager audioManager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
audioManager.setMicrophoneMute(false);
audioManager.setSpeakerphoneOn(true);//使用扬声器外放,即使已经插入耳机
//setVolumeControlStream(AudioManager.STREAM_MUSIC);//控制声音的大小
audioManager.setMode(AudioManager.STREAM_MUSIC);
//切换为耳机
mAudioManager.setSpeakerphoneOn(false);
另外,播放音频android提供了两套Api,一套为MediaPlayer,偏上层。另一套AudioTrack偏底层。实验发现,在使用AudioTrack时需要添加增加AUDIO_SETTING权限。所以为了保险起见,需要加上如下权限:
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"></uses-permission>
蓝牙耳机
起初认为蓝牙耳机与有线耳机效果一样,但发现使用上述有线耳机的切换代码,效果为:切换至扬声器可从扬声器播放,关闭扬声器后。蓝牙耳机中无声音,扬声器也无声音。查找资料发现,需要手动打开蓝牙耳机,建立连接。代码如下:
- 连接蓝牙耳机,关闭扬声器
/**
* 关闭扬声器
*/
private void offSpeaker()
if (mAudioManager == null)
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
Log.i("zxg", "isBluetoothSco 2:" + mAudioManager.isBluetoothScoOn());
mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
//如果有蓝牙耳机设备连接,打开Sco通道使用蓝牙耳机播放音频
if (isBluetoothHeadsetConnected())
Log.i("zxg", "need start BluetoothSco");
mAudioManager.startBluetoothSco();
mAudioManager.setBluetoothScoOn(true);
//关闭扬声器
mAudioManager.setSpeakerphoneOn(false);
- 关闭蓝牙Sco通道,打开扬声器
/**
* 打开扬声器
*/
private void speaker()
if (mAudioManager == null)
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
// mAudioManager.setMicrophoneMute(false);
//关闭Sco
if (isBluetoothHeadsetConnected())
mAudioManager.setBluetoothScoOn(false);
mAudioManager.stopBluetoothSco();
//打开扬声器
mAudioManager.setSpeakerphoneOn(true);
mAudioManager.setMode(AudioManager.STREAM_MUSIC);
Log.i("zxg", "isBluetoothSco 1:" + mAudioManager.isBluetoothScoOn());
- 判断是否有蓝牙耳机与设备连接
/**
* 判断蓝牙耳机是否连接
* @return
*/
private boolean isBluetoothHeadsetConnected()
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (BluetoothProfile.STATE_CONNECTED == adapter.getProfileConnectionState(BluetoothProfile.HEADSET))
return true;
return false;
- 注册广播监听
需要注意的是,打开/关闭Sco是异步的,并不是马上完成的,所以我们需要监听系统广播,收到相关广播后继续进行后续逻辑操作。在具体逻辑代码中可以通过mAudioManager.isBluetoothScoOn()判断Sco状态,以及在广播中更新标记位来记录Sco状态
/**
* 监听Sco变化广播
*/
private void registerBluetoothBroadCast()
registerReceiver(new BroadcastReceiver()
@Override
public void onReceive(Context context, Intent intent)
int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -100);
Log.i("zxg", "EXTRA_SCO_AUDIO_STATE:" + state);
, new IntentFilter(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED));
- 添加权限
操作蓝牙需要申请如下权限
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
调研结果
使用以上代码嵌入出行司机端中,使用蓝牙/有线耳机切换,播放百度TTS语音。可以实现切换效果:即在连接蓝牙耳机/插入有线耳机时,可以通过扬声器播放音频。
参考资料
以上是关于Android蓝牙耳机/扬声器音频切换的主要内容,如果未能解决你的问题,请参考以下文章