Bootstrap

安卓播放语音时,蓝牙耳机、有线耳机、听筒、免提切换

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" />
;