One Logo Pool Ball
wwwwwwwwwwwwwwwwwww

Motion sensors

Read accelerometer, gyroscope, magnetometer, and fused device-motion streams on iOS and Android.

One.Motion reports which motion sensors the device can use and subscribes to live readings. It requires an iOS or Android native build. Check availability before subscribing, because iPads and simulator devices can lack sensors. The iOS Simulator has no physical motion input.

import { One } from 'one'
const availability = One.Motion.getAvailability()
if (availability.accelerometer) {
const remove = One.Motion.addListener(
'accelerometer', 100,
(reading) => {
// reading.value has x, y, z acceleration in units of g
console.log(reading.value, reading.timestampMs)
},
(code, message) => console.error(code, message)
)
// stop updates when the screen no longer needs them
remove()
}

getAvailability() returns accelerometer, gyroscope, magnetometer, and deviceMotion booleans. addListener(sensor, intervalMs, onReading, onError) accepts an interval from 0 through 1000 milliseconds and returns an idempotent remover. Zero requests the sensor’s fastest hardware rate. Positive intervals request that delay, limited by the hardware minimum. The same rule applies on both platforms, without a fixed 16 ms floor. Core Motion clamps the request to its hardware limit, commonly about 100 Hz; Android uses SENSOR_DELAY_FASTEST for zero and respects each sensor’s minDelay for a positive request. The operating system controls the actual frequency, and callbacks may be less frequent. Multiple listeners share one sensor stream; each receives no more than its requested rate. Remove listeners when their screen unmounts to stop the hardware stream.

All readings have a Unix timestampMs, sensor name, and value with x, y, z. Accelerometer values are in units of gravity, gyroscope values are radians per second, and magnetometer values are microteslas. For deviceMotion, value is gravity-free user acceleration in units of gravity. It also includes gravity, userAcceleration, rotationRate, and attitude; attitude x/y/z are roll/pitch/yaw in radians. Axes use the device coordinate system: x points right, y toward the top, and z out of the screen in the device’s natural orientation. Android acceleration and gravity are converted to Core Motion’s sign and units. Attitude uses an arbitrary horizontal reference on both platforms; yaw is not a compass heading. Android device motion requires linear acceleration, gravity, gyroscope, and game rotation vector sensors.

The error callback receives E_MOTION_UNAVAILABLE when the sensor is absent, E_MOTION_INPUT for a native interval validation failure, or E_MOTION_STREAM if the native stream fails. The JavaScript wrapper throws TypeError for an invalid sensor or callbacks and RangeError for an invalid interval before registering a listener. Basic accelerometer, gyroscope, magnetometer, and device-motion streams do not request a motion and fitness permission. Android includes the normal install-time HIGH_SAMPLING_RATE_SENSORS permission so zero can request rates above 200 Hz on hardware that supports them. Other Core Motion services such as pedometer and activity tracking need NSMotionUsageDescription and are not part of this API.

The iOS 27 simulator proof checks the real Core Motion availability flags, unavailable-stream errors, and input validation. Live values and sensor frequency need a physical-device proof.

On web, DeviceMotionEvent supplies acceleration and rotation rate, and DeviceOrientationEvent supplies roll, pitch, and yaw. Acceleration is converted to Core Motion’s sign and gravity units; angular values use radians. Each subscription retains its own requested interval and remover. Device-motion fields are omitted when the browser does not provide them. Magnetometer readings are unavailable because these events do not expose magnetic field vectors.

Browser availability starts false and becomes true only after observing finite readings. Calling getAvailability() starts observation without requesting permission. To request access on browsers with a motion permission prompt, call addListener from a user gesture; a refusal reaches onError as E_MOTION_PERMISSION. Event constructors alone do not prove hardware exists. Desktop browsers can expose constructors while delivering no readings. Browsers control the sampling rate and can suspend events in hidden pages. SSR reports all sensors false and retains inert listeners.

Edit this page on GitHub.