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

Android GATT客户端如何在回调内获取服务器通知数据?

解决GATT客户端无需广播直接处理通知数据的问题

嘿,我明白你的困扰了!其实你之前的核心误区是找错了回调方法,而且误解了getValue()的作用——咱们一步步来解决:

首先,找对触发通知的回调方法

当GATT服务器发送通知时,不会触发onCharacteristicRead(这个回调是你主动调用readCharacteristic()读取特征值时才会触发的),真正对应通知的回调是BluetoothGattCallback里的onCharacteristicChanged方法!

然后,直接在回调里获取实时通知数据

你之前以为getValue()是读取发现特征时的静态数据,这是错的——当设备推送通知时,系统会把最新的通知数据更新到对应的BluetoothGattCharacteristic对象里,此时调用characteristic.getValue()拿到的就是刚收到的那23字节实时数据,完全可以当场处理,不需要广播转发。

代码示例

这里给你一个完整的实现片段:

1. 重写onCharacteristicChanged回调处理数据

private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
    // 其他回调方法(比如onConnectionStateChange、onServicesDiscovered)...

    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
        super.onCharacteristicChanged(gatt, characteristic);
        // 获取通知的字节数组
        byte[] receivedBytes = characteristic.getValue();
        
        if (receivedBytes != null && receivedBytes.length == 23) {
            // 把字节数组转成char数组(注意编码格式,根据你的设备协议选,比如ASCII/UTF-8)
            char[] charData = new char[receivedBytes.length];
            for (int i = 0; i < receivedBytes.length; i++) {
                charData[i] = (char) receivedBytes[i];
            }
            
            // 在这里直接处理你的char数组或者原始字节数据
            // 比如打印日志或者执行业务逻辑
            Log.d("GATT_NOTIFICATION", "收到的char数据: " + new String(charData));
        }
    }
};

2. 别忘了开启特征的通知功能

要让回调触发,你必须先给目标特征开启通知权限,还要配置对应的描述符:

// 假设你已经获取到了要监听的特征characteristic
BluetoothGattCharacteristic targetCharacteristic = ...;

// 第一步:开启特征通知
mBluetoothGatt.setCharacteristicNotification(targetCharacteristic, true);

// 第二步:配置Client Characteristic Configuration描述符(必须做!)
BluetoothGattDescriptor descriptor = targetCharacteristic.getDescriptor(
        UUID.fromString("00002902-0000-1000-8000-00805f9b34fb")
);
if (descriptor != null) {
    // 设置为启用通知的值
    descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
    // 写入描述符到设备
    mBluetoothGatt.writeDescriptor(descriptor);
}

最后再强调一遍

  • 通知触发的是onCharacteristicChanged,不是onCharacteristicRead
  • characteristic.getValue()在这个回调里拿到的是实时的通知数据,不是静态的初始值
  • 一定要配置好描述符,否则通知不会触发回调

这样你就完全不需要用广播,直接在回调里当场处理收到的23字节数据啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:10:50