1,效果图
来电图:
接通后的默认听筒播放图:
点击免提后的图:
当连接上有线耳机或者蓝牙耳机时,免提按钮不可以点击
2,语音播放输出方式切换代码
下面切换工具类针对的是StreamType为AudioManager.STREAM_VOICE_CALL(注意不是AudioManager.STREAM_MUSIC)
package com.eastmoney.emvideovisit.util;
import android.content.Context;
import android.media.AudioManager;
import android.os.Build;
/**
* 音频播放输出的切换
* <p>
* <详细功能描述>
*
* @author : liuxs
* @date : 2021/4/23
*/
public class AudioOutputUtil {
/**
* 切换到外放
*/
public static void changeToSpeaker(){
AudioManager audioManager = (AudioManager) ContextUtil.getContext().getSystemService(Context.AUDIO_SERVICE);
// audioManager.setMode(AudioManager.MODE_NORMAL);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
} else {
audioManager.setMode(AudioManager.MODE_IN_CALL);
}
audioManager.setBluetoothScoOn(false);
audioManager.stopBluetoothSco();
audioManager.setSpeakerphoneOn(true);
}
/**
* 切换到耳机模式
*/
public static void changeToHeadset(boolean wired){
AudioManager audioManager = (AudioManager) ContextUtil.getContext().getSystemService(Context.AUDIO_SERVICE);
if(!wired){//蓝牙
// audioManager.setMode(AudioManager.MODE_NORMAL);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
} else {
audioManager.setMode(AudioManager.MODE_IN_CALL);
}
audioManager.setSpeakerphoneOn(false);
audioManager.startBluetoothSco();
audioManager.setBluetoothScoOn(true);
}else{
// audioManager.setMode(AudioManager.MODE_NORMAL);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
} else {
audioManager.setMode(AudioManager.MODE_IN_CALL);
}
audioManager.setSpeakerphoneOn(false);
audioManager.setBluetoothScoOn(false);
audioManager.stopBluetoothSco();
}
}
/**
* 切换到听筒
*/
public static void changeToReceiver(){
AudioManager audioManager = (AudioManager) ContextUtil.getContext().getSystemService(Context.AUDIO_SERVICE);
audioManager.setSpeakerphoneOn(false);
audioManager.setBluetoothScoOn(false);
audioManager.stopBluetoothSco();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
} else {
audioManager.setMode(AudioManager.MODE_IN_CALL);
}
}
/**
* 恢复正常
*/
public static void changeToNormal(){
AudioManager audioManager = (AudioManager) ContextUtil.getContext().getSystemService(Context.AUDIO_SERVICE);
audioManager.setBluetoothScoOn(false);
audioManager.stopBluetoothSco();
audioManager.setSpeakerphoneOn(false);
audioManager.setMode(AudioManager.MODE_NORMAL);
}
public static void changeToHeadset() {
changeToHeadset(HeadSetManager.getInstance().getHeadSetStatus() == HeadSetManager.HEADSET_STATUS_WIRED);
}
}
3,是否连接耳机判断、监听管理类
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import java.util.ArrayList;
import java.util.List;
/**
* 简要功能描述
* <p>
* <详细功能描述>
* 注册广播
* HeadSetManager.getInstance().register()
* 添加监听
* addListener(OnHeadSetListener onHeadSetListener)
* 记得remove监听
* removeListener(OnHeadSetListener onHeadSetListener)
* 记得确认不用了的时候解除注册
* HeadSetManager.getInstance().unRegister()()
*
* @author : liuxs
* @date : 2021/3/22
*/
public class HeadSetManager extends BroadcastReceiver {
public static int HEADSET_STATUS_UNKNOWN = -1000;
public static int HEADSET_STATUS_NO = -1;
public static int HEADSET_STATUS_WIRED = 1; //有线耳机
public static int HEADSET_STATUS_BLUETOOTH = 2; //蓝牙耳机
// public static int HEADSET_STATUS_Bluetooth_A2DP = 3; //可操控蓝牙设备,如带播放暂停功能的蓝牙耳机
// public static int HEADSET_STATUS_Bluetooth_HEADSET = 4;//蓝牙头戴式耳机,支持语音输入输出
// public static int HEADSET_STATUS_Bluetooth_HEALTH = 5; //蓝牙穿戴式设备
private List<OnHeadSetListener> mHeadSetListeners;
private boolean hasRegistered;
private HeadSetManager() {
mHeadSetListeners = new ArrayList<>();
}
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
if(state == BluetoothProfile.A2DP || state == BluetoothProfile.HEADSET
|| state == BluetoothProfile.HEALTH){
onCallback(HEADSET_STATUS_BLUETOOTH);
}else{
if(hasHeadset()){
onCallback(HEADSET_STATUS_WIRED);
}else{
onCallback(HEADSET_STATUS_NO);
}
}
} else if (Intent.ACTION_HEADSET_PLUG.equals(action)) {
if (intent.hasExtra("state")) {
if (intent.getIntExtra("state", 0) == 0) {
if(getHeadSetStatus() == HEADSET_STATUS_BLUETOOTH){
onCallback(HEADSET_STATUS_BLUETOOTH);
}else{
onCallback(HEADSET_STATUS_NO);
}
}else if(intent.getIntExtra("state", 0) == 1){
onCallback(HEADSET_STATUS_WIRED);
}
}
}
}
private void onCallback(int status) {
if(mHeadSetListeners != null && !mHeadSetListeners.isEmpty()){
for (OnHeadSetListener onHeadSetListener : mHeadSetListeners) {
onHeadSetListener.onHeadsetStatusChanged(status);
}
}
}
/**
* 有无耳机判断
* @return
*/
public boolean hasHeadset(){
int status = getHeadSetStatus();
if( status == HEADSET_STATUS_WIRED
|| status == HEADSET_STATUS_BLUETOOTH){
// Log.d("lxs0331" , "showDlg status = "+status);
return true;
}
return false;
}
/**
* 返回当前的耳机连接状态
* @return {@link #HEADSET_STATUS_NO} {@link #HEADSET_STATUS_WIRED} {@link #HEADSET_STATUS_BLUETOOTH}
*/
public int getHeadSetStatus(){
AudioManager audioManager = (AudioManager)ContextUtil.getContext().getSystemService(Context.AUDIO_SERVICE);
if(audioManager != null && audioManager.isWiredHeadsetOn()){
return HEADSET_STATUS_WIRED;
}
BluetoothAdapter ba = BluetoothAdapter.getDefaultAdapter();
if (ba == null){
return HEADSET_STATUS_NO;
}
else if(ba.isEnabled()) {
int a2dp = ba.getProfileConnectionState(BluetoothProfile.A2DP); //可操控蓝牙设备,如带播放暂停功能的蓝牙耳机
int headset = ba.getProfileConnectionState(BluetoothProfile.HEADSET); //蓝牙头戴式耳机,支持语音输入输出
int health = ba.getProfileConnectionState(BluetoothProfile.HEALTH); //蓝牙穿戴式设备
//查看是否蓝牙是否连接到三种设备的一种,以此来判断是否处于连接状态还是打开并没有连接的状态
int flag = -1;
if (a2dp == BluetoothProfile.STATE_CONNECTED) {
flag = a2dp;
} else if (headset == BluetoothProfile.STATE_CONNECTED) {
flag = headset;
} else if (health == BluetoothProfile.STATE_CONNECTED) {
flag = health;
}
//说明连接上了三种设备的一种
if (flag != -1) {
return HEADSET_STATUS_BLUETOOTH;
}
}
return HEADSET_STATUS_NO;
}
/**
* 使用之前需要注册
*/
public void register(){
if(hasRegistered){
return;
}
hasRegistered = true;
IntentFilter headsetFilter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
ContextUtil.getContext().registerReceiver(this, headsetFilter);
IntentFilter bluetoothFilter = new IntentFilter(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
ContextUtil.getContext().registerReceiver(this, bluetoothFilter);
}
/**
* 添加Headset监听器,和{@link #removeListener(OnHeadSetListener)}成对使用,防止内存泄漏
* @param onHeadSetListener
*/
public void addListener(OnHeadSetListener onHeadSetListener){
if(mHeadSetListeners != null){
mHeadSetListeners.add(onHeadSetListener);
}
}
/**
* 移除Headset监听器
* @param onHeadSetListener
*/
public void removeListener(OnHeadSetListener onHeadSetListener){
if(mHeadSetListeners != null){
mHeadSetListeners.remove(onHeadSetListener);
}
}
/**
* 确认不再使用解注册
*/
public void unRegister(){
if(mHeadSetListeners != null){
mHeadSetListeners.clear();
}
if(hasRegistered){
ContextUtil.getContext().unregisterReceiver(this);
hasRegistered = false;
}
}
public static HeadSetManager getInstance(){
return InstanceHolder.sINSTANCE;
}
static class InstanceHolder{
static HeadSetManager sINSTANCE = new HeadSetManager();
}
public interface OnHeadSetListener{
/**
* 这里尽量使用status,部分华为机型在接收到蓝牙耳机连接上的广播后立马执行getHeadSetStatus()返回的不是蓝牙已经连接上
* 监听回调方法
* @param status {@link #HEADSET_STATUS_NO} {@link #HEADSET_STATUS_WIRED} {@link #HEADSET_STATUS_BLUETOOTH}
*/
void onHeadsetStatusChanged(int status);
}
}
记得添加权限:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />