Na web aberta, um clique basta para a página usar navigator.bluetooth e solicitar um dispositivo BLE próximo, conectar-se ao seu servidor GATT e ler ou escrever características. Mas dentro de um WebView esse ponto de entrada simplesmente não existe. O Android WebView não expõe navigator.bluetooth —a propriedade é undefined— e os dados de compatibilidade da MDN marcam WebView (Android) como "não suportado". No iOS a situação é mais sutil: nem Safari nem WKWebView implementam Web Bluetooth, e como o iOS obriga todos os navegadores a usar o motor WebKit, Chrome e Edge no iOS herdam a mesma lacuna. O WebKit registrou uma posição "oposta" à especificação, então não há implementação a caminho.

Para uma página WebView o resultado é uniforme entre motores: o código que funciona na web de desktop lança erro ou não faz nada, e a página não tem nenhum recurso interno.

Mesmo onde existe, é frágil

Vale notar que o Web Bluetooth é delicado mesmo nos navegadores que o suportam. O Chrome exige contexto seguro (HTTPS), uma ativação transitória do usuário (a chamada deve vir de um clique, não de um timer ou fetch) e mantém uma blocklist integrada que oculta alguns IDs de fornecedor e produto —incluindo algumas classes FIDO e HID— antes do seletor abrir. Uma página que depende dele já está a um aviso de permissão e uma flag de distância de quebrar. Num WebView não há navegador para recorrer, então a capacidade simplesmente desaparece.

O que quebra quando o emparelhamento de hardware morre

  • Chaves de segurança BLE não emparelham. Uma corretora ou exchange que confirma saques com um autenticador FIDO BLE não consegue concluir esse fluxo a partir de uma página WebView: o autenticador é invisível para a página.
  • Carteiras de hardware ficam desconectadas. Mesas de cripto e OTC que emparelham uma carteira de hardware para verificar endereços ou assinar transações não têm nenhum caminho a partir do conteúdo web embutido.
  • Terminais periféricos falham. Impressoras de recibo BLE, scanners e acessórios POS dos quais um mini-programa de comércio depende não podem ser alcançados.
  • Silencioso, não barulhento. Como a API é undefined (ou, no iOS, nunca abre o aviso), a falha é um no-op silencioso: sem erro que o usuário possa tratar, só um botão que não faz nada.

A correção no runtime

Um runtime próprio do host faz a ponte com a camada Bluetooth. A página chama uma única API uniforme —runtime.connectBle({ filters, onData })— e o host a resolve com a pilha Bluetooth nativa da plataforma: Android BluetoothGatt sobre BluetoothAdapter, ou iOS CoreBluetooth (CBCentralManager, CBPeripheral). Emparelhamento, descoberta de serviços e E/S de características são tratados nativa e consistentemente. Uma integração, todos os motores, hardware real no fim.

DimensãoWebViewRuntime próprio do host
navigator.bluetoothundefined (Android WebView); ausente (iOS WKWebView)BLE nativo via CoreBluetooth / Android Bluetooth
Contexto seguro + gestoExigido mesmo onde há suporteDisparado pelo host; sem token frágil
Classes de dispositivoBlocklist do Chrome oculta FIDO/HIDAcesso GATT completo a periféricos emparelhados
Carteira / chave de segurançaNão emparelhaEmparelhamento nativo + resposta assinada
Impressora / scannerNão conectaConexão nativa, confiável
ConsistênciaPor motor, maiormente ausenteUniforme

Um app nativo emparelha uma chave BLE em todos os dispositivos. Um WebView padrão não o faz em quase nenhum. Um runtime dá à página uma única chamada connect —e um periférico real no fim.

Fontes