Esta página fue traducida automáticamente del portugués y puede contener errores. La versión en portugués es la canónica.
Bluetooth BLE / GATT
CrossFly usa una pila BLE/GATT asíncrona (dev.crossfly.device.bluetooth), que sustituyó
al antiguo JSR-82/SPP. El modelado se basa en CompletableFuture.
⚠️ Nota de honestidad (léela antes de codificar)
En el core, varias operaciones son esqueleto sobre estado en memoria — BluetoothConnectionBuilder.build()
crea streams vacíos, GattCharacteristic.read()/write() solo tocan la caché local, y discoverServices()
retorna una lista vacía. El transporte de radio real viene de los launchers de plataforma (Android/iOS). El
modelado (UUIDs, futures, jerarquía service→characteristic→descriptor) ya es definitivo; cuenta con
la API, pero prueba en dispositivo real por plataforma.
Descubrimiento y conexión
BluetoothManager bt = BluetoothManager.getInstance(); // throws IOException
// escanear (asíncrono)
bt.scanForDevices(10, TimeUnit.SECONDS, new BluetoothManager.ScanCallback() {
public void onSuccess(List<BluetoothDevice> devices) { /* elegir uno */ }
public void onError(String error) { Debug.log(error); }
});
// conectar (asíncrono) — devuelve una BluetoothConnection
bt.connect(device, new BluetoothManager.ConnectionCallback() {
public void onSuccess(BluetoothConnection conn) { usar(conn); }
public void onError(String error) { Debug.log(error); }
});
Hay variantes *Sync (scanForDevicesSync, connectSync) — úsalas solo en un worker thread, nunca
en el paint thread.
GATT — leer batería y suscribir notificaciones
Modelo service → characteristic → descriptor, I/O vía CompletableFuture:
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 -> // suscribe cambios
Component.onUI(() -> label.setText((bytes[0] & 0xFF) + "%")));
});
GattCharacteristic expone read() → CompletableFuture<byte[]>, write(byte[]) → CompletableFuture<Void>,
enableNotifications(Consumer<byte[]>), y las pruebas de capacidad canRead()/canWrite()/canNotify().
BluetoothConnection es AutoCloseable
try (BluetoothConnection conn = bt.connectSync(device)) { // solo en worker thread
conn.write("PING".getBytes());
byte[] resp = conn.read();
} // se cierra por sí solo
Buenas prácticas
- Asíncrono en la UI (
connect(...)),*Syncsolo en worker. - Los callbacks/futures vuelven a la UI con
Component.onUI(...). try-with-resourcesen laBluetoothConnection.- Prueba en dispositivo real por plataforma (el core es modelado; la radio vive en el launcher).
Errores comunes
- Llamar a las variantes
*Syncen el paint thread (bloquea la UI). - Esperar que el core haga I/O de radio real (es esqueleto; el transporte es de la plataforma).
- Tocar la UI dentro de
thenAccept/callback sinonUI(...).