Bluetooth

Ce document explique comment utiliser les API Bluetooth, Bluetooth Socket et Bluetooth Low Energy pour communiquer avec les appareils Bluetooth et Bluetooth Low Energy.

Pour en savoir plus sur le Bluetooth, consultez les spécifications officielles du Bluetooth.

Exigences du fichier manifeste

Pour les applications Chrome qui utilisent le Bluetooth, ajoutez l'entrée bluetooth au fichier manifeste et spécifiez, le cas échéant, les UUID des profils, protocoles ou services que vous souhaitez implémenter, et indiquez si vous souhaitez les implémenter avec les API de socket et/ou les API à basse consommation.

Par exemple pour une implémentation de socket:

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

Et pour une mise en œuvre à faible consommation d'énergie:

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

Pour accéder uniquement à l'état de l'adaptateur, détecter les appareils à proximité et obtenir des informations de base sur les appareils, seule l'entrée proprement dite est requise:

"bluetooth": {}

Informations sur l'adaptateur

Obtenir l'état de l'adaptateur

Pour obtenir l'état de l'adaptateur Bluetooth, utilisez la méthode bluetooth.getAdapterState:

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

Notifications de l'adaptateur

L'événement bluetooth.onAdapterStateChanged est envoyé chaque fois que l'état de l'adaptateur change. Cela permet, par exemple, de déterminer quand le signal radio de l'adaptateur est mis sous tension ou hors tension.

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");
      }
    }
  });

Informations sur l'appareil

Lister les appareils connus

Pour obtenir la liste des appareils connus de l'adaptateur Bluetooth, utilisez la méthode bluetooth.getDevices:

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

Tous les appareils sont renvoyés, y compris les appareils associés et ceux récemment détectés. Elle ne commencera pas à détecter de nouveaux appareils (voir Découvrir les appareils à proximité).

Recevoir des notifications sur l'appareil

Au lieu d'appeler à plusieurs reprises bluetooth.getDevices, vous pouvez utiliser les événements bluetooth.onDeviceAdded, bluetooth.onDeviceChanged et bluetooth.onDeviceRemoved pour recevoir des notifications.

L'événement bluetooth.onDeviceAdded est envoyé chaque fois qu'un appareil est détecté par l'adaptateur ou établit une connexion avec l'adaptateur:

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

L'ajout d'un écouteur pour cet événement ne lance pas la détection des appareils (voir Découvrir les appareils à proximité).

Les modifications apportées aux appareils, y compris les appareils précédemment détectés en cours d'association, sont notifiées par l'événement bluetooth.onDeviceChanged:

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

Enfin, l'événement bluetooth.onDeviceRemoved est envoyé chaque fois qu'un appareil associé est supprimé du système ou qu'un appareil détecté n'a pas été vu récemment:

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

Détection des appareils à proximité

Pour commencer la détection des appareils à proximité, utilisez la méthode bluetooth.startDiscovery. La détection peut nécessiter beaucoup de ressources. Vous devez donc appeler bluetooth.stopDiscovery une fois l'opération terminée.

Vous devez appeler bluetooth.startDiscovery chaque fois que votre application doit détecter les appareils à proximité. Ne rendez pas l'appel conditionnel sur la propriété discovering de bluetooth.AdapterState. L'appel aboutit même si une autre application découvre des appareils à proximité, et il s'assure que l'adaptateur continue à effectuer la détection après l'arrêt de cette autre application.

Les informations sur chaque appareil nouvellement découvert sont reçues à l'aide de l'événement bluetooth.onDeviceAdded. L'événement ne sera pas envoyé pour les appareils qui ont déjà été détectés récemment, ou qui ont été associés ou connectés. À la place, vous devez appeler bluetooth.getDevices pour obtenir les informations actuelles et utiliser l'événement bluetooth.onDeviceChanged pour être informé des modifications apportées à ces informations à la suite de la découverte.

Exemple :

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);
});

Si l'utilisateur désactive le signal radio Bluetooth, toutes les sessions de découverte sont interrompues et ne reprennent pas automatiquement à l'activation du signal radio. Si cela est important pour votre application, vous devez surveiller l'événement bluetooth.onAdapterStateChanged. Si la propriété discovering passe à false, votre application devra à nouveau appeler bluetooth.startDiscovery pour reprendre. Méfiez-vous de la nature de la découverte, qui nécessite beaucoup de ressources.

Identifier les appareils

Un certain nombre d'options différentes sont fournies pour identifier les appareils renvoyés par bluetooth.getDevices et les événements associés.

