树莓派GATT Server向Android GATT Client传数据时代码报错求解
问题解决:bluepy中Service无addCharacteristic方法的错误
错误原因
bluepy的btle.Service类没有提供addCharacteristic或add_Characteristic方法,它通过内置的characteristics列表来管理下属特征。你之前的代码误用了不存在的方法,导致AttributeError。
修正方案
核心修改
将自定义Service类中的self.addCharacteristic(MyCharacteristic(self))替换为:
self.characteristics.append(MyCharacteristic(self))
完整修正代码
from bluepy.btle import Peripheral, UUID, DefaultDelegate, Characteristic, Service import struct import time import uuid # 定义服务和特征的UUID SERVICE_UUID = uuid.UUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E") CHARACTERISTIC_UUID = uuid.UUID("6E400002-B5A3-F393-E0A9-E50E24DCCA9E") # 回调处理类:处理来自Android设备的通知 class MyDelegate(DefaultDelegate): def __init__(self): DefaultDelegate.__init__(self) def handleNotification(self, cHandle, data): print("收到Android设备数据:", data) # 自定义特征类:实现读、写逻辑 class MyCharacteristic(Characteristic): def __init__(self, service): # 配置特征属性:支持读、写、通知 Characteristic.__init__(self, CHARACTERISTIC_UUID, Characteristic.PROP_READ | Characteristic.PROP_WRITE | Characteristic.PROP_NOTIFY, service) self.data = b"Hello, Android!" # 初始数据 def read(self): # 处理Android设备的读请求 return self.data def write(self, value): # 处理Android设备的写请求 self.data = value print("收到写入数据:", value) # 自定义服务类 class MyService(Service): def __init__(self, peripheral): Service.__init__(self, peripheral, SERVICE_UUID, primary=True) # 将特征添加到服务的特征列表中 self.characteristics.append(MyCharacteristic(self)) # 主程序逻辑 if __name__ == "__main__": # 创建GATT Server实例 peripheral = Peripheral() peripheral.setDelegate(MyDelegate()) # 绑定回调处理 # 注册自定义服务 service = MyService(peripheral) peripheral.setServices([service]) # 构造广播数据:携带128位服务UUID,让Android设备能扫描到 AD_TYPE_128_BIT_UUID = 0x07 adv_data = struct.pack("BB", AD_TYPE_128_BIT_UUID, 16) + SERVICE_UUID.bytes_le peripheral.setAdvertisingData(adv_data) peripheral.setAdvertisingInterval(1000) peripheral.startAdvertising() print("树莓派GATT Server已启动,等待Android设备连接...") try: target_char = peripheral.getCharacteristics(uuid=CHARACTERISTIC_UUID)[0] while True: # 等待通知,超时1秒 if peripheral.waitForNotifications(1.0): continue # 可选:定时推送分析后的数据到Android设备 # target_char.write(b"分析结果: " + str(time.time()).encode()) time.sleep(1) except KeyboardInterrupt: print("停止服务") peripheral.stopAdvertising() peripheral.disconnect()
其他关键修改说明
- 移除重复Peripheral实例:原代码中创建了两个Peripheral对象,导致广播配置和服务注册分离,现在统一为一个实例。
- 规范特征属性配置:使用bluepy内置的
Characteristic.PROP_*常量定义特征权限,比字符串列表更符合API规范。 - 修复广播数据:使用
0x07类型(128位UUID)构造广播数据,确保Android设备能识别自定义服务。 - 绑定Delegate:将回调类绑定到Peripheral,才能处理来自Android设备的通知。
- 调整数据推送逻辑:将数据写入代码放到循环中(注释部分),模拟定时推送分析结果,避免原代码中永远无法执行的问题。
内容的提问来源于stack exchange,提问作者santobedi
相关产品推荐
相关产品推荐

