【HarmonyOS】鸿蒙应用实现手机摇一摇功能
一、前言
手机摇一摇功能,是通过获取手机设备,加速度传感器接口,获取其中的数值,进行逻辑判断实现的功能。
在鸿蒙中手机设备传感器@ohos.sensor (传感器)的系统API 监听有以下:
@ohos.sensor (传感器)官网API
- 加速度传感器
- 环境光传感器
- 气压计传感器
- 重力传感器
- 陀螺仪传感器
- 霍尔传感器
- 心率传感器
- 湿度传感器
- 线性加速度传感器
- 地磁传感器
- 方向传感器
- 计步器传感器
- 接近光传感器
- 旋转矢量传感器
- 大幅动作检测传感器
- 佩戴检测传感器
其中摇一摇用到的,加速度传感器是多个维度测算 的,是指x、y、z 三个方向上的加速度值。
主要测算一些瞬时加速或减速的动作。比如测量手机的运动速度和方向。
当用户拿着手机运动时,会出现上下摆动的情况,这样可以检测出加速度在某个方向上来回改变,通过检测这个来回改变的次数,可以计算出步数。
在游戏里能通过加速度传感器触发特殊指令。日常应用中的一些甩动切歌、翻转静音等也都用到了这枚传感器。
注意:
至于为什么不用线性加速传感器,是因为线性加速度传感器和加速度传感器在定义、工作原理以及应用场景上存在显著的区别。线性主要是来检测物体在直线方向上的位移。
二、功能开发思路:
1.根据通过@ohos.sensor接口,获取加速度传感器的数值,添加权限:ohos.permission.ACCELEROMETER
dart
{
"name": "ohos.permission.ACCELEROMETER",
"reason": "$string:reason",
"usedScene": {
"abilities": [
"EntryAbility"
],
"when": "always"
}
}
dart
sensor.on(sensor.SensorId.ACCELEROMETER, (data: sensor.AccelerometerResponse) => {
}, { interval: 100000000 }); // 设置间隔为100000000 ns = 0.1 s
2.将x,y,z三个方向的数值进行绝对值处理,获取运动数值
dart
sensor.on(sensor.SensorId.ACCELEROMETER, (data: sensor.AccelerometerResponse) => {
console.info(this.TAG, 'Succeeded in invoking on. X-coordinate component: ' + data.x);
console.info(this.TAG,'Succeeded in invoking on. Y-coordinate component: ' + data.y);
console.info(this.TAG,'Succeeded in invoking on. Z-coordinate component: ' + data.z);
}, { interval: 100000000 }); // 设置间隔为100000000 ns = 0.1 s
3.根据运动数值进行判断,是否符合摇一摇的运动区间
dart
let x = Math.abs(data.x);
let y = Math.abs(data.y);
let z = Math.abs(data.z);
this.message = "x : " + x + " y: " + y + " z: " + z;
if(x > this.SWING_VAL || y > this.SWING_VAL || z > this.SWING_VAL){
promptAction.showToast({
message: "手机正在摇一摇!"
})
}
最后一步,当然就是使用手机设备进行代码功能效果的验证。
若没有真机设备,使用模拟器,点击该按钮可实现摇一摇手机的触发。
注意:
不使用加速传感器时,一定要移除监听。否则会白白损耗性能。
三、源码示例:
dart
import { sensor } from '@kit.SensorServiceKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { promptAction } from '@kit.ArkUI';
@Entry
@Component
struct SensorTestPage {
private TAG: string = "SenorTestPage";
private SWING_VAL: number = 50;
@State message: string = '';
aboutToAppear(): void {
try {
// 订阅加速度传感器返回的数据
sensor.on(sensor.SensorId.ACCELEROMETER, (data: sensor.AccelerometerResponse) => {
console.info(this.TAG, 'Succeeded in invoking on. X-coordinate component: ' + data.x);
console.info(this.TAG,'Succeeded in invoking on. Y-coordinate component: ' + data.y);
console.info(this.TAG,'Succeeded in invoking on. Z-coordinate component: ' + data.z);
let x = Math.abs(data.x);
let y = Math.abs(data.y);
let z = Math.abs(data.z);
this.message = "x : " + x + " y: " + y + " z: " + z;
if(x > this.SWING_VAL || y > this.SWING_VAL || z > this.SWING_VAL){
promptAction.showToast({
message: "手机正在摇一摇!"
})
}
}, { interval: 100000000 }); // 设置间隔为100000000 ns = 0.1 s
} catch (error) {
let e: BusinessError = error as BusinessError;
console.error(this.TAG, `Failed to invoke on. Code: ${e.code}, message: ${e.message}`);
}
}
aboutToDisappear(): void {
sensor.off(sensor.SensorId.ACCELEROMETER);
}
build() {
RelativeContainer() {
Text(this.message)
.id('SenorTestPageHelloWorld')
.fontSize(50)
.fontWeight(FontWeight.Bold)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
})
}
.height('100%')
.width('100%')
}
}
注意:
记得添加ohos.permission.ACCELEROMETER权限,否则无法监听到加速传感器!