HarmonyOS 鸿蒙Next中摇一摇/震动功能

HarmonyOS 鸿蒙Next中摇一摇/震动功能 摇一摇跳转红包界面

https://developer.huawei.com/consumer/cn/doc/architecture-guides/shaking_to_dialog-0000002238306420

震动

https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/vibrator

权限:ohos.permission.VIBRATE

Demo:

import { promptAction } from "@kit.ArkUI";
import { sensor, vibrator } from "@kit.SensorServiceKit";
import { hilog } from "@kit.PerformanceAnalysisKit";
import { BusinessError } from "@kit.BasicServicesKit";


export class SensorToJump {
  JUMPING_DEGREE: number = 36;
  private static singleton_: SensorToJump;

  public static instance(): SensorToJump {
    if (!SensorToJump.singleton_) {
      SensorToJump.singleton_ = new SensorToJump();
    }
    return SensorToJump.singleton_;
  }

  // 手机是否开始计算摇动角度
  private shaking: boolean = false
  // 手机摇晃Y轴角度
  // 前
  private y1: number = 0
  // 后
  private y2: number = 0
  // 前后变化差值
  private yChange: number = this.y2 - this.y1
  // 手机摇晃X轴角度
  // 前
  private x1: number = 0
  // 后
  private x2: number = 0
  //前后变化差值
  private xChange: number = this.x2 - this.x1
  // 手机摇晃Z轴角度
  // 前
  private z1: number = 0
  // 后
  private z2: number = 0
  private zChange: number = this.z2 - this.z1
  // 手机晃动角度偏差和
  private changes: number = 0

  // 通过方位传感器监听手机摇晃角度X,Y,Z轴的和是否达到
  public sensorOn() {
    // let canJump: boolean = false;
    this.shaking = true;
    let number = 0
    try {
      sensor.on(sensor.SensorId.ORIENTATION, (data: sensor.OrientationResponse) => {
        this.y1 = data.gamma;
        this.x1 = data.beta;
        this.z1 = data.alpha;
        setTimeout(() => {
          this.y2 = data.gamma;
          this.x2 = data.beta;
          this.z2 = data.alpha;
        }, 400)
        setTimeout(() => {
        }, 500)
        if (this.y2 > 0 || this.x2 > 0 || this.z2 > 0) {
          this.yChange = this.y2 - this.y1
          this.xChange = this.x2 - this.x1
          this.zChange = this.z2 - this.z1
          this.changes = Math.abs(this.xChange) + Math.abs(this.yChange) + Math.abs(this.zChange)
          if (this.shaking && this.changes > this.JUMPING_DEGREE) {
            number++
            promptAction.showToast({
              message: "摇一摇触发" + number
            })
            //触发马达振动
            this.motorVibration();
            //按照预置振动效果触发马达振动  很短
            // this.motorVibration1();
            //按照自定义振动配置文件触发马达振动

            this.shaking = false;
            setTimeout(() => {
              this.shaking = true;
            }, 1000)
          }
        }
      }, { interval: 1000000000 }) //1秒
    } catch (e) {
      hilog.error(0xFFFF, "摇一摇", `Failed to invoke on. Code: ${e.code}, message: ${e.message}`);
    }
  }

  private motorVibration1() {
    try {
      vibrator.isSupportEffect('haptic.effect.soft', (err: BusinessError, state: boolean) => {
        if (err) {
          console.error(`Failed to query effect. Code: ${err.code}, message: ${err.message}`);
          return;
        }
        console.info('Succeed in querying effect');
        if (state) {
          try {
            // 触发马达振动
            vibrator.startVibration({
              type: 'preset',
              effectId: 'haptic.effect.soft',
              count: 20,
              intensity: 50,
            }, {
              usage: 'unknown'
            }, (error: BusinessError) => {
              if (error) {
                console.error(`Failed to start vibration. Code: ${error.code}, message: ${error.message}`);
              } else {
                console.info('Succeed in starting vibration');
              }
            });
          } catch (error) {
            let e: BusinessError = error as BusinessError;
            console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);
          }
        }
      });
    } catch (error) {
      let e: BusinessError = error as BusinessError;
      console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);
    }
  }

  private motorVibration() {
    try {
      vibrator.startVibration({
        type: 'time',
        duration: 1000,
      }, {
        id: 0,
        usage: 'alarm'
      }, (error: BusinessError) => {
        if (error) {
          console.error(`Failed to start vibration. Code: ${error.code}, message: ${error.message}`);
          return;
        }
        console.info('Succeed in starting vibration');
      });
    } catch (err) {
      let e: BusinessError = err as BusinessError;
      console.error(`An unexpected error occurred. Code: ${e.code}, message: ${e.message}`);
    }
  }

  // 关闭传感器
  public sensorOff() {
    sensor.off(sensor.SensorId.ORIENTATION);
  }
}

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';

  onPageShow(): void {
    SensorToJump.instance().sensorOn()
  }

  onPageHide(): void {
    SensorToJump.instance().sensorOff()
  }

  build() {
    RelativeContainer() {
      Text(this.message)
        .id('HelloWorld')
        .fontSize($r('app.float.page_text_font_size'))
        .fontWeight(FontWeight.Bold)
        .alignRules({
          center: { anchor: '__container__', align: VerticalAlign.Center },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })
        .onClick(() => {
          this.message = 'Welcome';
        })
    }
    .height('100%')
    .width('100%')
  }
}

更多关于HarmonyOS 鸿蒙Next中摇一摇/震动功能的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

666

更多关于HarmonyOS 鸿蒙Next中摇一摇/震动功能的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


HarmonyOS NEXT的摇一摇功能通过传感器管理模块实现。设备使用加速度传感器监听设备动态,当检测到符合预设阈值和方向的加速度变化时触发回调事件。震动功能由Vibrator模块提供,支持预定义震动效果和自定义震动时长与强度。开发者可通过@ohos.sensor和@ohos.vibrator模块调用相关API实现功能集成。

在HarmonyOS Next中实现摇一摇和震动功能,需要结合传感器监听和振动器API。以下是关键实现要点:

摇一摇检测:

使用@kit.SensorServiceKitsensor.on()监听ORIENTATION传感器,通过计算X/Y/Z轴角度变化差值判断是否达到摇动阈值(示例中设为36度)。触发后调用promptAction.showToast()显示提示。

震动功能:

通过@kit.SensorServiceKitvibrator.startVibration()实现。需在module.json5中声明ohos.permission.VIBRATE权限。支持两种模式:

  • 时间模式:type: 'time',指定持续时间(如1000ms)
  • 预设效果模式:type: 'preset',使用系统预置效果(如haptic.effect.soft

注意事项:

  1. 传感器监听需及时关闭(sensor.off()),避免资源浪费
  2. 振动强度可配置,但需考虑用户体验
  3. 摇动阈值需根据实际场景调整,避免误触发

代码示例已完整展示从摇动检测到震动反馈的流程,可直接参考实现。

回到顶部