Bluetooth

Questo documento descrive come utilizzare le API Bluetooth, Presa Bluetooth e Bluetooth Low Energy per comunicare con i dispositivi Bluetooth e Bluetooth Low Energy.

Per informazioni di base sul Bluetooth, consulta le specifiche relative al Bluetooth ufficiali.

Requisiti del file manifest

Per le app di Chrome che utilizzano il Bluetooth, aggiungi la voce bluetooth al file manifest e specifica, se opportuno, gli UUID di profili, protocolli o servizi che vuoi implementare e se vuoi implementarli con il socket e/o le API Low Energy.

Ad esempio per un'implementazione socket:

"bluetooth": {
  "uuids": [ "1105", "1106" ],
  "socket": true
}

Per un'implementazione Low Energy:

"bluetooth": {
  "uuids": [ "180D", "1809", "180F" ],
  "low_energy": true
}

Per accedere solo allo stato dell'adattatore, rilevare i dispositivi nelle vicinanze e ottenere informazioni di base sui dispositivi, è necessaria solo la voce stessa:

"bluetooth": {}

Informazioni sull'adattatore

Recupero dello stato dell'adattatore in corso...

Per conoscere lo stato dell'adattatore Bluetooth, utilizza il metodo bluetooth.getAdapterState:

chrome.bluetooth.getAdapterState(function(adapter) {
  console.log("Adapter " + adapter.address + ": " + adapter.name);
});

Notifiche dell'adattatore

L'evento bluetooth.onAdapterStateChanged viene inviato ogni volta che lo stato dell'adattatore cambia. Questa funzione può essere utilizzata, ad esempio, per determinare quando accendere o spegnere la radio dell'adattatore.

var powered = false;
chrome.bluetooth.getAdapterState(function(adapter) {
  powered = adapter.powered;
});

chrome.bluetooth.onAdapterStateChanged.addListener(
  function(adapter) {
    if (adapter.powered != powered) {
      powered = adapter.powered;
      if (powered) {
        console.log("Adapter radio is on");
      } else {
        console.log("Adapter radio is off");
      }
    }
  });

Informazioni del dispositivo

Elenco dei dispositivi noti

Per ottenere un elenco dei dispositivi noti per l'adattatore Bluetooth, utilizza il metodo bluetooth.getDevices:

chrome.bluetooth.getDevices(function(devices) {
  for (var i = 0; i < devices.length; i++) {
    console.log(devices[i].address);
  }
});

Vengono restituiti tutti i dispositivi, inclusi quelli accoppiati e quelli rilevati di recente. Il rilevamento di nuovi dispositivi non verrà avviato (vedi Rilevamento di dispositivi nelle vicinanze).

Ricezione di notifiche sul dispositivo

Anziché chiamare ripetutamente bluetooth.getDevices, puoi utilizzare gli eventi bluetooth.onDeviceAdded, bluetooth.onDeviceChanged e bluetooth.onDeviceRemoved per ricevere notifiche.

L'evento bluetooth.onDeviceAdded viene inviato ogni volta che un dispositivo viene rilevato dall'adattatore o effettua una connessione all'adattatore:

chrome.bluetooth.onDeviceAdded.addListener(function(device) {
  console.log(device.address);
});

L'aggiunta di un listener per questo evento non avvia il rilevamento dei dispositivi (vedi Rilevamento di dispositivi nelle vicinanze).

Le modifiche ai dispositivi, inclusi i dispositivi rilevati in precedenza che vengono accoppiati, vengono notificate dall'evento bluetooth.onDeviceChanged:

chrome.bluetooth.onDeviceChanged.addListener(function(device) {
  console.log(device.address);
});

Infine, l'evento bluetooth.onDeviceRemoved viene inviato ogni volta che un dispositivo accoppiato viene rimosso dal sistema o un dispositivo rilevato non è stato rilevato di recente:

chrome.bluetooth.onDeviceRemoved.addListener(function(device) {
  console.log(device.address);
});

Rilevamento di dispositivi nelle vicinanze

