Combined motion sensor providing comprehensive device orientation, acceleration, and rotation data. Ideal for applications requiring precise motion tracking and orientation awareness.
Provides access to comprehensive device motion data including acceleration with and without gravity, rotation rates, and device orientation.
/**
* DeviceMotion sensor instance providing access to comprehensive motion data
*/
declare const DeviceMotion: DeviceMotionSensor;
interface DeviceMotionSensor extends DeviceSensor<DeviceMotionMeasurement> {
/** Constant value representing standard gravitational acceleration for Earth (9.80665 m/s^2) */
Gravity: number;
/**
* Subscribe for updates to the device motion sensor
* @param listener - Callback invoked when device motion sensor update is available
* @returns Subscription that can be removed when done
*/
addListener(listener: Listener<DeviceMotionMeasurement>): Subscription;
/**
* Returns whether the device motion sensor is enabled on the device
* @returns Promise resolving to boolean denoting availability
*/
isAvailableAsync(): Promise<boolean>;
}
interface DeviceMotionMeasurement {
/** Device acceleration on the three axis (without gravity). Expressed in m/s^2 */
acceleration: null | {
x: number;
y: number;
z: number;
timestamp: number;
};
/** Device acceleration with the effect of gravity on the three axis. Expressed in m/s^2 */
accelerationIncludingGravity: {
x: number;
y: number;
z: number;
timestamp: number;
};
/** Device's orientation in space with alpha, beta, gamma rotation values */
rotation: {
alpha: number; // rotation around Z axis
beta: number; // rotation around X axis
gamma: number; // rotation around Y axis
timestamp: number;
};
/** Device's rate of rotation in space expressed in degrees per second */
rotationRate: null | {
alpha: number; // rotation in X axis
beta: number; // rotation in Y axis
gamma: number; // rotation in Z axis
timestamp: number;
};
/** Interval at which data is obtained from the native platform in milliseconds */
interval: number;
/** Device orientation based on screen rotation */
orientation: DeviceMotionOrientation;
}
enum DeviceMotionOrientation {
Portrait = 0,
RightLandscape = 90,
UpsideDown = 180,
LeftLandscape = -90,
}Usage Examples:
import { DeviceMotion, DeviceMotionOrientation } from "expo-sensors";
// Check availability
const isAvailable = await DeviceMotion.isAvailableAsync();
if (!isAvailable) {
console.log("DeviceMotion not available");
return;
}
// Subscribe to comprehensive motion updates
const subscription = DeviceMotion.addListener((data) => {
const { acceleration, accelerationIncludingGravity, rotation, rotationRate, orientation } = data;
// Handle device orientation changes
switch (orientation) {
case DeviceMotionOrientation.Portrait:
console.log("Device is in portrait mode");
break;
case DeviceMotionOrientation.RightLandscape:
console.log("Device is in right landscape mode");
break;
case DeviceMotionOrientation.UpsideDown:
console.log("Device is upside down");
break;
case DeviceMotionOrientation.LeftLandscape:
console.log("Device is in left landscape mode");
break;
}
// Process acceleration data (without gravity)
if (acceleration) {
const userAcceleration = Math.sqrt(
acceleration.x ** 2 + acceleration.y ** 2 + acceleration.z ** 2
);
console.log(`User acceleration: ${userAcceleration.toFixed(3)} m/s²`);
}
// Process rotation data
console.log(`Rotation - Alpha: ${rotation.alpha.toFixed(2)}°, Beta: ${rotation.beta.toFixed(2)}°, Gamma: ${rotation.gamma.toFixed(2)}°`);
// Process rotation rate
if (rotationRate) {
console.log(`Rotation rate - Alpha: ${rotationRate.alpha.toFixed(2)}°/s, Beta: ${rotationRate.beta.toFixed(2)}°/s, Gamma: ${rotationRate.gamma.toFixed(2)}°/s`);
}
});
// Set update interval
DeviceMotion.setUpdateInterval(100); // 10 Hz
// Clean up
subscription.remove();Access to Earth's gravitational acceleration constant.
The Gravity constant is accessible as a property of the DeviceMotion instance: DeviceMotion.Gravity
Usage Example:
import { DeviceMotion } from "expo-sensors";
console.log(`Earth's gravity: ${DeviceMotion.Gravity} m/s²`); // 9.80665
// Calculate user acceleration magnitude relative to gravity
const subscription = DeviceMotion.addListener((data) => {
if (data.acceleration) {
const userAccelMagnitude = Math.sqrt(
data.acceleration.x ** 2 +
data.acceleration.y ** 2 +
data.acceleration.z ** 2
);
// Express as multiples of gravity
const gForces = userAccelMagnitude / DeviceMotion.Gravity;
console.log(`User acceleration: ${gForces.toFixed(2)}g`);
}
});Shake Detection:
import { DeviceMotion } from "expo-sensors";
let shakeThreshold = 2.5; // g-forces
let lastShakeTime = 0;
let shakeTimeout = 1000; // ms between shakes
const subscription = DeviceMotion.addListener((data) => {
if (data.acceleration) {
const { x, y, z } = data.acceleration;
const acceleration = Math.sqrt(x * x + y * y + z * z) / DeviceMotion.Gravity;
const currentTime = Date.now();
if (acceleration > shakeThreshold && (currentTime - lastShakeTime) > shakeTimeout) {
console.log("Device shaken!");
lastShakeTime = currentTime;
// Handle shake event
}
}
});Orientation Tracking:
import { DeviceMotion, DeviceMotionOrientation } from "expo-sensors";
let currentOrientation = DeviceMotionOrientation.Portrait;
const subscription = DeviceMotion.addListener((data) => {
if (data.orientation !== currentOrientation) {
const oldOrientation = currentOrientation;
currentOrientation = data.orientation;
console.log(`Orientation changed from ${oldOrientation} to ${currentOrientation}`);
// Handle orientation change in your app
handleOrientationChange(currentOrientation);
}
});
function handleOrientationChange(orientation: DeviceMotionOrientation) {
switch (orientation) {
case DeviceMotionOrientation.Portrait:
// Adjust UI for portrait
break;
case DeviceMotionOrientation.RightLandscape:
case DeviceMotionOrientation.LeftLandscape:
// Adjust UI for landscape
break;
case DeviceMotionOrientation.UpsideDown:
// Handle upside down if needed
break;
}
}Tilt Detection:
import { DeviceMotion } from "expo-sensors";
const subscription = DeviceMotion.addListener((data) => {
const { rotation } = data;
// Calculate tilt angles
const tiltX = rotation.beta; // Forward/backward tilt
const tiltY = rotation.gamma; // Left/right tilt
// Detect significant tilt (>30 degrees)
const significantTiltThreshold = 30;
if (Math.abs(tiltX) > significantTiltThreshold) {
console.log(`Significant forward/backward tilt: ${tiltX.toFixed(1)}°`);
}
if (Math.abs(tiltY) > significantTiltThreshold) {
console.log(`Significant left/right tilt: ${tiltY.toFixed(1)}°`);
}
});