Bluetooth

En este documento, se describe cómo usar las APIs de Bluetooth, Socket Bluetooth y Bluetooth Low Energy para comunicarse con dispositivos Bluetooth y Bluetooth de bajo consumo.

Para obtener información general sobre el uso de Bluetooth, consulta las especificaciones de Bluetooth oficiales.

Requisitos del manifiesto

Para las Apps de Chrome que usan Bluetooth, agrega la entrada Bluetooth al manifiesto y especifica, si corresponde, los UUID de los perfiles, protocolos o servicios que deseas implementar junto con si deseas implementarlos con el socket o las APIs de bajo consumo.

Por ejemplo, para una implementación de socket:

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

Y para una implementación de bajo consumo:

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

Para acceder solo al estado del adaptador, descubrir dispositivos cercanos y obtener información básica sobre ellos, solo se requiere la siguiente entrada:

"bluetooth": {}

Información del adaptador

Obtén el estado del adaptador

Para obtener el estado del adaptador Bluetooth, usa el método bluetooth.getAdapterState:

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

Notificaciones del adaptador

El evento bluetooth.onAdapterStateChanged se envía cada vez que cambia el estado del adaptador. Se puede usar, por ejemplo, para determinar cuándo se enciende o se apaga la radio del adaptador.

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

Información del dispositivo

Cómo mostrar una lista de dispositivos conocidos

Para obtener una lista de los dispositivos que el adaptador Bluetooth conoce, usa el método bluetooth.getDevices:

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

Se muestran todos los dispositivos, incluidos los dispositivos vinculados y los descubiertos recientemente. No comenzará a descubrir dispositivos nuevos (consulta Cómo descubrir dispositivos cercanos).

Recibir notificaciones del dispositivo

En lugar de llamar repetidamente a bluetooth.getDevices, puedes usar los eventos bluetooth.onDeviceAdded, bluetooth.onDeviceChanged y bluetooth.onDeviceRemoved para recibir notificaciones.

El evento bluetooth.onDeviceAdded se envía cada vez que el adaptador detecta un dispositivo o se conecta a él:

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

Agregar un objeto de escucha para este evento no comienza a detectar dispositivos (consulta Cómo descubrir dispositivos cercanos).

Los cambios en los dispositivos, incluidos los dispositivos previamente descubiertos que se vinculan, reciben una notificación a través del evento bluetooth.onDeviceChanged:

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

Por último, el evento bluetooth.onDeviceRemoved se envía cada vez que se quita un dispositivo vinculado del sistema o no se detectó un dispositivo detectado recientemente:

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

Detectando dispositivos cercanos

Para comenzar a descubrir dispositivos cercanos, usa el método bluetooth.startDiscovery. Como la detección puede consumir muchos recursos, deberías llamar a bluetooth.stopDiscovery cuando termines.

Debes llamar a bluetooth.startDiscovery cada vez que la app necesite detectar dispositivos cercanos. No hagas que la llamada sea condicional en la propiedad discovering de bluetooth.AdapterState. La llamada se realizará correctamente incluso si otra app detecta dispositivos cercanos y se asegurará de que el adaptador continúe realizando la detección después de que se detenga la otra app.

La información sobre cada dispositivo descubierto recientemente se recibe a través del evento bluetooth.onDeviceAdded. En el caso de los dispositivos que ya se detectaron recientemente o que se vincularon o se conectaron con anterioridad, no se enviará el evento. En su lugar, debes llamar a bluetooth.getDevices para obtener la información actual y usar el evento bluetooth.onDeviceChanged para recibir notificaciones sobre los cambios en esa información como resultado del descubrimiento.

Ejemplo:

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 el usuario desactiva la radio Bluetooth, todas las sesiones de detección finalizarán y no se reanudarán automáticamente cuando se encienda la radio. Si esto es importante para tu app, debes mirar el evento bluetooth.onAdapterStateChanged. Si la propiedad discovering cambia a false, tu app deberá volver a llamar a bluetooth.startDiscovery para reanudarse. Ten cuidado con la naturaleza del descubrimiento, que requiere muchos recursos.

Cómo identificar dispositivos

Se proporcionan varias opciones para identificar los dispositivos que muestra bluetooth.getDevices y los eventos relacionados.

Si el dispositivo admite la especificación de ID de dispositivo de Bluetooth, se agregan varias propiedades al objeto Device que contiene los campos definidos por esa especificación. Ejemplo:

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