Per iniziare il rilevamento dei dispositivi nelle vicinanze, utilizza il metodo bluetooth.startDiscovery. Il rilevamento può richiedere molte risorse, quindi devi chiamare bluetooth.stopDiscovery una volta terminato.

Devi chiamare bluetooth.startDiscovery ogni volta che la tua app ha bisogno di rilevare i dispositivi nelle vicinanze. Non rendere condizionale la chiamata nella proprietà discovering di bluetooth.AdapterState. La chiamata avrà esito positivo anche se un'altra app sta rilevando dispositivi nelle vicinanze e garantirà che l'adattatore continui a eseguire il rilevamento dopo l'interruzione dell'altra app.

Le informazioni su ogni dispositivo appena rilevato vengono ricevute utilizzando l'evento bluetooth.onDeviceAdded. Per i dispositivi che sono già stati rilevati di recente o che sono stati precedentemente accoppiati o a cui sono stati connessi, l'evento non verrà inviato. Devi chiamare bluetooth.getDevices per ottenere le informazioni attuali e utilizzare l'evento bluetooth.onDeviceChanged per ricevere notifiche sulle modifiche apportate a queste informazioni in seguito al rilevamento.

Esempio:

var device_names = {};
var updateDeviceName = function(device) {
  device_names[device.address] = device.name;
};
var removeDeviceName = function(device) {
  delete device_names[device.address];
}

// Add listeners to receive newly found devices and updates
// to the previously known devices.
chrome.bluetooth.onDeviceAdded.addListener(updateDeviceName);
chrome.bluetooth.onDeviceChanged.addListener(updateDeviceName);
chrome.bluetooth.onDeviceRemoved.addListener(removeDeviceName);

// With the listeners in place, get the list of devices found in
// previous discovery sessions, or any currently active ones,
// along with paired devices.
chrome.bluetooth.getDevices(function(devices) {
  for (var i = 0; i < devices.length; i++) {
    updateDeviceName(devices[i]);
  }
});

// Now begin the discovery process.
chrome.bluetooth.startDiscovery(function() {
  // Stop discovery after 30 seconds.
  setTimeout(function() {
    chrome.bluetooth.stopDiscovery(function() {});
  }, 30000);
});

Se l'utente disattiva la radio Bluetooth, tutte le sessioni di rilevamento verranno terminate e non riprenderanno automaticamente quando la radio viene accesa. Se questo è importante per la tua app, dovresti guardare l'evento bluetooth.onAdapterStateChanged. Se la proprietà discovering passa a false, la tua app dovrà chiamare di nuovo bluetooth.startDiscovery per riprendere. Fai attenzione alla natura delle scoperte che richiedono molte risorse.

Identificare i dispositivi

Vengono fornite diverse opzioni per identificare i dispositivi restituiti da bluetooth.getDevices e i relativi eventi.

Se il dispositivo supporta la specifica ID dispositivo Bluetooth, vengono aggiunte diverse proprietà all'oggetto Device contenente i campi definiti da tale specifica. Esempio:

chrome.bluetooth.getDevices(function(devices) {
  for (var i = 0; i < devices.length; i++) {
    if (devices[0].vendorIdSource != undefined) {
      console.log(devices[0].address + ' = ' +
                  devices[0].vendorIdSource + ':' +
                  devices[0].vendorId.toString(16) + ':' +
                  devices[0].productId.toString(16) + ':' +
                  devices[0].deviceId.toString(16));
    }
  }
});

La specifica dell'ID dispositivo di solito è sufficiente per identificare un particolare modello e persino la revisione di un dispositivo di un fornitore. Se non è presente, devi invece basarti sulle informazioni sulla classe o sul tipo di dispositivo, facoltativamente combinate con il prefisso del produttore nell'attributo address.

La maggior parte dei dispositivi Bluetooth fornisce informazioni sulla classe dei dispositivi come un campo di bit interpretato in base al documento Baseband Assigned Numbers (Numeri assegnati a banda base). Questo campo di bit è disponibile nella proprietà deviceClass.

