Read the original article:How to implement compass functionality with efficient sensor handling
Context
Compass functionality is a common requirement in navigation, fitness, and outdoor applications. In HarmonyOS, the ROTATION_VECTOR sensor can be used to detect the device's orientation in real-time and calculate the azimuth (the angle between the device's forward direction and magnetic north).
Description
This implementation uses the sensor.SensorId.ROTATION_VECTOR to access device orientation. It computes the azimuth (0°–360°) from quaternion values (x, y, z, w) and updates a UI with this direction. The azimuth value is also used to rotate a compass image accordingly.
The app listens to sensor updates at a defined interval and stops listening when the page disappears. Additionally, permission for the accelerometer must be declared in the app’s configuration.
Solution
Permission Declaration
"requestPermissions": [
{
"name": "ohos.permission.ACCELEROMETER"
}
]
Sensor Setup
sensor.on(sensor.SensorId.ROTATION_VECTOR, (data) => {
const { x, y, z, w } = data
const siny_cosp = 2 * (w * z + x * y)
const cosy_cosp = 1 - 2 * (y * y + z * z)
const azimuthRad = Math.atan2(siny_cosp, cosy_cosp)
const azimuthDeg = (azimuthRad * 180 / Math.PI + 360) % 360
this.azimuth = Math.round(azimuthDeg)
}, {
interval: 100_000_000 // 100ms
})
Lifecycle Management
aboutToAppear() {
this.onPageShow()
}
aboutToDisappear() {
sensor.off(sensor.SensorId.ROTATION_VECTOR)
}
UI Update
Text(`Azimuth: ${this.azimuth}°`)
Image($r('app.media.compass'))
.rotate({ angle: -this.azimuth })
Key Takeaways
- Use
ROTATION_VECTORfor smooth compass readings without magnetic field noise. - Convert quaternion values to azimuth using trigonometric formulas.
- Use
sensor.on()andsensor.off()in lifecycle methods for clean resource usage. - Declare sensor permissions (
ACCELEROMETER) inmodule.json5to avoid permission errors.
Top comments (0)