Por lo general, la especificación de ID de dispositivo es suficiente para identificar un modelo en particular (o incluso la revisión) de un dispositivo de un proveedor. Cuando no esté presente, en su lugar, debes basarte en la información sobre la clase o el tipo de dispositivo (opcionalmente combinado con el prefijo del fabricante en address).

La mayoría de los dispositivos Bluetooth proporcionan información sobre la clase de dispositivo como un campo de bits interpretado de acuerdo con el documento Números asignados de banda base. Este campo de bits está disponible en la propiedad 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));
    }
  }
});

El análisis del campo puede ser complejo, por lo que, para los tipos de dispositivos más comunes, Chrome lo maneja por ti y establece el campo type. Cuando esta opción no esté disponible o no sea suficiente para tus necesidades, deberás analizar deviceClass por tu cuenta.

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

Usa RFCOMM y L2CAP

Las Apps de Chrome pueden establecer conexiones con cualquier dispositivo que admita servicios RFCOMM o L2CAP. Esto incluye la mayoría de los dispositivos Bluetooth clásicos que se encuentran en el mercado.

Conéctate a un socket

Para establecer una conexión a un dispositivo, necesitas tres elementos. Un socket para establecer la conexión, creado con bluetoothSocket.create, la dirección del dispositivo al que deseas conectarte y el UUID del servicio en sí

Antes de establecer la conexión, debes verificar que el adaptador reconozca el dispositivo mediante bluetooth.getDevice o las API de detección de dispositivos.

La información necesaria para establecer la conexión subyacente, que incluye si se debe usar el protocolo RFCOMM o L2CAP y qué canal o PSM, se obtiene a través del descubrimiento del SDP en el dispositivo.

Ejemplo:

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

Mantén un controlador para el socketId para que más tarde puedas enviar datos (bluetoothSocket.send) a este socket.

Cómo recibir mensajes desde un socket y enviarlo a él

La recepción de datos de un socket y el envío a este usan objetos ArrayBuffer. Para obtener más información sobre ArrayBuffers, consulta la descripción general, los arrays escritos en JavaScript y el instructivo Cómo convertir ArrayBuffer a una string y viceversa.

Para enviar datos que tienes en arrayBuffer, usa 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 diferencia del método para enviar datos, los datos se reciben en un evento (bluetoothSocket.onReceive. Los sockets se crean de forma reanudada (consulta bluetoothSocket.setPaused), por lo que el objeto de escucha de este evento suele agregarse entre bluetoothSocket.create y bluetoothSocket.connect.

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

Recibir errores y desconexión de socket

Para recibir notificaciones sobre errores del socket, incluida la desconexión, agrega un objeto de escucha al evento bluetoothSocket.onReceiveError.

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

Desconéctate de un socket

Para finalizar la conexión y desconectar el socket, usa bluetoothSocket.disconnect.

chrome.bluetoothSocket.disconnect(socketId);

Servicios de publicación

Además de realizar conexiones salientes a los dispositivos, las Apps de Chrome pueden publicar servicios que cualquier dispositivo compatible con RFCOMM o L2CAP puede usar.

Escuchando en un tomacorriente

Se admiten dos tipos de servicios publicados. RFCOMM es el más utilizado y abarca la mayoría de los dispositivos y perfiles:

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

L2CAP es la otra opción y abarca otros tipos de dispositivos y usos específicos de los proveedores, como la carga de firmware.

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

En ambos casos, se puede pasar un bluetoothSocket.ListenOptions opcional para asignar un canal o PSM específicos. La devolución de llamada indica un error en chrome.runtime.lastError y, de lo contrario, se realizó correctamente. Mantén un controlador para el socketId para que más tarde puedas aceptar conexiones (bluetoothSocket.onAccept) desde este socket.

Acepta conexiones de clientes

Las conexiones de cliente se aceptan y se pasan a tu aplicación a través del 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);
});

Dejar de aceptar conexiones de clientes

Para dejar de aceptar conexiones de cliente y anular la publicación del servicio, usa bluetoothSocket.disconnect.

chrome.bluetoothSocket.disconnect(serverSocketId);

Cómo interactuar con dispositivos de bajo consumo

Bluetooth de bajo consumo (Bluetooth Smart) es una tecnología inalámbrica diseñada para reducir el consumo de energía. La API de Bluetooth de bajo consumo permite que las aplicaciones implementen la función central en una conexión de LE en un periférico. En las siguientes secciones, se describe cómo descubrir periféricos Bluetooth de bajo consumo, cómo conectarse a ellos e interactuar con ellos.

