跳到内容
CrossFly 是 100% 开源在 GitHub 关注我们
CrossFlyCrossFly
开始使用

本页面由葡萄牙语机器翻译,可能存在错误。葡萄牙语版本为准。

蓝牙 BLE / GATT

CrossFly 使用一个异步 BLE/GATT 栈(dev.crossfly.device.bluetooth),它取代了 旧的 JSR-82/SPP。其建模基于 CompletableFuture。

⚠️ 坦诚提示(写代码前请阅读)

在 core 中,若干操作是基于内存状态的骨架 —— BluetoothConnectionBuilder.build() 创建空的流,GattCharacteristic.read()/write() 只操作本地缓存,而 discoverServices() 返回空列表。真正的无线电传输来自平台启动器(Android/iOS)。而 建模(UUID、future、service→characteristic→descriptor 层级)已是最终形态;可依赖该 API,但要在每个平台的真实设备上测试。

发现与连接

BluetoothManager bt = BluetoothManager.getInstance();   // throws IOException

// 扫描(异步)
bt.scanForDevices(10, TimeUnit.SECONDS, new BluetoothManager.ScanCallback() {
   public void onSuccess(List<BluetoothDevice> devices) { /* 选择一个 */ }
   public void onError(String error) { Debug.log(error); }
});

// 连接(异步)— 返回一个 BluetoothConnection
bt.connect(device, new BluetoothManager.ConnectionCallback() {
   public void onSuccess(BluetoothConnection conn) { usar(conn); }
   public void onError(String error) { Debug.log(error); }
});

存在 *Sync 变体(scanForDevicesSync、connectSync)—— 仅在 worker 线程中使用,绝不 在绘制线程上使用。

GATT —— 读取电量并订阅通知

service → characteristic → descriptor 模型,通过 CompletableFuture 进行 I/O:

device.discoverServices(services -> {
   GattService bateria = device.getService("0000180F-0000-1000-8000-00805F9B34FB");
   GattCharacteristic nivel = bateria.getCharacteristic("00002A19-0000-1000-8000-00805F9B34FB");

   nivel.read().thenAccept(bytes -> {
      int pct = bytes[0] & 0xFF;
      Component.onUI(() -> label.setText(pct + "%"));
   });

   nivel.enableNotifications(bytes ->                     // 订阅变更
      Component.onUI(() -> label.setText((bytes[0] & 0xFF) + "%")));
});

GattCharacteristic 暴露 read() → CompletableFuture<byte[]>、write(byte[]) → CompletableFuture<Void>、 enableNotifications(Consumer<byte[]>),以及能力检测 canRead()/canWrite()/canNotify()。

BluetoothConnection 是 AutoCloseable

try (BluetoothConnection conn = bt.connectSync(device)) {   // 仅在 worker thread 中
   conn.write("PING".getBytes());
   byte[] resp = conn.read();
}   // 自动关闭

最佳实践

  • 在 UI 中用异步(connect(...)),*Sync 仅在 worker 中。
  • 回调/future 用 Component.onUI(...) 返回 UI。
  • 对 BluetoothConnection 使用 try-with-resources。
  • 在每个平台的真实设备上测试(core 只是建模;无线电存在于启动器中)。

常见错误

  • 在绘制线程上调用 *Sync 变体(阻塞 UI)。
  • 期望 core 执行真正的无线电 I/O(它只是骨架;传输属于平台)。
  • 在 thenAccept/回调中直接操作 UI 而不用 onUI(...)。

另见

这个页面有帮助吗?