Bluetooth

Este documento descreve como usar o Bluetooth, o soquete Bluetooth e o Bluetooth Low Energy para comunicação com dispositivos Bluetooth e Bluetooth de baixa energia.

Para ver informações contextuais sobre o Bluetooth, consulte as especificações oficiais do Bluetooth.

Requisitos do manifesto

Para apps do Chrome que usam Bluetooth, adicione a entrada Bluetooth ao manifesto e especifique: apropriados, os UUIDs de perfis, protocolos ou serviços que você quer implementar você quer implementá-los com APIs de soquete e/ou de baixa energia.

Por exemplo, para uma implementação de soquete:

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

E para uma implementação de baixa energia:

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

Para acessar apenas o estado do adaptador, descobrir dispositivos próximos e acessar informações básicas sobre eles, somente a entrada em si é obrigatória:

"bluetooth": {}

Informações do adaptador

Como receber o estado do adaptador

Para saber o estado do adaptador Bluetooth, use o método bluetooth.getAdapterState:

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

Notificações do adaptador

O evento bluetooth.onAdapterStateChanged é enviado sempre que o estado do adaptador muda. Isso pode ser usado, por exemplo, para determinar quando o rádio do adaptador está ligado ou desligado.

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

Informações do dispositivo

Listando os dispositivos conhecidos

Para ver uma lista dos dispositivos conhecidos pelo adaptador Bluetooth, use bluetooth.getDevices. :

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

Todos os dispositivos são devolvidos, incluindo os dispositivos pareados e os descobertos recentemente. Ele não vai começar a descobrir novos dispositivos (consulte Como descobrir dispositivos por perto).

Recebimento de notificações do dispositivo

Em vez de chamar bluetooth.getDevices repetidamente, você pode usar o bluetooth.onDeviceAdded, bluetooth.onDeviceChanged e bluetooth.onDeviceRemoved. para receber notificações.

O evento bluetooth.onDeviceAdded é enviado sempre que um dispositivo é descoberto pelo adaptador ou estabelece uma conexão com o adaptador:

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

Adicionar um listener a este evento não inicia a descoberta de dispositivos. Consulte Descobrir por perto dispositivos).

As alterações nos dispositivos, incluindo aqueles descobertos anteriormente que estão sendo pareados, são notificadas pelo evento bluetooth.onDeviceChanged:

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

Por fim, o evento bluetooth.onDeviceRemoved é enviado sempre que um dispositivo pareado é removido da o sistema ou um dispositivo descoberto não foi visto recentemente:

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

Descobrindo dispositivos por perto

Para iniciar a descoberta de dispositivos por perto, use o método bluetooth.startDiscovery. A descoberta pode consumir muitos recursos, então chame bluetooth.stopDiscovery quando terminar.

Chame bluetooth.startDiscovery sempre que o app precisar descobrir dispositivos por perto. Não torne a chamada condicional na propriedade discovering de bluetooth.AdapterState. A dará certo mesmo se outro aplicativo estiver descobrindo dispositivos próximos, e garantirá que o adaptador continua fazendo descobertas depois que o outro app é interrompido.

Informações sobre cada dispositivo recém-descoberto são recebidas usando o bluetooth.onDeviceAdded. evento. Para dispositivos que já foram descobertos recentemente ou que já foram pareados com ou estiver conectado, o evento não será enviado. Em vez disso, você deve chamar bluetooth.getDevices para obter as informações atuais e usar o evento bluetooth.onDeviceChanged para receber notificações sobre ou mudanças dessas informações como resultado da descoberta.

Exemplo:

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 o usuário desativar o rádio Bluetooth, todas as sessões de descoberta serão encerradas e não retomadas automaticamente quando o rádio é ligado. Se isso é importante para o seu aplicativo, você deve assistir evento bluetooth.onAdapterStateChanged. Se a propriedade discovering mudar para false, o app precisará chamar bluetooth.startDiscovery novamente para retomar. Tenha cuidado com as que consome muitos recursos da descoberta.

Como identificar dispositivos

Várias opções diferentes são fornecidas para identificar os dispositivos retornados por bluetooth.getDevices e os eventos relacionados.

Se o dispositivo for compatível com a especificação do ID do dispositivo Bluetooth, várias propriedades serão adicionadas à o objeto Device que contém os campos definidos por essa especificação. Exemplo:

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