chrome.bluetooth.getDevices(function(devices) {
  for (var i = 0; i < devices.length; i++) {
    if (devices[0].vendorIdSource != undefined) {
      console.log(devices[0].address + ' = ' +
                  devices[0].deviceClass.toString(16));
    }
  }
});

L'analisi del campo può essere complessa, quindi Chrome imposta il campo type per i tipi di dispositivi più comuni. Se non è disponibile o non soddisfa le tue esigenze, dovrai analizzare deviceClass in modo autonomo.

chrome.bluetooth.getDevices(function(devices) {
  for (var i = 0; i < devices.length; i++) {
    if (devices[0].vendorIdSource != undefined) {
      console.log(devices[0].address + ' = ' + devices[0].type);
    }
  }
});

Utilizzo di RFCOMM e L2CAP

Le App di Chrome potrebbero stabilire connessioni a qualsiasi dispositivo che supporti i servizi RFCOMM o L2CAP. Ciò include la maggior parte dei dispositivi Bluetooth classici sul mercato.

Collegamento a una presa

Per eseguire la connessione a un dispositivo, hai bisogno di tre cose. Un socket con cui stabilire la connessione, creato utilizzando bluetoothSocket.create, l'indirizzo del dispositivo a cui vuoi connetterti e l'UUID del servizio stesso.

Prima di effettuare la connessione, devi verificare che l'adattatore conosca il dispositivo utilizzando bluetooth.getDevice o le API di rilevamento del dispositivo.

Le informazioni necessarie per stabilire la connessione di base, inclusa se è necessario utilizzare il protocollo RFCOMM o L2CAP e quale canale o PSM, vengono ottenute mediante il rilevamento SDP sul dispositivo.

Esempio:

var uuid = '1105';
var onConnectedCallback = function() {
  if (chrome.runtime.lastError) {
    console.log("Connection failed: " + chrome.runtime.lastError.message);
  } else {
    // Profile implementation here.
  }
};

chrome.bluetoothSocket.create(function(createInfo) {
  chrome.bluetoothSocket.connect(createInfo.socketId,
    device.address, uuid, onConnectedCallback);
});

Mantieni un handle al socketId in modo da poter inviare dati (bluetoothSocket.send) a questo socket in un secondo momento.

Ricezione da e invio a un socket

La ricezione di dati da e l'invio a un socket utilizza oggetti ArrayBuffer. Per informazioni su ArrayBuffers, consulta la panoramica sugli array di tipo JavaScript e il tutorial Come convertire Arraybu da e verso una stringa.

Per inviare i dati presenti in arrayBuffer utilizza bluetoothSocket.send:

chrome.bluetoothSocket.send(socketId, arrayBuffer, function(bytes_sent) {
  if (chrome.runtime.lastError) {
    console.log("Send failed: " + chrome.runtime.lastError.message);
  } else {
    console.log("Sent " + bytes_sent + " bytes")
  }
})

