蓝牙连接GATT配置:手把手教你搞定设备通信
你有没有遇到过这种情况:新买的智能手环连不上手机,或者血压计的数据传不到App里?很多时候问题不出在蓝牙开关,而是GATT配置没对上。别被这个术语吓到,其实搞明白它,很多设备连接问题都能迎刃而解。
什么是GATT配置?
GATT(Generic Attribute Profile)是蓝牙低功耗(BLE)设备之间通信的通用规则。你可以把它理解成两个设备“对话”的格式说明书——谁先说话、用什么句式、数据怎么打包,都得按这个来。比如你的体温枪要上报读数,就得通过GATT定义的服务(Service)和特征(Characteristic)把数据发出来。
常见的健康设备通常使用标准服务UUID,比如心率服务是 0000180D-0000-1000-8000-00805F9B34FB。如果你开发App或调试工具时发现读不到数据,第一反应应该是检查GATT结构是否匹配。
用代码查看GATT服务结构
在Android开发中,可以通过BluetoothGatt对象获取远程设备的服务列表。下面是一个简单的遍历示例:
BluetoothGatt gatt = device.connectGatt(context, false, gattCallback);
private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
for (BluetoothGattService service : gatt.getServices()) {
Log.i("GATT", "Found service: " + service.getUuid().toString());
for (BluetoothGattCharacteristic chara : service.getCharacteristics()) {
Log.i("GATT", "-- Characteristic: " + chara.getUuid().toString());
}
}
}
}
};运行这段代码后,你会看到设备广播的所有服务和特征值。如果某个关键特征没有读写权限标志,可能需要在硬件端重新配置GATT表。
常见问题排查思路
有时候设备明明连上了,就是收不到数据。这时候可以看看是不是通知(Notify)没开。比如想实时接收心率变化,除了找到正确的特征值,还得启用通知:
BluetoothGattCharacteristic chara = gatt.getService(SERVICE_UUID)
.getCharacteristic(CHARACTERISTIC_UUID);
gatt.setCharacteristicNotification(chara, true);
BluetoothGattDescriptor descriptor = chara.getDescriptor(
UUID.fromString("00002902-0000-1000-8000-00805F9B34FB"));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
gatt.writeDescriptor(descriptor);这一步就像订阅公众号,不开通知,哪怕对方发了消息你也收不到。
家用IoT设备调试时,推荐用nRF Connect这类工具先探一探GATT结构。看清楚服务层级和属性权限,再动手写代码,能少走很多弯路。很多所谓的“连接失败”,其实是读写操作发到了只支持通知的特征上。
蓝牙连接不是打开开关就完事,GATT配置才是背后的关键拼图。下次设备连不上,不妨多往下挖一层,看看数据通道到底卡在哪一环。