A especificação do ID do dispositivo geralmente é suficiente para identificar um modelo e até mesmo revisão de um dispositivo de um fornecedor. Quando não estiver presente, você deve confiar nas informações sobre os classe ou tipo do dispositivo, opcionalmente combinado com o prefixo do fabricante no address.

A maioria dos dispositivos Bluetooth fornece informações de classe de dispositivo como um campo de bits interpretado de acordo com documento Números atribuídos da banda de base. Esse bit-field está disponível nos 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));
    }
  }
});

A análise do campo pode ser complexa. Portanto, para os tipos de dispositivos mais comuns, o Chrome faz isso por você e define o campo type. Quando isso não estiver disponível ou for insuficiente para suas necessidades, você precisará analise o 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].type);
    }
  }
});

Como usar RFCOMM e L2CAP

Os Aplicativos do Google Chrome podem fazer conexões com qualquer dispositivo compatível com serviços RFCOMM ou L2CAP. Isso inclui com a maioria dos dispositivos Bluetooth clássicos do mercado.

Como se conectar a um soquete

Para se conectar a um dispositivo, são necessários três itens. Um soquete para fazer a conexão criada usando bluetoothSocket.create; o endereço do dispositivo ao qual você quer se conectar; e o UUID do próprio serviço.

Antes de fazer a conexão, verifique se o adaptador reconhece o dispositivo usando bluetooth.getDevice ou às APIs de descoberta de dispositivos.

As informações necessárias para estabelecer a conexão subjacente, incluindo se RFCOMM ou O protocolo L2CAP deve ser usado e qual canal ou PSM é obtido usando a descoberta SDP no dispositivo.

Exemplo:

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

Mantenha um identificador para socketId para poder enviar dados (bluetoothSocket.send) para ele posteriormente soquete.

Como receber e enviar para um soquete

Receber dados e enviar para um soquete usa objetos ArrayBuffer. Para saber mais sobre ArrayBuffers, confira a visão geral, Matrizes tipadas em JavaScript e o tutorial Como converter o ArrayBuffer de e para String.

Para enviar dados que você tem no app arrayBuffer, use 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")
  }
})

Diferentemente do método de envio, os dados são recebidos em um evento (bluetoothSocket.onReceive. Os soquetes são criados novamente. Consulte bluetoothSocket.setPaused. portanto, o listener desse evento normalmente é adicionado entre bluetoothSocket.create e bluetoothSocket.connect.

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

Recebimento de erros e desconexão de soquetes

Para ser notificado sobre erros de soquete, incluindo desconexão, adicione um listener ao evento bluetoothSocket.onReceiveError.

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

Desconectar-se de um soquete

Para desligar a conexão e desconectar o soquete, use bluetoothSocket.disconnect.

chrome.bluetoothSocket.disconnect(socketId);

Serviços de publicação

Além de fazer conexões de saída a dispositivos, os Aplicativos do Google Chrome podem publicar serviços que podem ser usado por qualquer dispositivo que suporte RFCOMM ou L2CAP.

Ouvir em uma tomada

Há suporte para dois tipos de serviço publicado. RFCOMM é o mais comumente usado e abrange os para a maioria dos dispositivos e perfis:

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

L2CAP é o outro e abrange outros tipos de dispositivos e usos específicos do fornecedor, como firmware fazendo upload.

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

Em ambos os casos, um bluetoothSocket.ListenOptions opcional pode ser passado para alocar um determinado ou PSM. O callback indica um erro por chrome.runtime.lastError e foi bem-sucedido. caso contrário. Mantenha um identificador no socketId para poder aceitar conexões mais tarde. (bluetoothSocket.onAccept) por esse soquete.

Como aceitar conexões de clientes

As conexões do cliente são aceitas e transmitidas para seu aplicativo por meio do 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);
});

Parar de aceitar conexões de clientes

Para deixar de aceitar conexões de clientes e cancelar a publicação do serviço, use bluetoothSocket.disconnect.

chrome.bluetoothSocket.disconnect(serverSocketId);

Interagir com dispositivos de baixa energia

Bluetooth de baixa energia (Bluetooth Smart) é uma tecnologia sem fio voltada para redução de energia e consumo. A API Bluetooth Low Energy permite que os aplicativos implementem a função central na uma conexão LE a um periférico. As seções a seguir descrevem como descobrir, se conectar e interagem com periféricos de Bluetooth de baixa energia.