A differenza del metodo per inviare i dati, i dati vengono ricevuti in un evento (bluetoothSocket.onReceive. I socket vengono creati non in pausa (vedi bluetoothSocket.setPaused) quindi il listener di questo evento solitamente viene aggiunto tra bluetoothSocket.create e bluetoothSocket.connect.

chrome.bluetoothSocket.onRecieve.addListener(function(receiveInfo) {
  if (receiveInfo.socketId != socketId)
    return;
  // receiveInfo.data is an ArrayBuffer.
});

Errori di ricezione e disconnessione del socket

Per ricevere notifiche in caso di errori socket, inclusa la disconnessione, aggiungi un listener all'evento bluetoothSocket.onReceiveError.

chrome.bluetoothSocket.onReceiveError.addListener(function(errorInfo) {
  // Cause is in errorInfo.error.
  console.log(errorInfo.errorMessage);
});

Disconnessione da una presa di corrente

Per terminare la connessione e scollegare la presa, utilizza bluetoothSocket.disconnect.

chrome.bluetoothSocket.disconnect(socketId);

Servizi per l'editoria

Oltre a effettuare connessioni in uscita ai dispositivi, le App di Chrome potrebbero pubblicare servizi che potrebbero essere utilizzati da qualsiasi dispositivo che supporti RFCOMM o L2CAP.

Ascolto su una presa

Sono supportati due tipi di servizi pubblicati. RFCOMM è la più utilizzata e copre la maggior parte dei dispositivi e dei profili:

var uuid = '1105';
chrome.bluetoothSocket.create(function(createInfo) {
  chrome.bluetoothSocket.listenUsingRfcomm(createInfo.socketId,
    uuid, onListenCallback);
});

L2CAP è l'altro e riguarda altri tipi di dispositivi e utilizzi specifici del fornitore, come il caricamento del firmware.

var uuid = '0b87367c-f188-47cd-bc20-a5f4f70973c6';
chrome.bluetoothSocket.create(function(createInfo) {
  chrome.bluetoothSocket.listenUsingL2cap(createInfo.socketId,
    uuid, onListenCallback);
});

In entrambi i casi, può essere passato un bluetoothSocket.ListenOptions facoltativo per allocare un canale o un PSM specifico. Il callback indica un errore tramite chrome.runtime.lastError e, in caso contrario, l'esito positivo. Mantieni un handle al socketId in modo da poter accettare le connessioni (bluetoothSocket.onAccept) in un secondo momento da questo socket.

Accettazione delle connessioni client in corso...

Le connessioni client vengono accettate e passate alla tua applicazione tramite l'evento bluetoothSocket.onAccept.

chrome.bluetoothSocket.onAccept.addListener(function(acceptInfo) {
  if (info.socketId != serverSocketId)
    return;

  // Say hello...
  chrome.bluetoothSocket.send(acceptInfo.clientSocketId,
    data, onSendCallback);

  // Accepted sockets are initially paused,
  // set the onReceive listener first.
  chrome.bluetoothSocket.onReceive.addListener(onReceive);
  chrome.bluetoothSocket.setPaused(false);
});

Smetti di accettare connessioni client

Per interrompere l'accettazione delle connessioni client e annullare la pubblicazione del servizio, utilizza bluetoothSocket.disconnect.

chrome.bluetoothSocket.disconnect(serverSocketId);

Interazione con dispositivi a bassa energia

Bluetooth Low Energy o (Bluetooth Smart) è una tecnologia wireless finalizzata a ridurre il consumo di energia. L'API Bluetooth Low Energy consente alle applicazioni di implementare il ruolo centrale in una connessione LE a una periferica. Le seguenti sezioni descrivono come scoprire e interagire con le periferiche Bluetooth Low Energy.

Rilevamento e connessione alle periferiche

Come con i dispositivi Bluetooth tradizionali, le periferiche LE possono essere rilevate utilizzando i metodi descritti nella sezione Rilevamento dei dispositivi nelle vicinanze . Un dispositivo LE si rende rilevabile inviando pacchetti di dati chiamati "Dati pubblicitari" e si dice che sia in modalità pubblicitaria. I dati pubblicitari potrebbero contenere gli UUID dei servizi disponibili sul dispositivo. Se presenti, questi UUID saranno accessibili utilizzando la proprietà uuids dell'oggetto bluetooth.Device corrispondente.

Una volta rilevato, è possibile connettere un dispositivo LE chiamando bluetoothLowEnergy.connect in modo che l'applicazione possa interagire con i propri servizi:

chrome.bluetooth.onDeviceAdded.addListener(function(device) {
  var uuid = '0000180d-0000-1000-8000-00805f9b34fb';
  if (!device.uuids || device.uuids.indexOf(uuid) < 0)
    return;

  // The device has a service with the desired UUID.
  chrome.bluetoothLowEnergy.connect(device.address, function () {
    if (chrome.runtime.lastError) {
      console.log('Failed to connect: ' + chrome.runtime.lastError.message);
      return;
    }

    // Connected! Do stuff...
    ...
  });
});

Dopo la connessione, la proprietà connected dell'oggetto bluetooth.Device corrispondente avrà il valore true. La chiamata a bluetoothLowEnergy.connect stabilisce una richiesta da parte dell'applicazione sulla connessione fisica al dispositivo. Può esistere una connessione fisica al dispositivo senza mai chiamare bluetoothLowEnergy.connect (ad esempio a causa di un'altra applicazione). In questo caso, anche se la tua applicazione può comunque interagire con i servizi del dispositivo, dovrebbe chiamare sempre bluetoothLowEnergy.connect per impedire a un'altra applicazione di disconnettere il link fisico.

Una volta che l'applicazione non deve più essere connessa, può rimuovere la sua richiesta di connessione chiamando bluetoothLowEnergy.disconnect:

chrome.bluetoothLowEnergy.disconnect(deviceAddress);

Tieni presente che ciò non distruggerà necessariamente il collegamento fisico al dispositivo, poiché potrebbero esserci altre applicazioni che hanno connessioni attive al dispositivo. A volte il dispositivo potrebbe disconnettersi per motivi che esulano dal controllo dell'applicazione (ad esempio se il dispositivo scompare o viene esplicitamente disconnesso dall'utente tramite utilità del sistema operativo). L'applicazione deve osservare l'evento bluetooth.onDeviceChanged per ricevere una notifica delle modifiche alla connessione e riconnettersi, se necessario.

Una volta connesso, il dispositivo su cui è in esecuzione Chrome sarà nel cosiddetto ruolo centrale, mentre il dispositivo remoto avrà il ruolo periferica. A questo punto, l'applicazione può interagire con i servizi sul dispositivo utilizzando i metodi descritti nella sezione seguente. Nota: le API attualmente non supportano il funzionamento come periferica LE; le app possono implementare solo il ruolo centrale.

Servizi, caratteristiche e descrittori

Bluetooth Low Energy si basa su un semplice protocollo richiesta-risposta chiamato Attribute Protocol (ATT). Utilizzando l'ATT, un dispositivo centrale interagisce con i cosiddetti attributi su un dispositivo periferico conforme a uno speciale profilo Bluetooth chiamato GATT (Generic Attribute Profile). GATT definisce i seguenti concetti generali:

  • Servizio: un servizio GATT rappresenta una raccolta di dati e comportamenti associati per svolgere una determinata funzione di un dispositivo. Ad esempio, un cardiofrequenzimetro avrà in genere almeno un "Servizio del battito cardiaco". Le informazioni su un servizio GATT sono contenute in un oggetto bluetoothLowEnergy.Service.
  • Caratteristica: una caratteristica GATT è un elemento dati di base utilizzato per costruire un servizio GATT, contenente un valore e proprietà che definiscono la modalità di accesso a tale valore. Ad esempio, il "Servizio della frequenza cardiaca" ha la caratteristica "Misurazione della frequenza cardiaca", che viene utilizzata per ottenere il valore della frequenza cardiaca dell'utente. Le informazioni su una caratteristica GATT sono contenute in un oggetto bluetoothLowEnergy.Characteristic.
  • Descrittore: un descrittore della caratteristica GATT contiene ulteriori informazioni su una caratteristica. Le informazioni su un descrittore della caratteristica GATT sono contenute in un oggetto bluetoothLowEnergy.Descriptor.

L'API Bluetooth Low Energy consente alle applicazioni di trovare informazioni su servizi, caratteristiche e descrittori di un dispositivo chiamando bluetoothLowEnergy.getServices, bluetoothLowEnergy.getCharacteristics e bluetoothLowEnergy.getDescriptors. Le app possono filtrare i servizi, le caratteristiche e i descrittori confrontando il relativo campo uuid con l'UUID GATT desiderato:

chrome.bluetoothLowEnergy.getServices(deviceAddress, function(services) {
  ...
  for (var i = 0; i < services.length; i++) {
    if (services[i].uuid == HEART_RATE_SERVICE_UUID) {
      heartRateService = services[i];
      break;
    }
  }
  ...
});

A ogni servizio, caratteristica e descrittore accessibile tramite l'API viene assegnato un identificatore di istanza univoco, che può essere ottenuto utilizzando il campo instanceId. Questo ID istanza può essere utilizzato per identificare un oggetto GATT ed eseguire operazioni specifiche su di esso:

chrome.bluetoothLowEnergy.getCharacteristics(heartRateService.instanceId,
                                             function(chracteristics) {
  ...
  for (var i = 0; i < characteristics.length; i++) {
    if (characteristics[i].uuid == HEART_RATE_MEASUREMENT_UUID) {
      measurementChar = characteristics[i];
      break;
    }
  }
  ...
  chrome.bluetoothLowEnergy.getDescriptors(measurementChar.instanceId,
                                           function(descriptors) {
    ...
  });
});

Eventi di servizio

Quando un dispositivo è connesso, Chrome ne rileva i servizi. Man mano che ogni servizio viene rilevato e rimosso, l'applicazione riceverà gli eventi bluetoothLowEnergy.onServiceAdded e bluetoothLowEnergy.onServiceRemoved:

  var initializeService = function(service) {
    if (!service) {
      console.log('No service selected!');
      // Reset UI, etc.
      ...
      return;
    }

    myService = service;

    // Get all the characteristics and descriptors and bootstrap the app.
    ...
  };

  chrome.bluetoothLowEnergy.onServiceAdded.addListener(function(service) {
    if (service.uuid == MY_SERVICE_UUID)
      initializeService(service);
  });

  chrome.bluetoothLowEnergy.onServiceRemoved.addListener(function(service) {
    if (service.instanceId == myService.instanceId)
      initializeService(null);
  });

Chrome rileva tutte le caratteristiche e i descrittori di un servizio in modo asincrono e invia l'evento bluetoothLowEnergy.onServiceAdded al termine del rilevamento. Se la connessione a una periferica termina, Chrome rimuove tutti i servizi correlati e invia l'evento bluetoothLowEnergy.onServiceRemoved.

Alcune periferiche possono modificare i propri servizi, ad esempio le caratteristiche di un servizio potrebbero cambiare o i servizi potrebbero essere aggiunti e rimossi completamente. Chrome avvisa le app di queste modifiche utilizzando gli eventi bluetoothLowEnergy.onServiceChanged, bluetoothLowEnergy.onServiceAdded e bluetoothLowEnergy.onServiceRemoved.

  chrome.bluetoothLowEnergy.onServiceChanged.addListener(function(service) {
    if (service.instanceId != myService.instanceId)
      return;

    updateMyService(service);
  });

Leggere e scrivere il valore di una caratteristica

Una caratteristica GATT codifica un aspetto del suo servizio. Un'app centrale legge, agisce e modifica lo stato del servizio di una periferica operando sul valore di una caratteristica. Il valore della caratteristica è una sequenza di byte e il suo significato è definito dalla specifica di alto livello che definisce una determinata caratteristica. Ad esempio, il valore della caratteristica Misurazione della frequenza cardiaca codifica la frequenza cardiaca dell'utente e la quantità totale di calorie bruciate, mentre la caratteristica Posizione sensore del corpo codifica il punto del corpo in cui deve essere indossato il sensore del battito cardiaco.

Chrome fornisce il metodo bluetoothLowEnergy.readCharacteristicValue per leggere il valore di una caratteristica:

chrome.bluetoothLowEnergy.readCharacteristicValue(chrc.instanceId,
                                                  function(result) {
  if (chrome.runtime.lastError) {
    console.log('Failed to read value: ' + chrome.runtime.lastError.message);
    return;
  }

  var bytes = new Uint8Array(result.value);

  // Do stuff with the bytes.
  ...
});

Alcune caratteristiche sono scrivibili, soprattutto quelle che si comportano come "punti di controllo", dove la scrittura del valore ha effetti collaterali. Ad esempio, la caratteristica Punto di controllo della frequenza cardiaca viene utilizzata per comunicare a un sensore del battito cardiaco di reimpostare il conteggio delle calorie totali bruciate e supporta solo le scritture. A tale scopo, Chrome fornisce il metodo bluetoothLowEnergy.writeCharacteristicValue:

var myBytes = new Uint8Array([ ... ]);
chrome.bluetoothLowEnergy.writeCharacteristicValue(chrc.instanceId,
                                                   myBytes.buffer,
                                                   function() {
  if (chrome.runtime.lastError) {
    console.log('Failed to write value: ' +
                chrome.runtime.lastError.message);
    return;
  }

  // Value is written now.
});

I descrittori caratteristici si comportano allo stesso modo e possono essere leggibili e/o scrivibili. Chrome fornisce i metodi bluetoothLowEnergy.readDescriptorValue e bluetoothLowEnergy.writeDescriptorValue per leggere e scrivere il valore di un descrittore.

Per verificare se una caratteristica supporta le letture o le scritture, un'applicazione può controllare il campo properties di un oggetto bluetoothLowEnergy.Characteristic. Questo campo non contiene informazioni sui requisiti di sicurezza per accedere a un valore, ma descrive quale operazione sul valore è supportata in generale dalla caratteristica.

Gestione delle notifiche relative ai valori

Alcune caratteristiche rendono noto il loro valore tramite notifiche o indicazioni. Ad esempio, la caratteristica Misurazione della frequenza cardiaca non è né leggibile né scrivibile, ma invia aggiornamenti sul suo valore corrente a intervalli regolari. Le applicazioni possono ascoltare queste notifiche utilizzando l'evento bluetoothLowEnergy.onCharacteristicValueChanged.

  chrome.bluetoothLowEnergy.onCharacteristicValueChanged.addListener(
      function(chrc) {
    if (chrc.instanceId != myCharId)
      return;

    var bytes = new Uint8Array(chrc.value);

    // Do stuff with the bytes.
    ...
  });

Anche se una caratteristica supporta notifiche/indicazioni, queste non sono attive per impostazione predefinita. Un'applicazione deve chiamare i metodi bluetoothLowEnergy.startCharacteristicNotifications e bluetoothLowEnergy.stopCharacteristicNotifications per avviare o interrompere la ricezione dell'evento bluetoothLowEnergy.onCharacteristicValueChanged.

  // Start receiving characteristic value notifications.
  var notifying = false;
  chrome.bluetoothLowEnergy.startCharacteristicNotifications(chrc.instanceId,
                                                             function() {
    if (chrome.runtime.lastError) {
      console.log('Failed to enable notifications: ' +
                  chrome.runtime.lastError.message);
      return;
    }

    notifying = true;
  });

  ...

  // No longer interested in notifications from this characteristic.
  if (notifying) {
    chrome.bluetoothLowEnergy.stopCharacteristicNotifications(
        chrc.instanceId);
  }

Una volta avviate le notifiche, l'applicazione riceverà bluetoothLowEnergy.onCharacteristicValueChanged ogni volta che viene ricevuta una notifica o un'indicazione dalla caratteristica. Se la caratteristica supporta le letture, questo evento verrà inviato anche dopo una chiamata riuscita a bluetoothLowEnergy.readCharacteristicValue. Ciò consente alle app di unificare il flusso di controllo di un aggiornamento di valore attivato tramite una richiesta di lettura e notifiche:

  chrome.bluetoothLowEnergy.onCharacteristicValueChanged.addListener(
      function(chrc) {
    // Process the value.
    ...
  });

  chrome.bluetoothLowEnergy.startCharacteristicNotifications(chrc.instanceId,
                                                             function() {
    // Notifications started. Read the initial value.
    chrome.bluetoothLowEnergy.readCharacteristicValue(chrc.instanceId,
                                                      function(result) {
      ...
      // No need to do anything here since onCharacteristicValueChanged
      // will handle it.
    });
  });

Se una caratteristica supporta le notifiche, il relativo campo properties conterrà la proprietà "notify" o "indicate".

NOTA: se una caratteristica supporta notifiche/indicazioni, avrà il descrittore "Configurazione caratteristica client" per attivare/disattivare le notifiche. Chrome non consente alle app di scrivere in questo descrittore. Le app devono invece utilizzare i metodi bluetoothLowEnergy.startCharacteristicNotifications e bluetoothLowEnergy.stopCharacteristicNotifications per controllare il comportamento delle notifiche.