DeviceMotion, DeviceOrientation, and Vibration are first-class on the mobile web — until they run inside a WebView. Android System WebView left the Device Orientation API disabled until v55 and still returns all-zero acceleration on many builds unless the right flags and permissions are set; Vibration needs an explicit VIBRATE permission. On iOS, WKWebView does not even expose requestPermission(), so the gesture-gated iOS 13+ flow never starts. A host-owned runtime bridges the sensor layer — one API that reads the real hardware on every engine.
Android: disabled by default, silent when "on"
The Chromium documentation is plain: among hardware-sensor APIs, the Device Orientation API was disabled in WebView v33 and only enabled from v55. Geolocation, media capture, and Vibration are partly gated too. And "enabled" is not "working" — many WebView builds return acceleration as all zeros or never fire the event unless the page is served over https and the app grants the runtime permission. A common failure is a "shake to action" feature that simply never triggers because the container did not forward the sensor. Vibration (navigator.vibrate) needs android.permission.VIBRATE; without it the call is a silent no-op.
iOS: the permission API is missing entirely
From iOS 13, Safari requires DeviceMotionEvent.requestPermission() / DeviceOrientationEvent.requestPermission() — a dialog triggered by a user gesture — before any motion or orientation event fires. But that API is not exposed in WKWebView. WebKit's own bug tracker (bug 203287) records it: "The requestPermission() API is only exposed in MobileSafari, not WKWebView." So inside an app's WebView the gesture-gated flow cannot even begin; the page must instead rely on the WebView having direct access, which depends entirely on how the host configured it. Add the secure-context requirement (no http://) and the iframe allow="gyroscope; accelerometer" policy, and most embedded pages get nothing.
What breaks when sensors go quiet
- Shake, tilt, and step features die. No
devicemotionevents means no gesture-based UX. - 360° / AR / level tools return nothing.
deviceorientationis absent or all-zero. - Haptics are silent.
navigator.vibrateis a no-op without the VIBRATE permission. - iOS 13+ double trap. No
requestPermission()in WKWebView, so the Safari path cannot run; the host must grant natively. - Embedded browsers diverge. WeChat/Weibo containers often expose neither the API nor a way to prompt, so QA in Safari hides the break.
The runtime fix
A host-owned runtime bridges the sensor layer. The host reads the real hardware — SensorManager on Android, Core Motion on iOS — and exposes one uniform API to the page: motion, orientation, and haptic feedback that work on every engine and every embedded browser. Permission is requested once, natively, and the values flow to the page without the per-engine gating. One sensor surface, real hardware, everywhere.
| Dimension | WebView | Host-owned runtime |
|---|---|---|
| Android Device Orientation | Disabled < v55, often zero | Real hardware |
| iOS requestPermission | Not exposed in WKWebView | Native grant |
| Vibration | Needs VIBRATE permission | Native haptics |
| Secure context gate | Easy to miss | Handled natively |
| Embedded browsers | No API, no prompt | Uniform API |
| Consistency | Per-engine | Uniform |
A native app reads the gyroscope on every phone. A stock WebView reads it on almost none. A runtime gives the page one sensor layer — and the real hardware behind it.
Sources
- Chrome for Developers — WebView overview (hardware sensor support) — the table showing Device Orientation disabled in WebView v33 and enabled from v55, and Vibration gated by permission.
- WebKit Bug 203287 — "requestPermission() is only exposed in MobileSafari, not WKWebView," with a WebKit engineer's confirmation.
- MDN — DeviceMotionEvent — the iOS 13+
requestPermission()gesture requirement and the secure-context constraint. - MDN — DeviceOrientationEvent — the same permission and context rules for orientation data.
- MDN — Vibration API —
navigator.vibratesupport and the Android VIBRATE permission requirement.