车载蓝牙笔记

方法不完整,仅是个人学习笔记。

1、前期准备

在Android应用中,BluetoothAdapter.getDefaultAdapter() 是一个静态方法,用于获取当前设备默认的蓝牙适配器实例。这个方法在蓝牙相关的操作中非常常用,因为它提供了访问蓝牙功能和设置的基础。

//如果设备支持蓝牙,这个方法将返回一个 BluetoothAdapter 对象。如果设备不支持蓝牙,这个方法将返回 null。
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter != null) {
    // 蓝牙适配器可用,可以继续进行蓝牙相关的操作
} else {
    // 蓝牙适配器不可用,可能需要通知用户或采取其他措施
}

注册蓝牙广播 

public static final String ACTION_NAME_CHANGED = "android.bluetooth.device.action.NAME_CHANGED";
private static final String HID_BROADCAST_RECEIVER_ACTION =
            "android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED";
public static final String ACTION_HF_INDICATORS_VALUE_CHANGED =
            "android.bluetooth.headset.action.HF_INDICATORS_VALUE_CHANGED";
public static final String EXTRA_HF_INDICATORS_IND_ID =
            "android.bluetooth.headset.extra.HF_INDICATORS_IND_ID";
public static final String EXTRA_HF_INDICATORS_IND_VALUE =
            "android.bluetooth.headset.extra.HF_INDICATORS_IND_VALUE";

public static final String ACTION_PLAYING_STATE_CHANGED =
            "android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED";

public final static int HF_INDICATOR_BATTERY_LEVEL_STATUS = 2;
public static final int BATTERY_LEVEL_UNKNOWN = -1;
public static final String VENDOR_SPECIFIC_HEADSET_EVENT_XEVENT = "+XEVENT";
public static final String VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV = "+IPHONEACCEV";
public static final String VENDOR_SPECIFIC_HEADSET_EVENT_XEVENT_BATTERY_LEVEL = "BATTERY";
public static final int VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV_BATTERY_LEVEL = 1;
private static final int HID_DEVICE_TYPE = 1280;
private static final int A2DP_DEVICE_TYPE = 1024;





private void registerBluetoothBroadcast() {
    IntentFilter intentFilter = new IntentFilter();
//当蓝牙适配器的状态发生变化时触发,例如蓝牙被开启或关闭
    intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
//当蓝牙设备的名称发生变化时触发
    intentFilter.addAction(ACTION_NAME_CHANGED);
//当蓝牙适配器开始搜索新设备时触发
    intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
//当蓝牙适配器完成搜索新设备时触发
    intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
//当发现新的蓝牙设备时触发
    intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
//当蓝牙设备请求配对时触发
    intentFilter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST);
//当蓝牙设备的配对状态发生变化时触发
    intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
//当蓝牙音频设备的连接状态发生变化时触发
    intentFilter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
//用于监听HID(人机界面设备)相关的广播
    intentFilter.addAction(HID_BROADCAST_RECEIVER_ACTION);
//当蓝牙耳机设备的特定事件发生时触发
    intentFilter.addAction(BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT);
//用于监听HF(免提)指示器值的变化
    intentFilter.addAction(ACTION_HF_INDICATORS_VALUE_CHANGED);
//蓝牙音频流的播放状态发生变化时被触发
    intentFilter.addAction(ACTION_PLAYING_STATE_CHANGED);
  
 //用于过滤特定品牌的蓝牙耳机事件
intentFilter.addCategory(BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY + "."
                + BluetoothAssignedNumbers.PLANTRONICS);
//用于过滤特定品牌的蓝牙耳机事件
    intentFilter.addCategory(BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY + "."
                + BluetoothAssignedNumbers.APPLE);
    mContext.registerReceiver(bluetoothBroadcastReceiver,intentFilter);
}

a2dp连接器 

public class A2dpConnector {
    private Context mContext;
    private BluetoothDevice mDevices;
    private BluetoothA2dp mA2dpProfile;
    public A2dpConnector(Context context) {
        mContext = context;
    }

    public void a2dpConnect(BluetoothDevice device) {
        mDevices = device;
        BluetoothAdapter.getDefaultAdapter().getProfileProxy(mContext, connect, BluetoothProfile.A2DP);
    }

    public void a2dpDisconnect(BluetoothDevice device) {
        mDevices = device;
        BluetoothAdapter.getDefaultAdapter().getProfileProxy(mContext, disconnect, BluetoothProfile.A2DP);
    }