Cómo descubrir periféricos y conectarse a ellos

Al igual que con los dispositivos Bluetooth tradicionales, los periféricos LE se pueden descubrir mediante los métodos descritos en Cómo detectar dispositivos cercanos . Un dispositivo de LE se vuelve detectable mediante el envío de paquetes de datos llamados "datos publicitarios", y se dice que el dispositivo está en modo publicitario. Los datos publicitarios pueden contener UUIDs de servicios disponibles en el dispositivo. Si están presentes, se podrá acceder a estos UUID a través de la propiedad uuids del objeto bluetooth.Device correspondiente.

Una vez descubierto, se puede conectar un dispositivo de bajo consumo mediante una llamada a bluetoothLowEnergy.connect para que la aplicación pueda interactuar con sus servicios:

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

Una vez conectado, la propiedad connected del objeto bluetooth.Device correspondiente tendrá el valor true. Una llamada a bluetoothLowEnergy.connect establece una reclamación por parte de la aplicación en la conexión física al dispositivo. Puede existir una conexión física con el dispositivo sin llamar a bluetoothLowEnergy.connect (por ejemplo, debido a otra aplicación). En este caso, mientras tu aplicación aún puede interactuar con los servicios del dispositivo, siempre debe llamar a bluetoothLowEnergy.connect para evitar que otra aplicación desconecte el vínculo físico.

Una vez que tu aplicación ya no necesita estar conectada, puedes quitar su reclamación sobre la conexión llamando a bluetoothLowEnergy.disconnect:

chrome.bluetoothLowEnergy.disconnect(deviceAddress);

Ten en cuenta que esto no destruirá necesariamente el vínculo físico con el dispositivo, ya que pueden existir otras aplicaciones que tengan conexiones activas con el dispositivo. A veces, el dispositivo se puede desconectar por razones que están fuera del control de la aplicación (p.ej., si el dispositivo desaparece o el usuario lo desconecta explícitamente a través de las utilidades del sistema operativo). La aplicación debe observar el evento bluetooth.onDeviceChanged para recibir notificaciones sobre los cambios en la conexión y volver a conectarse si es necesario.

Una vez conectado, el dispositivo que ejecuta Chrome estará en la denominada función central, mientras que el dispositivo remoto se encontrará en la función periférico. En este punto, tu aplicación puede interactuar con los servicios en el dispositivo usando los métodos que se describen en la siguiente sección. Nota: Por el momento, las APIs no admiten actuar como un periférico LE. Las apps solo pueden implementar la función central.

Servicios, características y descriptores

Bluetooth de bajo consumo se basa en un protocolo simple de solicitud y respuesta denominado protocolo de atributos (ATT). Mediante ATT, un dispositivo central interactúa con los llamados atributos en un dispositivo periférico de acuerdo con un perfil especial de Bluetooth llamado perfil genérico de atributos (GATT). GATT define los siguientes conceptos de alto nivel:

  • Servicio: Un servicio GATT representa una colección de datos y comportamientos asociados para cumplir una función particular de un dispositivo. Por ejemplo, un monitor de frecuencia cardíaca tendrá al menos un "servicio de frecuencia cardíaca". La información sobre el servicio GATT se encuentra en el objeto bluetoothLowEnergy.Service.
  • Característica: Una característica GATT es un elemento de datos básico utilizado para construir un servicio GATT, que contiene un valor junto con propiedades que definen cómo se puede acceder a ese valor. Por ejemplo, el "Servicio de frecuencia cardíaca" tiene la característica "Medición de frecuencia cardíaca", que se usa para obtener el valor de la frecuencia cardíaca del usuario. La información sobre una característica GATT está incluida en un objeto bluetoothLowEnergy.Characteristic.
  • Descriptor: un descriptor de característica GATT contiene más información sobre una característica. La información sobre un descriptor de característica GATT se encuentra en un objeto bluetoothLowEnergy.Descriptor.

La API de Bluetooth Low Energy permite que las aplicaciones encuentren información sobre los servicios, las características y los descriptores de un dispositivo llamando a bluetoothLowEnergy.getServices, bluetoothLowEnergy.getCharacteristics y bluetoothLowEnergy.getDescriptors. Las apps pueden filtrar servicios, características y descriptores si comparan su campo uuid con el UUID de GATT deseado:

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 cada servicio, característica y descriptor accesible a través de la API se le asigna un identificador de instancia único, que se puede obtener mediante el campo instanceId. Este ID de instancia se puede usar para identificar un objeto GATT y realizar operaciones específicas en él:

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