Si l'appareil est compatible avec la spécification d'ID d'appareil Bluetooth, plusieurs propriétés sont ajoutées à l'objet Device contenant les champs définis par cette spécification. Exemple :

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 spécification de l'ID d'appareil suffit généralement à identifier un modèle particulier, voire une révision, d'un appareil auprès d'un fournisseur. S'il n'est pas présent, vous devez vous fier aux informations sur la classe ou le type d'appareil, éventuellement associés au préfixe du fabricant dans address.

La plupart des appareils Bluetooth fournissent des informations sur la classe de l'appareil sous la forme d'un champ de bits interprété conformément au document Numéros attribués par la bande de base. Ce champ de bits est disponible dans la propriété 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'analyse du champ peut être complexe. Pour les types d'appareils les plus courants, Chrome gère cela à votre place et définit le champ type. Si elle n'est pas disponible ou qu'elle est insuffisante pour vos besoins, vous devez analyser deviceClass vous-même.

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);
    }
  }
});

Utiliser RFCOMM et L2CAP

Les applications Chrome peuvent se connecter à tout appareil compatible avec les services RFCOMM ou L2CAP. Cela inclut la majorité des appareils Bluetooth classiques disponibles sur le marché.

Connexion à un socket

Pour établir une connexion avec un appareil, vous avez besoin de trois choses. Un socket créé à l'aide de bluetoothSocket.create : l'adresse du périphérique auquel vous souhaitez vous connecter et l'UUID du service lui-même.

Avant d'établir la connexion, vous devez vérifier que l'adaptateur reconnaît l'appareil à l'aide de bluetooth.getDevice ou des API de détection d'appareils.

Les informations nécessaires pour établir la connexion sous-jacente, y compris si le protocole RFCOMM ou L2CAP doit être utilisé, et le canal ou le PSM, sont obtenues via la découverte SDP sur l'appareil.

Exemple :

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);
});

Conservez un handle vers le socketId pour pouvoir envoyer ultérieurement des données (bluetoothSocket.send) à ce socket.

Recevoir et envoyer à un socket

La réception et l'envoi de données à un socket utilisent des objets ArrayBuffer. Pour en savoir plus sur les ArrayBuffers, consultez la présentation, les tableaux typés JavaScript, et le tutoriel Comment convertir un ArrayBuffer en String.

Pour envoyer les données de arrayBuffer, utilisez 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")
  }
})

Contrairement à la méthode d'envoi de données, les données sont reçues dans un événement (bluetoothSocket.onReceive. Les sockets sont créés réactivés (voir bluetoothSocket.setPaused). L'écouteur de cet événement est donc généralement ajouté entre bluetoothSocket.create et bluetoothSocket.connect.

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

Réception des erreurs et des déconnexions de socket

Pour être averti des erreurs de socket, y compris des déconnexions, ajoutez un écouteur à l'événement bluetoothSocket.onReceiveError.

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

Déconnexion d'un support

Pour raccrocher et débrancher le socket, utilisez bluetoothSocket.disconnect.

chrome.bluetoothSocket.disconnect(socketId);

Services de publication

En plus d'établir des connexions sortantes avec des appareils, les applications Chrome peuvent publier des services utilisables par tout appareil compatible avec RFCOMM ou L2CAP.

Écouter sur un socket

Deux types de services publiés sont acceptés. RFCOMM est la solution la plus couramment utilisée et couvre la majorité des appareils et des profils:

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

L2CAP est l'autre et couvre d'autres types d'appareils et des utilisations spécifiques au fournisseur, telles que l'importation de micrologiciels.

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

Dans les deux cas, une option bluetoothSocket.ListenOptions peut être transmise pour allouer un canal ou un PSM spécifique. Le rappel indique une erreur via chrome.runtime.lastError, et un succès dans le cas contraire. Conservez un handle vers le socketId afin de pouvoir accepter ultérieurement les connexions (bluetoothSocket.onAccept) à partir de ce socket.

Accepter des connexions client

Les connexions client sont acceptées et transmises à votre application via l'événement 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);
});

Ne plus accepter les connexions client

Pour arrêter d'accepter les connexions client et annuler la publication du service, utilisez bluetoothSocket.disconnect.

chrome.bluetoothSocket.disconnect(serverSocketId);

Interaction avec les appareils à basse consommation

Bluetooth à basse consommation ou (Bluetooth Smart) est une technologie sans fil visant à réduire la consommation d'énergie. L'API Bluetooth Low Energy permet aux applications d'implémenter le rôle central dans une connexion LE à un périphérique. Les sections suivantes décrivent comment détecter des périphériques Bluetooth à basse consommation, s'y connecter et interagir avec ceux-ci.

Découvrir des périphériques et s'y connecter