Como descobrir e se conectar a periféricos

Assim como nos dispositivos Bluetooth tradicionais, os periféricos de LE podem ser descobertos usando os métodos descritos em Como descobrir dispositivos por perto . Um dispositivo LE se torna detectável enviando pacotes de dados chamado "Dados de publicidade" e diz-se que o dispositivo está no modo de publicidade. Dados de publicidade pode conter UUIDs de serviços disponíveis no dispositivo. Se estiverem presentes, esses UUIDs serão acessíveis usando a propriedade uuids do objeto bluetooth.Device correspondente.

Depois de descoberto, é possível conectar um dispositivo de LE chamando bluetoothLowEnergy.connect. que o aplicativo possa interagir com os serviços:

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

Após a conexão, a propriedade connected do objeto bluetooth.Device correspondente será têm o valor true. Chamar bluetoothLowEnergy.connect estabelece uma reivindicação pelo aplicativo na conexão física com o dispositivo. Pode existir uma conexão física com o dispositivo sem nunca chamar bluetoothLowEnergy.connect (por exemplo, devido a outro aplicativo). Em nesse caso, embora seu aplicativo ainda possa interagir com os serviços do dispositivo, ele deve sempre chame bluetoothLowEnergy.connect para evitar que outro aplicativo desconecte o um link físico.

Quando seu aplicativo não precisar mais estar conectado, ele poderá remover a reivindicação da conexão Fazendo uma chamada para bluetoothLowEnergy.disconnect:

chrome.bluetoothLowEnergy.disconnect(deviceAddress);

Isso não destruirá necessariamente o vínculo físico com o dispositivo, pois pode haver outras aplicativos que têm conexões ativas com o dispositivo. Às vezes, o dispositivo pode ficar desconectados por motivos que estão além do controle do aplicativo (por exemplo, se o dispositivo desaparece ou é explicitamente desconectado pelo usuário por meio de utilitários do sistema operacional). Seu aplicativo deve observar o evento bluetooth.onDeviceChanged para ser notificado sobre as alterações. à conexão e reconecte, se necessário.

Depois de conectado, o dispositivo que executa o Chrome terá o chamado papel central, enquanto o o dispositivo remoto tem a função periférico. Neste ponto, o aplicativo pode interagir com os serviços no dispositivo usando os métodos descritos na próxima seção. Observação: o No momento, as APIs não oferecem suporte a atuar como periférico de LE. só podem implementar a função central.

Serviços, características e descritores

O Bluetooth Low Energy é baseado em um protocolo de solicitação-resposta simples chamado Attribute Protocol (ATT). Usando o ATT, um dispositivo central interage com os chamados atributos em um dispositivo periférico. usando um perfil Bluetooth especial chamado Generic Attribute Profile (GATT). GATT define os seguintes conceitos de alto nível:

  • Serviço: um serviço GATT representa uma coleção de dados e comportamentos associados para realizar uma específica de um dispositivo. Por exemplo, um monitor de frequência cardíaca normalmente tem pelo menos um "Serviço de frequência cardíaca". As informações sobre um serviço GATT estão contidas em um objeto bluetoothLowEnergy.Service.
  • Característica: uma característica GATT é um elemento de dados básico usado para construir um serviço GATT, que contêm um valor e propriedades que definem como esse valor pode ser acessado. Por exemplo: o "Serviço de frequência cardíaca" tem a "Medição de frequência cardíaca" característica, que é usada para conseguir o valor da frequência cardíaca do usuário. As informações sobre uma característica GATT estão contidas em um objeto bluetoothLowEnergy.Characteristic.
  • Descritor: um descritor de característica GATT contém mais informações sobre uma característica. As informações sobre um descritor de característica GATT estão contidas em um bluetoothLowEnergy.Descriptor.

A API do Bluetooth Low Energy permite que os aplicativos encontrem informações sobre a serviços, características e descritores chamando bluetoothLowEnergy.getServices, bluetoothLowEnergy.getCharacteristics e bluetoothLowEnergy.getDescriptors. Os apps podem filtrar por serviços, características e descritores comparando o campo uuid ao UUID do GATT desejado:

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

Cada serviço, característica e descritor acessível pela API recebe um identificador de instância, que pode ser obtido usando o campo instanceId. Esse ID de instância pode ser usada para identificar um objeto GATT e executar operações específicas nele:

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 serviço

