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ão | WebView | Runtime próprio do host |
|---|---|---|
navigator.bluetooth | undefined (Android WebView); ausente (iOS WKWebView) | BLE nativo via CoreBluetooth / Android Bluetooth |
| Contexto seguro + gesto | Exigido mesmo onde há suporte | Disparado pelo host; sem token frágil |
| Classes de dispositivo | Blocklist do Chrome oculta FIDO/HID | Acesso GATT completo a periféricos emparelhados |
| Carteira / chave de segurança | Não emparelha | Emparelhamento nativo + resposta assinada |
| Impressora / scanner | Não conecta | Conexão nativa, confiável |
| Consistência | Por motor, maiormente ausente | Uniforme |
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
- openpwa — Web Bluetooth API — Android WebView não expõe
navigator.bluetooth; WebKit registra posição "oposta". - MDN Web Docs — Web Bluetooth API — dados de compatibilidade marcam WebView (Android) como não suportado.
- Chrome Developers — Communicating with Bluetooth devices — contexto seguro, ativação transitória e blocklist integrada.
- WebKit Standards Positions — posição oposta do WebKit; sem implementação.
- Median docs — Web Bluetooth in WebView — "não suportado por iOS WebKit nem Android WebView".