Comme pour les appareils Bluetooth traditionnels, il est possible de détecter les périphériques LE à l'aide des méthodes décrites dans la section Détecter les appareils à proximité . Un appareil LE se rend visible en envoyant des paquets de données appelés "données publicitaires". Il est dit qu'il est en mode Publicité. Les données publicitaires peuvent contenir des UUID des services disponibles sur l'appareil. S'ils sont présents, ces UUID seront accessibles à l'aide de la propriété uuids de l'objet bluetooth.Device correspondant.

Une fois détecté, un appareil LE peut être connecté en appelant bluetoothLowEnergy.connect afin que l'application puisse interagir avec ses services:

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...
    ...
  });
});

Une fois la connexion établie, la propriété connected de l'objet bluetooth.Device correspondant prend la valeur true. L'appel de bluetoothLowEnergy.connect établit une revendication par l'application sur la connexion physique à l'appareil. Une connexion physique à l'appareil peut exister sans jamais appeler bluetoothLowEnergy.connect (par exemple, à cause d'une autre application). Dans ce cas, même si votre application peut toujours interagir avec les services de l'appareil, elle doit toujours appeler bluetoothLowEnergy.connect pour empêcher une autre application de déconnecter la liaison physique.

Une fois que votre application n'a plus besoin d'être connectée, elle peut supprimer sa revendication de connexion en appelant bluetoothLowEnergy.disconnect:

chrome.bluetoothLowEnergy.disconnect(deviceAddress);

Notez que cette opération ne détruira pas nécessairement le lien physique vers l'appareil, car d'autres applications peuvent avoir des connexions actives à l'appareil. Parfois, l'appareil peut être déconnecté pour des raisons qui échappent au contrôle de l'application (par exemple, s'il disparaît ou est explicitement déconnecté par l'utilisateur via les utilitaires du système d'exploitation). Votre application doit observer l'événement bluetooth.onDeviceChanged pour être averti des changements de connexion et se reconnecter si nécessaire.

Une fois connecté, l'appareil qui exécute Chrome est doté du rôle central, tandis que l'appareil distant est considéré comme ayant le rôle périphérique. À ce stade, votre application peut interagir avec les services de l'appareil à l'aide des méthodes décrites dans la section suivante. Remarque:Actuellement, les API ne sont pas compatibles avec le rôle de périphérique LE. Les applications ne peuvent implémenter que le rôle central.

Services, caractéristiques et descripteurs

La technologie Bluetooth à basse consommation est basée sur un simple protocole requête/réponse appelé Attribute Protocol (ATT, protocole d'attribut). À l'aide de la fonctionnalité ATT, un appareil central interagit avec les attributs d'un périphérique périphérique en se conformant à un profil Bluetooth spécial appelé Generic Attribute Profile (GATT). GATT définit les concepts généraux suivants:

  • Service: un service GATT représente un ensemble de données et de comportements associés pour accomplir une fonction particulière d'un appareil. Par exemple, un moniteur de fréquence cardiaque dispose généralement d'au moins un "service de suivi de la fréquence cardiaque". Les informations sur un service GATT sont contenues dans un objet bluetoothLowEnergy.Service.
  • Caractéristique: une caractéristique GATT est un élément de données de base utilisé pour construire un service GATT. Elle contient une valeur et des propriétés qui définissent comment cette valeur est accessible. Par exemple, le "Service de la fréquence cardiaque" possède la caractéristique "Mesure de la fréquence cardiaque", qui permet d'obtenir la valeur de la fréquence cardiaque de l'utilisateur. Les informations sur une caractéristique GATT sont contenues dans un objet bluetoothLowEnergy.Characteristic.
  • Descripteur: le descripteur d'une caractéristique GATT contient des informations supplémentaires sur une caractéristique. Les informations sur un descripteur de caractéristique GATT sont contenues dans un objet bluetoothLowEnergy.Descriptor.

L'API Bluetooth Low Energy permet aux applications de rechercher des informations sur les services, les caractéristiques et les descripteurs d'un appareil en appelant bluetoothLowEnergy.getServices, bluetoothLowEnergy.getCharacteristics et bluetoothLowEnergy.getDescriptors. Les applications peuvent filtrer les services, les caractéristiques et les descripteurs en comparant leur champ uuid à l'UUID GATT souhaité:

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;
    }
  }
  ...
});

Chaque service, caractéristique et descripteur accessible via l'API se voit attribuer un identifiant d'instance unique, qui peut être obtenu à l'aide du champ instanceId. Cet ID d'instance peut servir à identifier un objet GATT et à effectuer des opérations spécifiques sur celui-ci:

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) {
    ...
  });
});

Événements de service