Eventos de servicio

Una vez que se conecte un dispositivo, Chrome descubrirá sus servicios. A medida que se descubra y quite cada servicio, la aplicación recibirá los eventos bluetoothLowEnergy.onServiceAdded y 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 descubre todas las características y los descriptores de un servicio de forma asíncrona y envía el evento bluetoothLowEnergy.onServiceAdded una vez que se complete el descubrimiento. Si finaliza la conexión a un periférico, Chrome quita todos los servicios relacionados y envía el evento bluetoothLowEnergy.onServiceRemoved.

Algunos periféricos pueden modificar sus servicios, p.ej., las características de un servicio pueden cambiar o pueden agregarse y quitarse servicios por completo. Chrome notifica a las apps sobre estos cambios mediante los eventos bluetoothLowEnergy.onServiceChanged, bluetoothLowEnergy.onServiceAdded y bluetoothLowEnergy.onServiceRemoved.

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

    updateMyService(service);
  });

Leer y escribir el valor de una característica

Una característica GATT codifica un aspecto de su servicio. Una app central lee, actúa y modifica el estado del servicio de un periférico mediante la operación del valor de una característica. El valor de característica es una secuencia de bytes y su significado se define mediante la especificación de alto nivel que define una característica en particular. Por ejemplo, el valor de la característica de medición del ritmo cardíaco codifica la frecuencia cardíaca del usuario y la cantidad total de calorías que quemó, mientras que la característica de ubicación del sensor corporal codifica en qué parte del cuerpo se debe usar el sensor de frecuencia cardíaca.

Chrome proporciona el método bluetoothLowEnergy.readCharacteristicValue para leer el valor de una característica:

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

Algunas características admiten escritura, en especial aquellas que se comportan como "Puntos de control", en los que escribir el valor tiene efectos secundarios. Por ejemplo, la característica Punto de control de frecuencia cardíaca se usa para indicarle a un sensor de frecuencia cardíaca que restablezca su recuento total de calorías quemadas y solo admite escrituras. Para lograrlo, Chrome proporciona el método 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.
});

Los descriptores de características se comportan de la misma manera y pueden leerse o escribirse. Chrome proporciona los métodos bluetoothLowEnergy.readDescriptorValue y bluetoothLowEnergy.writeDescriptorValue para leer y escribir el valor de un descriptor.

Para comprobar si una característica admite lecturas o escrituras, una aplicación puede verificar el campo properties de un objeto bluetoothLowEnergy.Characteristic. Si bien este campo no contiene información sobre los requisitos de seguridad para acceder a un valor, describe qué operación de valor admite en general la característica.

Administra las notificaciones de valores

Algunas características dan a conocer su valor a través de notificaciones o indicaciones. Por ejemplo, la característica de medición de la frecuencia cardíaca no se puede leer ni escribir, pero envía actualizaciones sobre su valor actual a intervalos regulares. Las aplicaciones pueden escuchar estas notificaciones con el 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.
    ...
  });

Incluso si una característica admite notificaciones/indicaciones, estas no están habilitadas de forma predeterminada. Una aplicación debe llamar a los métodos bluetoothLowEnergy.startCharacteristicNotifications y bluetoothLowEnergy.stopCharacteristicNotifications para iniciar o dejar de recibir el 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 vez que se inicien las notificaciones, la aplicación recibirá bluetoothLowEnergy.onCharacteristicValueChanged cada vez que se reciba una notificación o indicación desde la característica. Si la característica admite lecturas, este evento también se enviará después de una llamada exitosa a bluetoothLowEnergy.readCharacteristicValue. Esto permite que las apps unifiquen el flujo de control de una actualización de valor activada a través de una solicitud de lectura y notificaciones:

  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 una característica admite notificaciones, su campo properties contendrá la propiedad "notify" o "indicate".

NOTA: Si una característica admite notificaciones o indicaciones, tendrá el descriptor de "Configuración de características del cliente" para habilitar o inhabilitar las notificaciones. Chrome no permite que las apps escriban en este descriptor. En su lugar, las apps deben usar los métodos bluetoothLowEnergy.startCharacteristicNotifications y bluetoothLowEnergy.stopCharacteristicNotifications para controlar el comportamiento de las notificaciones.