DeviceMotion、DeviceOrientation 和 Vibration 在移动 Web 上本是一等公民——直到它们跑进 WebView。Android System WebView 在 v55 之前一直禁用方向传感器 API,并且在许多构建里即便「已启用」也返回全零加速度,除非设置正确的标志位与权限;Vibration 还需要显式的 VIBRATE 权限。在 iOS 上,WKWebView 根本不暴露 requestPermission(),于是 iOS 13+ 那套靠手势触发的流程永远无法启动。宿主自有 runtime 桥接传感器层——一套 API,读取每台引擎上的真实硬件。
Android:默认禁用,开了也是静默
Chromium 文档写得很直白:在硬件传感器 API 中,方向传感器 API 在 WebView v33 里被禁用,到 v55 才启用。定位、媒体采集、振动也部分受限。而「已启用」不等于「能用」——许多 WebView 构建在页面没有通过 https 提供、或 App 未授予运行时权限时,返回的 acceleration 是全零,或根本不触发事件。一个典型故障是「摇一摇」功能永远不触发,因为容器没有透传传感器。振动(navigator.vibrate)需要 android.permission.VIBRATE 权限;缺了它调用就是个静默空操作。
iOS:权限 API 干脆不存在
从 iOS 13 起,Safari 要求在触发任何运动或方向事件前,由用户手势调用 DeviceMotionEvent.requestPermission() / DeviceOrientationEvent.requestPermission() 弹出授权框。但这个 API 在 WKWebView 上不暴露。WebKit 自己的缺陷追踪(bug 203287)记录着:「requestPermission() 只在 MobileSafari 暴露,不在 WKWebView」。所以在 App 内的 WebView 里,那套靠手势触发的流程根本无法启动;页面只能指望 WebView 拥有直接访问权限——而这完全取决于宿主如何配置。再加上安全上下文要求(拒绝 http://)以及 iframe 的 allow="gyroscope; accelerometer" 策略,大多数嵌入式页面什么都拿不到。
传感器失声后哪些东西会坏
- 摇一摇、倾斜、计步功能失效。 没有
devicemotion事件,就没有基于手势的交互。 - 360° / AR / 水平仪工具返回空。
deviceorientation缺位或全为零。 - 触觉反馈静默。 没有 VIBRATE 权限时
navigator.vibrate是空操作。 - iOS 13+ 双重陷阱。 WKWebView 没有
requestPermission(),Safari 那套路径跑不了;宿主必须原生授权。 - 嵌入式浏览器各不相同。 微信/微博容器常常既不暴露 API、也不提供弹窗途径,所以在 Safari 里做 QA 会掩盖故障。
runtime 的解法
宿主自有 runtime 桥接传感器层。宿主读取真实硬件——Android 用 SensorManager,iOS 用 Core Motion——并向页面暴露一套统一 API:运动、方向、触觉反馈,在所有引擎、所有嵌入式浏览器上都能用。权限由原生层一次性申请,数值无需经过那套因引擎而异的门槛就流向页面。一套传感器界面,真实硬件,处处可用。
| 维度 | WebView | 宿主自有 runtime |
|---|---|---|
| Android 方向传感器 | v55 前禁用,常返回零 | 真实硬件 |
| iOS 的 requestPermission | WKWebView 不暴露 | 原生授权 |
| 振动 | 需 VIBRATE 权限 | 原生触觉 |
| 安全上下文门槛 | 极易踩空 | 原生层处理 |
| 嵌入式浏览器 | 无 API、无弹窗 | 统一 API |
| 一致性 | 因引擎而异 | 统一 |
原生 App 在每台手机上都能读陀螺仪;而普通 WebView 在几乎任何一台上都读不到。runtime 给页面一套传感器层——以及它背后的真实硬件。
参考来源
- Chrome for Developers — WebView 概览(硬件传感器支持) — 表格显示方向传感器在 WebView v33 禁用、v55 起启用,振动受权限限制。
- WebKit Bug 203287 —「requestPermission() 只在 MobileSafari 暴露,不在 WKWebView」,并有 WebKit 工程师确认。
- MDN — DeviceMotionEvent — iOS 13+ 的 requestPermission() 手势要求与安全上下文约束。
- MDN — DeviceOrientationEvent — 方向数据的同样权限与上下文规则。
- MDN — Vibration API — navigator.vibrate 支持与 Android VIBRATE 权限要求。