En la web abierta, un clic basta para que una página use navigator.bluetooth y solicite un dispositivo BLE cercano, se conecte a su servidor GATT y lea o escriba características. Pero dentro de un WebView ese punto de entrada simplemente no existe. Android WebView no expone navigator.bluetooth —la propiedad es undefined— y los datos de compatibilidad de MDN marcan WebView (Android) como "no soportado". En iOS la situación es más sutil: ni Safari ni WKWebView implementan Web Bluetooth, y como iOS obliga a todos los navegadores a usar el motor WebKit, Chrome y Edge en iOS heredan la misma brecha. WebKit registra una posición "opuesta" sobre la especificación, así que no hay ninguna implementación en camino.
Para una página WebView el resultado es uniforme entre motores: el código que funciona en la web de escritorio lanza error o no hace nada, y la página no tiene ningún respaldo interno.
Incluso donde existe, es frágil
Vale la pena señalar que Web Bluetooth es delicado incluso en los navegadores que lo soportan. Chrome exige un contexto seguro (HTTPS), una activación transitoria del usuario (la llamada debe venir de un clic, no de un temporizador o un fetch) y mantiene una lista negra integrada que oculta algunos IDs de proveedor y producto —incluidas algunas clases FIDO y HID— antes de que se abra el selector. Una página que depende de él ya está a un aviso de permiso y un flag de distancia de romperse. En un WebView no hay navegador al que recurrir, así que la capacidad simplemente desaparece.
Qué se rompe cuando el emparejamiento de hardware muere
- Las llaves de seguridad BLE no se emparejan. Un bróker o exchange que confirma retiros con un autenticador FIDO BLE no puede completar ese flujo desde una página WebView: el autenticador es invisible para la página.
- Los monederos de hardware quedan desconectados. Los mostradores de cripto y OTC que emparejan un monedero de hardware para verificar direcciones o firmar transacciones no tienen ninguna vía desde el contenido web embebido.
- Las terminales periféricas fallan. Las impresoras de recibos BLE, los escáneres y los accesorios POS que usa un mini-programa de comerciante no se pueden alcanzar.
- Silencioso, no ruidoso. Como la API es
undefined(o, en iOS, nunca muestra el aviso), el fallo es un no-op silencioso: sin error que el usuario pueda manejar, solo un botón que no hace nada.
La solución en el runtime
Un runtime propio del host conecta la capa Bluetooth. La página llama a una sola API uniforme —runtime.connectBle({ filters, onData })— y el host la resuelve con la pila Bluetooth nativa de la plataforma: Android BluetoothGatt sobre BluetoothAdapter, o iOS CoreBluetooth (CBCentralManager, CBPeripheral). El emparejamiento, el descubrimiento de servicios y la E/S de características se manejan de forma nativa y coherente. Una integración, todos los motores, hardware real al final.
| Dimensión | WebView | Runtime propio del host |
|---|---|---|
navigator.bluetooth | undefined (Android WebView); ausente (iOS WKWebView) | BLE nativo vía CoreBluetooth / Android Bluetooth |
| Contexto seguro + gesto | Requerido incluso donde hay soporte | Activado por el host; sin token frágil |
| Clases de dispositivo | La lista negra de Chrome oculta FIDO/HID | Acceso GATT completo a periféricos emparejados |
| Monedero / llave de seguridad | No se empareja | Emparejamiento nativo + respuesta firmada |
| Impresora / escáner | No se conecta | Conexión nativa, fiable |
| Consistencia | Por motor, mayormente ausente | Uniforme |
Una app nativa empareja una llave BLE en todos los dispositivos. Un WebView estándar no lo hace en casi ninguno. Un runtime le da a la página una sola llamada connect —y un periférico real al final.
Fuentes
- openpwa — Web Bluetooth API — Android WebView no expone
navigator.bluetooth; WebKit registra posición "opuesta". - MDN Web Docs — Web Bluetooth API — datos de compatibilidad marcan WebView (Android) como no soportado.
- Chrome Developers — Communicating with Bluetooth devices — contexto seguro, activación transitoria y lista negra integrada.
- WebKit Standards Positions — posición opuesta de WebKit; sin implementación.
- Median docs — Web Bluetooth in WebView — "no soportado por iOS WebKit ni Android WebView".