You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android蓝牙经典模式下获取VID/PID遇connectGatt错误133求助

问题

我正在开发一款获取蓝牙设备厂商ID(VID)和产品ID(PID)的应用,该应用在BLE设备上运行正常,但连接仅支持经典模式(BR/EDR)的设备时出现错误状态133。请问如何通过connectGatt连接经典模式设备?

相关代码片段如下:

private final BluetoothGattCallback bluetoothGattCallback =
    new BluetoothGattCallback() {
      @Override
      public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        Log.d(TAG, "### onConnectionStateChange status: " + status + ", state: " + newState);
      }
  
      @Override
      public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        final UUID SERVICE_DEVICE_INFORMATION =
            UUID.fromString("0000180a-0000-1000-8000-00805f9b34fb");
            List<BluetoothGattService> svclist = gatt.getServices();
            if (svc.getUuid().equals(SERVICE_DEVICE_INFORMATION)) {
              List<BluetoothGattCharacteristic> characteristics = svc.getCharacteristics();
            }
      }

      @Override
      public void onCharacteristicRead(
          BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
        byte[] value = characteristic.getValue();
        Log.d(TAG, "### onCharacteristicRead:  UUID: " + characteristic.getUuid().toString());
        if (value != null && value.length == 7) {
          Log.d(
              TAG,
              String.format(
                  "### vid:%x pid:%x version:%x",
                  (0xFF & value[1]) | (0xFF & value[2]) << 8,
                  (0xFF & value[3]) | (0xFF & value[4]) << 8,
                  (0xFF & value[5]) | (0xFF & value[6]) << 8));
        }
      }        
};

device.connectGatt(context, true, bluetoothGattCallback, device.getType());

我尝试过使用fetchUuidsWithSdp并添加ACTION_UUID的处理逻辑,虽然获取到了HID UUID(00001124-0000-1000-8000-00805f9b34fb),但未得到除BASE_UUID和HID UUID之外的其他信息。

我还尝试了device.sdpSearch(BluetoothUuid.Hid),并在ACTION_SDP_RECORD中查看SDP记录,但没有收获,相关日志如下:

Debug: android.bluetooth.device.extra.SDP_SEARCH_STATUS = "0"
Debug: android.bluetooth.device.extra.DEVICE = "F4:73:35:06:74:3E"
Debug: android.bluetooth.device.extra.SDP_RECORD = "BluetoothSdpRecord [rawData=[], rawSize=0]"
Debug: android.bluetooth.device.extra.UUID = "00001124-0000-1000-8000-00805f9b34fb"
解决方案

1. 明确connectGatt的局限性

BluetoothGatt是专为BLE设备设计的API,无法直接连接仅支持经典蓝牙(BR/EDR)的设备,这是出现错误133的核心原因。经典蓝牙设备需要使用传统的RFCOMM连接方式,而非Gatt协议。

2. 获取经典蓝牙设备VID/PID的正确路径

经典蓝牙设备的VID和PID通常存储在SDP记录的Device ID服务中,需通过以下步骤获取:

  • 确保设备已与手机完成配对
  • 搜索SDP中的Device ID服务(UUID:00001200-0000-1000-8000-00805f9b34fb)
  • 解析该服务的属性提取VID、PID

3. 代码调整示例

步骤1:注册广播接收器监听SDP搜索结果

private BroadcastReceiver sdpReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (BluetoothDevice.ACTION_SDP_RECORD.equals(action)) {
            int status = intent.getIntExtra(BluetoothDevice.EXTRA_SDP_SEARCH_STATUS, -1);
            if (status == BluetoothDevice.SDP_SUCCESS) {
                BluetoothSdpRecord record = intent.getParcelableExtra(BluetoothDevice.EXTRA_SDP_RECORD);
                if (record != null) {
                    parseDeviceIdSdpRecord(record);
                }
            }
        }
    }
};

// 在Activity/Fragment的onCreate中注册接收器
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_SDP_RECORD);
registerReceiver(sdpReceiver, filter);

步骤2:发起Device ID服务的SDP搜索

// 先检查设备配对状态
if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
    UUID deviceIdServiceUuid = UUID.fromString("00001200-0000-1000-8000-00805f9b34fb");
    device.sdpSearch(deviceIdServiceUuid);
}

步骤3:解析SDP记录提取VID/PID

private void parseDeviceIdSdpRecord(BluetoothSdpRecord record) {
    // 获取Device ID服务的核心属性(属性ID 0x0003)
    BluetoothSdpAttribute attr = record.getAttribute(0x0003);
    if (attr != null) {
        byte[] data = attr.getValue();
        if (data != null && data.length >= 8) {
            // 按Device ID服务格式解析:偏移2-3字节为VID,4-5字节为PID
            int vid = ((data[2] & 0xFF) << 8) | (data[3] & 0xFF);
            int pid = ((data[4] & 0xFF) << 8) | (data[5] & 0xFF);
            Log.d(TAG, "经典蓝牙设备 VID: " + String.format("%04X", vid) + ", PID: " + String.format("%04X", pid));
        }
    }
}

4. 特殊设备的备选方案

部分HID设备(如键盘、鼠标)可能不暴露Device ID服务,可尝试读取系统存储的配对元数据:

Bundle metadata = device.getMetadata(BluetoothDevice.METADATA_GATT);
if (metadata != null) {
    int vid = metadata.getInt(BluetoothDevice.EXTRA_VENDOR_ID);
    int pid = metadata.getInt(BluetoothDevice.EXTRA_PRODUCT_ID);
    // 使用获取到的VID/PID
}

内容的提问来源于stack exchange,提问作者Lance Bai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 17:55:20