    public void setPriority(BluetoothDevice device, int priority) {
        if (mA2dpProfile == null) {
            return;
        }

        mA2dpProfile.setPriority(device,priority);
    }

    private BluetoothProfile.ServiceListener connect = new BluetoothProfile.ServiceListener() {

        @Override
        public void onServiceDisconnected(int profile) {
            mDevices = null;
        }

        @Override
        public void onServiceConnected(int profile, BluetoothProfile proxy) {
            mA2dpProfile = (BluetoothA2dp) proxy;
            if (mDevices == null) {
                return;
            }
            setPriority(mDevices,100);
            mA2dpProfile.connect(mDevices);
        }
    };

    private BluetoothProfile.ServiceListener disconnect = new BluetoothProfile.ServiceListener() {

        @Override
        public void onServiceDisconnected(int profile) {
            mDevices = null;
        }

        @Override
        public void onServiceConnected(int profile, BluetoothProfile proxy) {
            mA2dpProfile = (BluetoothA2dp) proxy;

            if (mDevices == null) {
                return;
            }

            setPriority(mDevices,0);
            mA2dpProfile.disconnect(mDevices);
        }
    };

}

2、打开/关闭蓝牙开关

当蓝牙开关时,去获取当前蓝牙状态,更新界面上的蓝牙开关控件的选中状态。

//打开蓝牙
bluetoothAdapter.enable()
//关闭蓝牙
bluetoothAdapter.disable()

收蓝牙状态改变广播

//关于广播接收后续就省略写下边两条了
String action = intent.getAction();
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
case BluetoothAdapter.ACTION_STATE_CHANGED: 
//获取蓝牙适配器的新状态
    int blueState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,0);
    switch (blueState) {
        case BluetoothAdapter.STATE_TURNING_ON:
//蓝牙适配器正在开启
            break;
        case BluetoothAdapter.STATE_ON:
//蓝牙适配器开启
//设置蓝牙设备的名称
            BluetoothLocalAdapter.getInstance().
                                        setName(XXX);
            mBluetoothPairedInfoList.clear();
            mBluetoothPairedDevicesList.clear();
            Set<BluetoothDevice> pairedDevices = BluetoothLocalAdapter.getInstance().getBondedDevices();
            if(pairedDevices != null && pairedDevices.size()>0){
                for(BluetoothDevice device:pairedDevices) {
                    BluetoothDeviceInfo bluetoothDeviceInfo = new BluetoothDeviceInfo();
                    bluetoothDeviceInfo.setDeviceName(device.getName());
                    bluetoothDeviceInfo.setDeviceMacAddress(device.getAddress());
                     
                     bluetoothDeviceInfo.setDeviceConnectStatus(BluetoothProfile.STATE_DISCONNECTED);

bluetoothDeviceInfo.setDeviceAddDate(getSavePairedDeviceInfo(mContext,device.getAddress() 
));
                    mBluetoothPairedInfoList.add(bluetoothDeviceInfo);
                    mBluetoothPairedDevicesList.add(device);
                }
                onPairedBluetoothDeviceCallback(mBluetoothPairedInfoList, mBluetoothPairedDevicesList);
            }
//开始搜索新设备(如果蓝牙已开启)
            bluetoothAdapter.startScanning();
//设置蓝牙设备的可见性超时时间
            bluetoothAdapter.setDiscoverableTimeout(0);
//设置蓝牙设备的扫描模式。这个方法接受两个参数:第一个参数是扫描模式,第二个参数是可见性超时时间。
//BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE表示设备在搜索其他设备的同时也允许被其他设备搜索。
//这意味着设备将广播其存在,并且可以接收其他设备的连接请求。
            bluetoothAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE,0);
//更新蓝牙开关状态ui
            updateBluetoothSwitchStatus(true);
//保存蓝牙状态,方便后续相关业务
            SharedPreferencesUtil.getInstance(mContext).
                                        saveBtSwitchStatus(KEY_BLUETOOTH_SWITCH, true);
            break;
        case BluetoothAdapter.STATE_TURNING_OFF:
//蓝牙适配器正在关闭
            break;
        case BluetoothAdapter.STATE_OFF:
//蓝牙适配器关闭
             bluetoothAdapter.setDiscoverableTimeout(0);
//设置蓝牙设备的扫描模式。
//BluetoothAdapter.SCAN_MODE_CONNECTABLE表示设备在搜索其他设备的同时只允许被其他设备搜索,而不会主动搜索其他设备。
   bluetoothAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE,0);
