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.