失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Android蓝牙耳机/扬声器音频切换

Android蓝牙耳机/扬声器音频切换

时间:2020-11-05 18:22:20

相关推荐

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);//关闭Scoif (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() {@Overridepublic 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音频输出通道切换 -蓝牙 外放

android插入耳机状态使用扬声器外放音乐

蓝牙连接的sco问题

Android蓝牙耳机使用

如果觉得《Android蓝牙耳机/扬声器音频切换》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。