//清除“可用设备”
            clearAvailableDevice();
            updateBluetoothSwitchStatus(false);
            SharedPreferencesUtil.getInstance(mContext).
                                        saveBtSwitchStatus(KEY_BLUETOOTH_SWITCH, false);
            break;
        default:
            break;
    }
    break;

3、扫描相关

//开始扫描
bluetoothLocalAdapter.startScanning()
case BluetoothAdapter.ACTION_DISCOVERY_STARTED:
//清空蓝牙可用设备列表,为新的搜索做准备
    mBluetoothAvailableDevicesList.clear();
    break;
case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
    break;

4、可用设备

case BluetoothDevice.ACTION_FOUND:
//检查新发现的设备对象device是否不为null,并且设备的蓝牙类(BluetoothClass)也不为null
    if (device != null && device.getBluetoothClass() != null) {
//从设备的蓝牙类中获取主要设备类别
        int iBluetoothDeviceType = device.getBluetoothClass().getMajorDeviceClass();
//检查设备的主要类别是否为HID(人机界面设备)类型或A2DP(高级音频分布配置文件)类型
        if (iBluetoothDeviceType == HID_DEVICE_TYPE || iBluetoothDeviceType == A2DP_DEVICE_TYPE) {
//用于标记新发现的设备是否已经存在于可用设备列表中
            boolean isExist = false;
            if (mBluetoothAvailableDevicesList != null) {
                for (int i = 0; i < mBluetoothAvailableDevicesList.size(); i++) {
                    if (device.getAddress().equals(mBluetoothAvailableDevicesList.get(i).getAddress())) {
                        isExist = true;
                        break;
                    }
                }
            }
            if (!isExist) {
                mBluetoothAvailableDevicesList.add(device);
            }
//已配对设备就不显示在可用设备里了
            if (mBluetoothPairedDevicesList != null && mBluetoothPairedDevicesList.size() > 0) {
                for (int i = 0; i < mBluetoothPairedDevicesList.size(); i++) {
                    if (bluetoothDevice.getAddress().equals(mBluetoothPairedDevicesList.get(i).getAddress())) {
                        mBluetoothAvailableDevicesList.remove(device);
                    }
                }
            }
            onAvailableBluetoothDeviceCallback(mBluetoothAvailableDevicesList);
       }
   }
   break;

5、配对

public void startPairing(BluetoothDevice device) {
//检查当前蓝牙适配器是否正在进行设备发现(discovery)过程
    if (bluetoothAdapter.isDiscovering()) {
//取消搜索
        bluetoothAdapter.cancelDiscovery();
    }
    if (device!= null) {
        device.createBond()
    }
}
case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
    if (device == null) {
        break;
    }
    switch (device.getBondState()) {
        case BluetoothDevice.BOND_BONDING:
//当设备正在配对
            break;
        case BluetoothDevice.BOND_BONDED:
//当设备已配对
//用于标记设备地址是否已经在已配对设备列表中
            boolean addBondedAddressEqual = false;
            if (mBluetoothPairedDevicesList != null && mBluetoothPairedDevicesList.size()>0) {
                for (int i = 0; i < mBluetoothPairedDevicesList.size(); i++) {
                    if (device.getAddress() != null) {
                        if (device.getAddress().equals(mBluetoothPairedDevicesList.get(i).getAddress())) {
                            addBondedAddressEqual = true;
                        }
                    }
                }
            }
            if (!addBondedAddressEqual) {
//设备地址不在已配对设备列表中
                BluetoothDeviceInfo bluetoothDeviceInfo = new BluetoothDeviceInfo();
                bluetoothDeviceInfo.setDeviceName(bluetoothDevice.getName());
                bluetoothDeviceInfo.setDeviceMacAddress(bluetoothDevice.getAddress());
                 bluetoothDeviceInfo.setDeviceConnectStatus(BluetoothProfile.STATE_DISCONNECTED);
                mBluetoothPairedInfoList.add(bluetoothDeviceInfo);
                mBluetoothPairedDevicesList.add(bluetoothDevice);
            }
            onPairedBluetoothDeviceCallback(mBluetoothPairedInfoList, mBluetoothPairedDevicesList);
//在可用设备list里remove此设备
            if (mBluetoothAvailableDevicesList != null && mBluetoothAvailableDevicesList.size() > 0) {
                mBluetoothAvailableDevicesList.remove(device);
            }
            onAvailableBluetoothDeviceCallback(mBluetoothAvailableDevicesList);
            if (device.getBluetoothClass() != null) {
                int iBluetoothDeviceType = device.getBluetoothClass().getMajorDeviceClass();
                if (iBluetoothDeviceType == A2DP_DEVICE_TYPE) {
//如果设备的主要类别是A2DP,则调用mBluetoothA2dpConnector的a2dpConnect方法,并传入设备对象。
//尝试连接到支持A2DP的蓝牙音频设备,如蓝牙耳机或扬声器。
                    mA2dpConnector.a2dpConnect(device);
                } else if (iBluetoothDeviceType == HID_DEVICE_TYPE) {
//如果设备的主要类别是HID,则调用mBluetoothHidConnector的hidConnect方法,并传入设备对象。
//尝试连接到支持HID的蓝牙设备,如蓝牙键盘或鼠标。
                    mHidConnector.hidConnect(device);
                }
            }
            break;
        case BluetoothDevice.BOND_NONE:
//设备未配对
            break;
        default:
            break;
    }
    break;

