Bluetooth Low Energy (BLE) è uno standard di comunicazione wireless ottimizzato per la trasmissione di piccoli volumi di dati con un consumo energetico minimo. Secondo Bluetooth SIG, 2025, la tecnologia è utilizzata in più di 5 miliardi di dispositivi in tutto il mondo. GATT (Generic Attribute Profile) organizza i dati in una gerarchia Service → Characteristic → Descriptor, che è alla base di tutte le applicazioni BLE per iOS e Android.
Punti Chiave
Bluetooth Low Energy (BLE) funziona secondo un modello client-server con due ruoli: Central (dispositivo mobile) e Peripheral (dispositivo). Central scansiona le onde e avvia la connessione, mentre Peripheral trasmette dati. A differenza del Bluetooth classico, BLE non è progettato per flussi audio — il suo compito è trasmettere piccoli pacchetti con un consumo energetico minimo. Secondo Bluetooth SIG Core Specification 5.4 (2025), BLE supporta velocità fino a 2 Mbps con una corrente inferiore a 15 mA in modalità attiva.
GATT (Generic Attribute Profile) definisce la struttura dei dati di Bluetooth Low Energy. Service è un gruppo logico di caratteristiche (ad esempio, Heart Rate Service 0x180D). Characteristic è un punto dati con un valore specifico. Descriptor sono metadati della caratteristica, incluso CCCD per la gestione delle notifiche. Ogni elemento ha un UUID — 16 bit per profili standard Bluetooth SIG o 128 bit per personalizzati.
Bluetooth Low Energy nelle applicazioni mobili utilizza questa gerarchia per organizzare lo scambio di dati tra smartphone e periferiche. Una corretta comprensione di GATT è la base per lo sviluppo di applicazioni BLE su entrambe le piattaforme. Lo sviluppatore deve conoscere gli UUID dei servizi e delle caratteristiche del dispositivo, nonché le proprietà di ciascuna caratteristica (read, write, notify, indicate).
I dispositivi BLE trasmettono pacchetti pubblicitari (advertising packets) per il rilevamento. Advertising Data contiene il nome del dispositivo, gli UUID dei servizi, RSSI e Manufacturer Specific Data. La dimensione del pacchetto pubblicitario è limitata a 31 byte. Per trasmettere dati aggiuntivi, viene utilizzato Scan Response — un secondo pacchetto che il dispositivo centrale richiede dopo il rilevamento.
Su iOS, il framework Core Bluetooth gestisce Bluetooth Low Energy. CBCentralManager gestisce la scansione e la connessione, CBPeripheral rappresenta un dispositivo BLE remoto. Il processo è standard: inizializzare CBCentralManager, verificare lo stato poweredOn, avviare scanForPeripherals, connettersi e scoprire i servizi. Core Bluetooth gestisce automaticamente l'alimentazione del modulo radio — se BLE non è in uso, si spegne.
BLE nello sviluppo mobile su iOS richiede la considerazione delle modalità background. La modalità background di Core Bluetooth viene attivata tramite le Capabilities del progetto (Uses Bluetooth LE accessories). In background, l'app può ricevere notifiche dalle caratteristiche, ma la scansione è limitata — il sistema la riavvia solo quando il dispositivo si muove. Per iBeacon, la scansione in background funziona più attivamente tramite CLLocationManager.
import CoreBluetooth
class DeviceScanner: NSObject, CBCentralManagerDelegate {
var centralManager: CBCentralManager!
func start() {
centralManager = CBCentralManager(delegate: self, queue: nil)
}
func centralManagerDidUpdateState(_ central: CBCentralManager) {
guard central.state == .poweredOn else { return }
central.scanForPeripherals(withServices: nil, options: nil)
}
func centralManager(_ central: CBCentralManager,
didDiscover peripheral: CBPeripheral,
advertisementData: [String: Any],
rssi RSSI: NSNumber) {
print("Trovato: \(peripheral.name ?? "unknown")")
}
}
In questo esempio, CBCentralManagerDelegate gestisce tutti gli eventi di connessione BLE. Il metodo centralManagerDidUpdateState verifica se Bluetooth è attivato sul dispositivo mobile. Dopo l'inizializzazione riuscita, viene avviata la scansione. Il callback didDiscover viene invocato per ogni dispositivo trovato.
Dopo aver scoperto un dispositivo, è necessario chiamare connect e discoverServices. CBPeripheralDelegate fornisce metodi per gestire ogni passaggio: didDiscoverServices, didDiscoverCharacteristics, didUpdateValueFor. Ogni metodo è asincrono — i dati arrivano tramite callback delegati. RSSI (Received Signal Strength Indicator) mostra il livello del segnale: più il valore è vicino a 0, più forte è il segnale.
Su Android, Bluetooth Low Energy è implementato tramite il pacchetto android.bluetooth. BluetoothAdapter è il punto di ingresso per tutte le operazioni BLE. BluetoothLeScanner avvia la scansione con callback ScanCallback. Dopo aver scoperto un dispositivo, viene creato BluetoothGatt — una connessione alla periferica. BluetoothGattCallback gestisce gli eventi: connessione, scoperta dei servizi, lettura delle caratteristiche, cambiamenti RSSI.
Bluetooth Low Energy nelle applicazioni mobili su Android richiede autorizzazioni esplicite BLUETOOTH_SCAN, BLUETOOTH_CONNECT e ACCESS_FINE_LOCATION. Da Android 12, le autorizzazioni sono separate: BLUETOOTH_SCAN per la scansione, BLUETOOTH_CONNECT per la connessione. ACCESS_FINE_LOCATION è necessaria solo per scansionare determinati tipi di dispositivi. Senza queste autorizzazioni, l'app non può funzionare con BLE.
class BLEScanner(private val bluetoothAdapter: BluetoothAdapter) {
fun startScan() {
val scanner = bluetoothAdapter.bluetoothLeScanner
val settings = ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build()
scanner.startScan(null, settings, scanCallback)
}
private val scanCallback = object : ScanCallback() {
override fun onScanResult(callbackType: Int, result: ScanResult) {
val device = result.device
val rssi = result.rssi
Log.d("BLE", "Dispositivo: ${device.name}, RSSI: $rssi")
}
}
}
ScanSettings consente di configurare la modalità di scansione: LOW_POWER per risparmiare batteria, BALANCED per attività standard, LOW_LATENCY per la massima velocità di rilevamento. ScanFilter restringe la ricerca per UUID del servizio, nome del dispositivo o indirizzo MAC. Il filtraggio riduce il consumo energetico e accelera il rilevamento del dispositivo desiderato.
Dopo aver creato BluetoothGatt tramite connectGatt, l'app chiama discoverServices. BluetoothGattCallback contiene onServicesDiscovered, onCharacteristicRead, onCharacteristicChanged. Per ricevere notifiche sulle modifiche delle caratteristiche, è necessario chiamare setCharacteristicNotification. Il processo richiede attenzione: ogni operazione GATT è asincrona e il risultato arriva in un callback separato.
iBeacon è la tecnologia di Apple per beacon BLE che trasmettono UUID, Major e Minor. Il dispositivo beacon trasmette un pacchetto pubblicitario e l'applicazione mobile determina posizione e distanza in base a questi dati. Su iOS, iBeacon è supportato nativamente tramite CLLocationManager. Su Android è necessaria una libreria di terze parti (ad esempio, AltBeacon o Android iBeacon Library).
Bonding è la procedura per creare una connessione sicura permanente tra dispositivi BLE. Dopo il Bonding, le chiavi di crittografia vengono salvate e i dispositivi si connettono automaticamente quando tornano in prossimità. Su iOS, il bonding è gestito automaticamente dal sistema. Su Android — tramite BluetoothDevice.createBond(). Il bonding è importante per dispositivi indossabili e fitness tracker che richiedono una riconnessione rapida.
Advertising Data è un meccanismo chiave di rilevamento in Bluetooth Low Energy. I produttori di dispositivi possono aggiungere Manufacturer Specific Data al pacchetto pubblicitario per trasmettere dati personalizzati. Il formato del pacchetto include un Company Identifier (2 byte) e dati arbitrari. Su iOS, CBCentralManager accetta un array di UUID di servizi per il filtraggio — questo risparmia batteria. Su Android, ScanFilter funziona sullo stesso principio.
| Parametro | iOS (Core Bluetooth) | Android (BluetoothGatt) |
|---|---|---|
| Gestore | CBCentralManager | BluetoothLeScanner |
| Connessione | connect(to:) | connectGatt() |
| Servizi | discoverServices() | discoverServices() |
| Lettura | readValue(for:) | readCharacteristic() |
| Notifiche | setNotifyValue(_:for:) | setCharacteristicNotification() |
| Autorizzazioni | Automatiche | BLUETOOTH_SCAN, BLUETOOTH_CONNECT |
| iBeacon | CLLocationManager (nativo) | AltBeacon / librerie |
MTU (Maximum Transmission Unit) è la dimensione massima di un singolo pacchetto di dati Bluetooth Low Energy. Per impostazione predefinita, MTU è di 23 byte (3 byte di intestazione + 20 byte di dati). L'aumento dell'MTU a 512 byte accelera significativamente la trasmissione durante lo scambio di configurazioni o log. Su iOS, maximumWriteValueLength mostra l'MTU disponibile. Su Android, requestMtu() viene utilizzato per aumentare l'MTU.
Connection Interval è la frequenza con cui il dispositivo centrale interroga la periferica. Più breve è l'intervallo, maggiore è la velocità di trasmissione, ma anche il consumo energetico. I valori tipici vanno da 7,5 ms a 4 secondi. Per i fitness tracker, 100 ms sono sufficienti; per l'audio — 7,5 ms. Il BLE nello sviluppo mobile richiede un equilibrio tra velocità di trasmissione e durata della batteria del dispositivo.
iOS supporta BLE in modalità background tramite Background Modes, ma con limitazioni. Un'app in background riceve notifiche dalle caratteristiche ma non può scansionare attivamente. Il sistema riavvia la scansione quando la posizione del dispositivo cambia. Su Android, la scansione in background richiede un Foreground Service con una notifica persistente. Senza di esso, il sistema mobile ucciderà il processo durante la minimizzazione dell'app.
Per un funzionamento affidabile del BLE nelle applicazioni mobili, seguire queste regole. Usare notify invece del polling — una caratteristica con notifiche invia dati quando cambia, risparmiando batteria. Impostare l'MTU ottimale all'inizio della connessione. Filtrare i dispositivi per UUID del servizio durante la scansione. Verificare la compatibilità dello stack BLE su diversi modelli — i produttori (Xiaomi, Huawei, Samsung) apportano modifiche che influenzano il comportamento del Bluetooth.
Domande Frequenti
Bluetooth Low Energy (BLE) è ottimizzato per la trasmissione periodica di piccoli pacchetti con basso consumo energetico. Bluetooth classico è progettato per flussi audio e trasmissione continua di grandi volumi di dati.
GATT (Generic Attribute Profile) è un protocollo di scambio dati in BLE che definisce la gerarchia Service → Characteristic → Descriptor. GATT viene utilizzato per leggere, scrivere e ricevere notifiche dai dispositivi BLE.
Prima di Android 12, la scansione BLE poteva essere utilizzata per determinare la posizione, quindi Google ha combinato queste autorizzazioni. Da Android 12, è stata introdotta un'autorizzazione separata BLUETOOTH_SCAN senza legame con la posizione.
Aumentare l'MTU tramite requestMtu() su Android e maximumWriteValueLength su iOS. Connection Interval influisce anche sulla velocità — più è piccolo, più veloce è il trasferimento. La combinazione ottimale fornisce un miglioramento fino a 10 volte.
Bonding è la procedura per creare una connessione sicura permanente tra dispositivi BLE. Dopo il Bonding, le chiavi di crittografia vengono salvate e i dispositivi si connettono automaticamente senza ricerca ripetuta.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.