本页面由葡萄牙语机器翻译,可能存在错误。葡萄牙语版本为准。
蓝牙 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(...)。
另见
这个页面有帮助吗?感谢你的反馈!