6、连接

//连接a2dp
A2dpConnector.a2dpConnect(bluetoothDevice);
//断连a2dp
A2dpConnector.a2dpDisconnect(bluetoothDevice);
case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED:
    if (device == null || device.getBluetoothClass() == null) {
        break;
    }
    int a2dpState = intent.getIntExtra(BluetoothA2dp.EXTRA_STATE, BluetoothA2dp.STATE_DISCONNECTED);
    int iA2dpDeviceType = device.getBluetoothClass().getMajorDeviceClass();
    switch (a2dpState) {
        case BluetoothA2dp.STATE_DISCONNECTED:
//a2dp连接断开
            break;
        case BluetoothA2dp.STATE_CONNECTING:
//a2dp连接中
            break;
        case BluetoothA2dp.STATE_CONNECTED:
//a2dp连接成功
            break;
        case BluetoothA2dp.STATE_DISCONNECTING:
//a2dp断连中
            break;
        default:
            break;
    }
    break;

8、蓝牙耳机指示器值变化

case ACTION_HF_INDICATORS_VALUE_CHANGED:
    if (device == null) {
        break;
    }
//指示器的ID
    int indicatorId = intent.getIntExtra(EXTRA_HF_INDICATORS_IND_ID, -1);
//指示器的值
    int indicatorValue = intent.getIntExtra(EXTRA_HF_INDICATORS_IND_VALUE, -1);
//检查指示器的ID是否为电池电量指示器
    if (indicatorId == HF_INDICATOR_BATTERY_LEVEL_STATUS ) {
        updateBatteryLevel(device, indicatorValue);
    }
    break;

case BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT:
    if (device == null) {
        break;
    }
    String cmd = intent.getStringExtra(BluetoothHeadset.EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD);
    if (cmd == null) {
        return;
    }
    int cmdType = intent.getIntExtra(
                                BluetoothHeadset.EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE, -1);
    if (cmdType != BluetoothHeadset.AT_CMD_TYPE_SET) {                  
        return;
    }
    Object[] args = (Object[]) intent.getExtras().get(
                                BluetoothHeadset.EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS);
    if (args == null) {
        return;
    }
    int batteryPercent = BATTERY_LEVEL_UNKNOWN;
    switch (cmd) {
        case VENDOR_SPECIFIC_HEADSET_EVENT_XEVENT:
            batteryPercent = getBatteryLevelFromXEventVsc(args);
            break;
        case VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV:
            batteryPercent = getBatteryLevelFromAppleBatteryVsc(args);
                                break;
    }
    if (batteryPercent != BATTERY_LEVEL_UNKNOWN) {
        updateBatteryLevel(device, batteryPercent);
    }
    break;

       android.bluetooth.headset.action.HF_INDICATORS_VALUE_CHANGED: 这个广播动作是当蓝牙耳机的某些指示器值发生变化时发出的。这些指示器通常包括耳机的电池电量、信号强度等。应用程序可以通过监听这个广播来获取这些指示器的最新值。

       BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT: 这个广播动作是用于处理来自蓝牙耳机的厂商特定事件。不同的耳机厂商可能会提供一些特定的功能或事件,这些事件可以通过这个广播动作来通知应用程序。例如,某些耳机可能会有特殊的按键功能,或者支持高级的语音识别功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值