Une fois qu'un appareil est connecté, Chrome détecte ses services. Lorsque chaque service est découvert et supprimé, l'application reçoit les événements bluetoothLowEnergy.onServiceAdded et 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 découvre toutes les caractéristiques et les descripteurs d'un service de manière asynchrone, et envoie l'événement bluetoothLowEnergy.onServiceAdded une fois la découverte terminée. Si la connexion à un périphérique prend fin, Chrome supprime tous les services associés et envoie l'événement bluetoothLowEnergy.onServiceRemoved.

Certains périphériques peuvent modifier leurs services. Par exemple, les caractéristiques d'un service peuvent changer ou des services peuvent être ajoutés et supprimés complètement. Chrome informe les applications de ces modifications à l'aide des événements bluetoothLowEnergy.onServiceChanged, bluetoothLowEnergy.onServiceAdded et bluetoothLowEnergy.onServiceRemoved.

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

    updateMyService(service);
  });

Lire et écrire la valeur d'une caractéristique

Une caractéristique GATT encode un aspect de son service. Une application centrale lit, agit et modifie l'état du service d'un périphérique en opérant sur la valeur d'une caractéristique. La valeur caractéristique est une séquence d'octets et sa signification est définie par la spécification de haut niveau qui définit une certaine caractéristique. Par exemple, la valeur de la caractéristique Mesure de la fréquence cardiaque encode la fréquence cardiaque de l'utilisateur et la quantité totale de calories brûlées, tandis que la caractéristique Body Sensor Location encode l'endroit où le capteur de fréquence cardiaque doit être porté dans le corps.

Chrome fournit la méthode bluetoothLowEnergy.readCharacteristicValue pour lire la valeur d'une caractéristique:

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.
  ...
});

Certaines caractéristiques sont accessibles en écriture, en particulier celles qui se comportent comme des "points de contrôle", où l'écriture de la valeur a des effets secondaires. Par exemple, la caractéristique Point de contrôle de la fréquence cardiaque permet d'indiquer à un capteur de fréquence cardiaque de réinitialiser le nombre total de calories brûlées. Elle n'accepte que les écritures. Pour ce faire, Chrome propose la méthode 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.
});

Les descripteurs caractéristiques se comportent de la même manière et peuvent être lus et/ou en écriture. Chrome fournit les méthodes bluetoothLowEnergy.readDescriptorValue et bluetoothLowEnergy.writeDescriptorValue pour lire et écrire la valeur d'un descripteur.

Pour vérifier si une caractéristique prend en charge les lectures ou les écritures, une application peut vérifier le champ properties d'un objet bluetoothLowEnergy.Characteristic. Bien que ce champ ne contienne pas d'informations sur les exigences de sécurité permettant d'accéder à une valeur, il décrit l'opération de valeur prise en charge par la caractéristique en général.

Gérer les notifications de valeur

Certaines caractéristiques permettent de connaître leur valeur à l'aide de notifications ou d'indications. Par exemple, la caractéristique de mesure de la fréquence cardiaque n'est ni lisible ni accessible en écriture, mais envoie des mises à jour sur sa valeur actuelle à intervalles réguliers. Les applications peuvent écouter ces notifications à l'aide de l'événement bluetoothLowEnergy.onCharacteristicValueChanged.

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

    var bytes = new Uint8Array(chrc.value);

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

Même si une caractéristique est compatible avec les notifications/indications, elles ne sont pas activées par défaut. Une application doit appeler les méthodes bluetoothLowEnergy.startCharacteristicNotifications et bluetoothLowEnergy.stopCharacteristicNotifications pour démarrer ou arrêter la réception de l'événement 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);
  }

Une fois les notifications démarrées, l'application reçoit bluetoothLowEnergy.onCharacteristicValueChanged chaque fois qu'une notification ou une indication est reçue de la caractéristique. Si la caractéristique accepte les lectures, cet événement est également envoyé après un appel réussi à bluetoothLowEnergy.readCharacteristicValue. Cela permet aux applications d'unifier le flux de contrôle d'une mise à jour de valeur déclenchée par une requête de lecture et des notifications:

  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.
    });
  });

Si une caractéristique prend en charge les notifications, son champ properties contient la propriété "notify" ou "indicate".

REMARQUE: Si une caractéristique prend en charge les notifications/indications, elle utilisera le descripteur "Configuration des caractéristiques du client" pour activer/désactiver les notifications. Chrome n'autorise pas les applications à écrire dans ce descripteur. À la place, les applications doivent utiliser les méthodes bluetoothLowEnergy.startCharacteristicNotifications et bluetoothLowEnergy.stopCharacteristicNotifications pour contrôler le comportement des notifications.