Quando um dispositivo está conectado, o Chrome descobre os serviços dele. À medida que cada serviço é descoberto removido, o aplicativo receberá os eventos bluetoothLowEnergy.onServiceAdded e Eventos 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);
  });

O Chrome descobre todas as características e descritores de um serviço de forma assíncrona e envia o evento bluetoothLowEnergy.onServiceAdded após a conclusão da descoberta. Se a conexão com um periférico é encerrado, o Chrome remove todos os serviços relacionados e envia os evento bluetoothLowEnergy.onServiceRemoved.

Alguns periféricos podem modificar seus serviços, por exemplo, as características de um serviço podem mudar ou serviços podem ser adicionados e removidos por completo. O Chrome notifica os apps sobre essas mudanças usando o bluetoothLowEnergy.onServiceChanged, bluetoothLowEnergy.onServiceAdded e Eventos bluetoothLowEnergy.onServiceRemoved.

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

    updateMyService(service);
  });

Ler e gravar o valor de uma característica

Uma característica GATT codifica um aspecto do seu serviço. Um app central lê, age e modifica o estado do serviço de um periférico operando no valor de uma característica. A característica "value" é uma sequência de bytes e seu significado é definido pela especificação de alto nível que define de uma determinada característica. Por exemplo, o valor da característica Medição de frequência cardíaca codifica a frequência cardíaca do usuário e a quantidade total de calorias que ele queimou, enquanto o Sensor corporal A característica de localização codifica em que parte do corpo o sensor de frequência cardíaca deve ser usado.

O Chrome fornece o método bluetoothLowEnergy.readCharacteristicValue para ler o valor de uma 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.
  ...
});

Algumas características são graváveis, especialmente aquelas que se comportam como "Pontos de controle", onde escrever o valor tem efeitos colaterais. Por exemplo, a característica Ponto de controle da frequência cardíaca é usada para instrua um sensor de frequência cardíaca a redefinir a contagem do total de calorias queimadas e só aceita gravações. Para fazer isso, o Chrome fornece o 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.
});

Os descritores de características se comportam da mesma maneira e podem ser legíveis e/ou graváveis. O Chrome oferece os valores de bluetoothLowEnergy.readDescriptorValue e bluetoothLowEnergy.writeDescriptorValue para ler e gravar o valor de um descritor.

Para verificar se uma característica oferece suporte a leituras ou gravações, um aplicativo pode verificar o properties campo de um objeto bluetoothLowEnergy.Characteristic. Embora este campo não contenha informações sobre os requisitos de segurança para acessar um valor, ela descreve qual valor que a característica suporta em geral.

Como processar notificações de valor

Algumas características usam notificações ou indicações para reconhecer o valor delas. Por exemplo, o A característica da Medição de frequência cardíaca não é legível nem gravável, mas envia atualizações sobre seu o valor atual em intervalos regulares. Os aplicativos podem ouvir essas notificações usando o 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.
    ...
  });

Mesmo que uma característica seja compatível com notificações/indicações, elas não serão ativadas por padrão. Um aplicativo deve chamar as APIs bluetoothLowEnergy.startCharacteristicNotifications e métodos bluetoothLowEnergy.stopCharacteristicNotifications para iniciar ou parar de receber o 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);
  }

Quando as notificações forem iniciadas, o aplicativo receberá o bluetoothLowEnergy.onCharacteristicValueChanged sempre que uma notificação ou indicação é recebidas da característica. Se a característica oferecer suporte a leituras, esse evento também será enviada após uma chamada para bluetoothLowEnergy.readCharacteristicValue. Isso permite que os apps para unificar o fluxo de controle de uma atualização de valor acionada por uma solicitação de leitura e notificações:

  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 uma característica oferecer suporte a notificações, o campo properties dela conterá o "notify" ou "indicate".

OBSERVAÇÃO: se uma característica oferecer suporte a notificações/indicações, ela terá a propriedade "Cliente configuração da característica" descritor para ativar/desativar notificações. O Chrome não permite para escrever nesse descritor. Em vez disso, os apps devem usar bluetoothLowEnergy.startCharacteristicNotifications e Métodos bluetoothLowEnergy.stopCharacteristicNotifications para controlar o comportamento de notificação.