开源 Arkts 鸿蒙应用 开发(十二)传感器的使用

 文章的目的为了记录使用Arkts 进行Harmony app 开发学习的经历。本职为嵌入式软件开发,公司安排开发app,临时学习,完成app的开发。开发流程和要点有些记忆模糊,赶紧记录,防止忘记。

 相关链接:

开源 Arkts 鸿蒙应用 开发(一)工程文件分析-CSDN博客

开源 Arkts 鸿蒙应用 开发(二)封装库.har制作和应用-CSDN博客

开源 Arkts 鸿蒙应用 开发(三)Arkts的介绍-CSDN博客

开源 Arkts 鸿蒙应用 开发(四)布局和常用控件-CSDN博客

开源 Arkts 鸿蒙应用 开发(五)控件组成和复杂控件-CSDN博客

开源 Arkts 鸿蒙应用 开发(六)数据持久--文件和首选项存储-CSDN博客

开源 Arkts 鸿蒙应用 开发(七)数据持久--sqlite关系数据库-CSDN博客

开源 Arkts 鸿蒙应用 开发(八)多媒体--相册和相机-CSDN博客

开源 Arkts 鸿蒙应用 开发(九)通讯--tcp客户端-CSDN博客

开源 Arkts 鸿蒙应用 开发(十)通讯--Http-CSDN博客

开源 Arkts 鸿蒙应用 开发(十一)证书和包名修改-CSDN博客

开源 Arkts 鸿蒙应用 开发(十二)传感器的使用-CSDN博客

开源 Arkts 鸿蒙应用 开发(十三)音频--MP3播放-CSDN博客

 推荐链接:

开源 java android app 开发(一)开发环境的搭建-CSDN博客

开源 java android app 开发(二)工程文件结构-CSDN博客

开源 java android app 开发(三)GUI界面布局和常用组件-CSDN博客

开源 java android app 开发(四)GUI界面重要组件-CSDN博客

开源 java android app 开发(五)文件和数据库存储-CSDN博客

开源 java android app 开发(六)多媒体使用-CSDN博客

开源 java android app 开发(七)通讯之Tcp和Http-CSDN博客

开源 java android app 开发(八)通讯之Mqtt和Ble-CSDN博客

开源 java android app 开发(九)后台之线程和服务-CSDN博客

开源 java android app 开发(十)广播机制-CSDN博客

开源 java android app 开发(十一)调试、发布-CSDN博客

开源 java android app 开发(十二)封库.aar-CSDN博客

推荐链接:

开源C# .net mvc 开发(一)WEB搭建_c#部署web程序-CSDN博客

开源 C# .net mvc 开发(二)网站快速搭建_c#网站开发-CSDN博客

开源 C# .net mvc 开发(三)WEB内外网访问(VS发布、IIS配置网站、花生壳外网穿刺访问)_c# mvc 域名下不可訪問內網,內網下可以訪問域名-CSDN博客

开源 C# .net mvc 开发(四)工程结构、页面提交以及显示_c#工程结构-CSDN博客

开源 Arkts 鸿蒙应用 开发(十)通讯--Http数据传输-CSDN博客开源 C# .net mvc 开发(五)常用代码快速开发_c# mvc开发-CSDN博客

本章内容主HarmonyOS next 系统上的传感器如何使用,获取传感器列表,然后建立监测,就可以获得传感器的实时数据。

工程中,只需修改module.json5和Index.ets的代码就可以完成APP。

1.传感器怎么用

2.设置权限

3.所有代码

4.显示效果

一、获取传感器列表

当设备需要获取传感器数据时,可以使用sensor模块。比较常用的是,加速度计,陀螺仪等。

首先获取所有传感器,其次获得传感器参数,最后建立监测。

1.1  首先将所有可用的传感器打印出来

以下为代码

sensor.getSensorList((error: BusinessError, data: Array<sensor.Sensor>) => {
    if (error) {
        console.error('getSensorList failed');
    } else {
        console.info('getSensorList success');
        for (let i = 0; i < data.length; i++) {
            console.info(JSON.stringify(data[i]));
        }
    }
});

打印效果,需要记住打印的传感器名称和Id方便后面使用

1.2  查询设备支持的所有传感器的参数。

sensor.getSensorList((error: BusinessError, data: Array<sensor.Sensor>) => {
    if (error) {
        console.error('getSensorList failed');
    } else {
        console.info('getSensorList success');
        for (let i = 0; i < data.length; i++) {
            console.info(JSON.stringify(data[i]));
        }
    }
});

1.3  注册监听。可以通过on()和once()两种接口监听传感器的调用结果。通过interval设置为100000000纳秒

import { sensor } from '@kit.SensorServiceKit';
import { BusinessError } from '@kit.BasicServicesKit';

try { 
  sensor.on(sensor.SensorId.ACCELEROMETER, (data: sensor.AccelerometerResponse) => {
       console.info("Succeeded in obtaining data. x: " + data.x + " y: " + data.y + " z: " + data.z);
  }, { interval: 100000000 });
} catch (error) {
   let e: BusinessError = error as BusinessError;
   console.error(`Failed to get sensorList. Code: ${e.code}, message: ${e.message}`);
}

二、传感器权限

鸿蒙权限查询网址为文档中心

这里就使用了加速度计,地磁的权限,陀螺仪。其中地磁和加速度计使用的同一个权限,估计地磁是用加速度计进行计算而得。

下面为module.json5文件中权限代码

    "requestPermissions": [
      {
        "name" : "ohos.permission.ACCELEROMETER",
        "reason": "$string:EntryAbility_label",
        "usedScene": {
          "abilities": [
            "FormAbility"
          ],
          "when":"inuse"
        }
      },
      {
        "name": "ohos.permission.GYROSCOPE",
        "reason": "$string:EntryAbility_label",
        "usedScene": {
          "abilities": ["EntryAbility"], // 替换为你的Ability名称
          "when": "inuse"
        }
      }
    ]

三、所有源码,实现了按下监测按钮,将加速度计,地磁,陀螺仪的数据显示到页面上的功能

以下为Index.ets的代码

import { sensor } from '@kit.SensorServiceKit';
import { BusinessError } from '@kit.BasicServicesKit';

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

  @State acc_x: string = '';
  @State acc_y: string = '';
  @State acc_z: string = '';

  @State mag_x: string = '';
  @State mag_y: string = '';
  @State mag_z: string = '';

  @State gyr_x: string = '';
  @State gyr_y: string = '';
  @State gyr_z: string = '';

  myCheck()
  {
    sensor.getSensorList((error: BusinessError, data: Array<sensor.Sensor>) => {
      if (error) {
        console.error('getSensorList failed');
      } else {
        console.info('getSensorList success');

        for (let i = 0; i < data.length; i++) {
          console.info("sersorprint:",JSON.stringify(data[i]));
        }


        /*
        for (let i = 0; i < data.length; i++) {
          let tmp =JSON.stringify(data[i]);
          if(tmp.includes("acc_s") || tmp.includes("gyro_s") || tmp.includes("als_s") || tmp.includes("mag_s"))
          {
            console.info("sersorprint:",tmp);
          }

        }
        * */
      }
    });
  }

  myListenAcc()
  {
    try {

      sensor.on(sensor.SensorId.ACCELEROMETER, (data: sensor.AccelerometerResponse) => {
        console.info("Succeeded in ACCELEROMETER data. x: " + data.x + " y: " + data.y + " z: " + data.z);
        this.acc_x = data.x.toString().substring(0, 5);;
        this.acc_y = data.y.toString().substring(0, 5);;
        this.acc_z = data.z.toString().substring(0, 5);;
      }, { interval: 1000000000 });

      /*
      sensor.once(sensor.SensorId.ACCELEROMETER, (data: sensor.AccelerometerResponse) => {
        console.info("Succeeded in obtaining data. x: " + data.x + " y: " + data.y + " z: " + data.z);

      });
      */

    } catch (error) {
      let e: BusinessError = error as BusinessError;
      console.error(`Failed to get sensorList. Code: ${e.code}, message: ${e.message}`);
    }
  }

  myListenMAG() {
    try {
      // 使用磁力计传感器ID和正确的数据类型
      sensor.on(sensor.SensorId.MAGNETIC_FIELD, (data: sensor.MagneticFieldResponse) => {
        console.info(
          "磁力计数据: " +
            "X=" + data.x.toFixed(2) + " μT, " +  // X轴磁场强度(微特斯拉)
            "Y=" + data.y.toFixed(2) + " μT, " +  // Y轴磁场强度
            "Z=" + data.z.toFixed(2) + " μT"      // Z轴磁场强度
        );

        this.mag_x = data.x.toString().substring(0, 5);;
        this.mag_y = data.y.toString().substring(0, 5);;
        this.mag_z = data.z.toString().substring(0, 5);;

      }, { interval: 1000000000 }); // 采样间隔200ms(单位:纳秒)

    } catch (error) {
      let e: BusinessError = error as BusinessError;
      console.error(`磁力计监听失败. Code: ${e.code}, message: ${e.message}`);
    }
  }
  myListenGYR() {
    try {
      // 使用陀螺仪传感器ID和正确的数据类型
      sensor.on(sensor.SensorId.GYROSCOPE, (data: sensor.GyroscopeResponse) => {
        console.info(
          "陀螺仪数据: " +
            "X=" + data.x.toFixed(4) + " rad/s, " +  // X轴角速度(弧度/秒)
            "Y=" + data.y.toFixed(4) + " rad/s, " +  // Y轴角速度
            "Z=" + data.z.toFixed(4) + " rad/s"      // Z轴角速度
        );

        this.gyr_x = data.x.toString().substring(0, 5);;
        this.gyr_y = data.y.toString().substring(0, 5);;
        this.gyr_z = data.z.toString().substring(0, 5);;

      }, { interval: 100000000 }); // 采样间隔100ms(单位:纳秒)

    } catch (error) {
      let e: BusinessError = error as BusinessError;
      console.error(`陀螺仪监听失败. Code: ${e.code}, message: ${e.message}`);
    }
  }

  build() {
    RelativeContainer() {
      Column() {
        // 加速度计数据卡片
        Column() {
          Text('加速度计 (m/s²)')
            .fontSize(18)
            .fontColor('#1E90FF')
            .margin({ bottom: 8 })

          Row() {
            Column() {
              Text('X轴')
                .fontSize(14)
                .fontColor('#666')
              Text(this.acc_x)
                .fontSize(16)
                .fontWeight(FontWeight.Bold)
            }
            .width('33%')
            .alignItems(HorizontalAlign.Center)

            Column() {
              Text('Y轴')
                .fontSize(14)
                .fontColor('#666')
              Text(this.acc_y)
                .fontSize(16)
                .fontWeight(FontWeight.Bold)
            }
            .width('33%')
            .alignItems(HorizontalAlign.Center)

            Column() {
              Text('Z轴')
                .fontSize(14)
                .fontColor('#666')
              Text(this.acc_z)
                .fontSize(16)
                .fontWeight(FontWeight.Bold)
            }
            .width('33%')
            .alignItems(HorizontalAlign.Center)
          }
          .width('100%')
          .margin({ bottom: 16 })
        }
        .padding(12)
        .backgroundColor('#F5F5F5')
        .borderRadius(8)
        .width('96%')

        // 磁力计数据卡片
        Column() {
          Text('磁力计 (μT)')
            .fontSize(18)
            .fontColor('#FF6B81')
            .margin({ bottom: 8 })

          Row() {
            Column() {
              Text('X轴')
                .fontSize(14)
                .fontColor('#666')
              Text(this.mag_x)
                .fontSize(16)
                .fontWeight(FontWeight.Bold)
            }
            .width('33%')
            .alignItems(HorizontalAlign.Center)

            Column() {
              Text('Y轴')
                .fontSize(14)
                .fontColor('#666')
              Text(this.mag_y)
                .fontSize(16)
                .fontWeight(FontWeight.Bold)
            }
            .width('33%')
            .alignItems(HorizontalAlign.Center)

            Column() {
              Text('Z轴')
                .fontSize(14)
                .fontColor('#666')
              Text(this.mag_z)
                .fontSize(16)
                .fontWeight(FontWeight.Bold)
            }
            .width('33%')
            .alignItems(HorizontalAlign.Center)
          }
          .width('100%')
          .margin({ bottom: 16 })
        }
        .padding(12)
        .backgroundColor('#FFF0F5')
        .borderRadius(8)
        .width('96%')

        // 陀螺仪数据卡片
        Column() {
          Text('陀螺仪 (rad/s)')
            .fontSize(18)
            .fontColor('#32CD32')
            .margin({ bottom: 8 })

          Row() {
            Column() {
              Text('X轴')
                .fontSize(14)
                .fontColor('#666')
              Text(this.gyr_x)
                .fontSize(16)
                .fontWeight(FontWeight.Bold)
            }
            .width('33%')
            .alignItems(HorizontalAlign.Center)

            Column() {
              Text('Y轴')
                .fontSize(14)
                .fontColor('#666')
              Text(this.gyr_y)
                .fontSize(16)
                .fontWeight(FontWeight.Bold)
            }
            .width('33%')
            .alignItems(HorizontalAlign.Center)

            Column() {
              Text('Z轴')
                .fontSize(14)
                .fontColor('#666')
              Text(this.gyr_z)
                .fontSize(16)
                .fontWeight(FontWeight.Bold)
            }
            .width('33%')
            .alignItems(HorizontalAlign.Center)
          }
          .width('100%')
        }
        .padding(12)
        .backgroundColor('#F0FFF0')
        .borderRadius(8)
        .width('96%')

        Column() {
          Button('开始监测')
            .width(150)
            .height(50)
            .margin(10)
            .onClick(() => {
              this.myCheck()
              this.myListenAcc();
              this.myListenMAG();
              this.myListenGYR();
            })
        }
      }
      .width('100%')
      .padding(8)
    }
  }
}

四、显示效果

<think>好的,我现在需要帮助用户了解鸿蒙应用开发中的自定义起床仪表盘。首先,我得回忆一下鸿蒙应用开发的基础知识,特别是关于UI设计和自定义组件的内容。用户提到的“自定义起床仪表盘”听起来像是一个显示起床相关数据的仪表盘界面,可能包括时间、天气、睡眠质量等信息,并且需要个性化的设计。 首先,我应该考虑鸿蒙开发的核心技术,比如使用ArkTS进行开发,以及方舟框架的UI组件。用户可能需要知道如何布局界面,使用哪些组件,比如进度条、文本显示、图表等。另外,自定义组件可能涉及绘制自定义图形,比如圆形进度条或者动画效果,这时候可能需要用到Canvas组件或者自定义绘制方法。 接下来,我需要分步骤来介绍如何实现这个仪表盘。可能需要从项目创建开始,然后设计UI布局,添加数据绑定,最后实现交互逻辑。同时,要确保代码符合鸿蒙的开发规范,比如使用声明式UI和状态管理。 可能还需要考虑数据来源,比如如何获取用户的起床时间、睡眠数据等。鸿蒙系统可能提供了一些API来访问健康数据或系统时间,需要确认这些API的使用方法。如果用户没有提到具体的数据源,可能需要建议使用模拟数据或者接入第三方服务。 另外,用户可能希望仪表盘有美观的动画效果,比如指针转动、数字渐变等。这时候需要介绍鸿蒙的动画API,比如属性动画或自定义动画的实现方式。 在结构方面,应该按照逻辑顺序,从环境搭建到具体实现步骤,逐步引导用户完成项目。同时,提供代码示例时,要确保语法正确,符合鸿蒙的ArkTS规范,比如使用@Entry、@Component装饰器,以及状态变量的管理。 可能遇到的问题包括自定义组件的性能优化、数据更新的实时性以及不同设备的适配。需要提醒用户注意这些方面,并给出解决方案,比如使用异步加载数据、响应式布局等。 最后,总结关键点,强调鸿蒙开发的灵活性和强大功能,鼓励用户动手实践,并参考官方文档和社区资源解决具体问题。</think>### 鸿蒙应用开发:自定义起床仪表盘实现指南 #### 一、技术准备 1. **开发环境**: - 安装DevEco Studio 3.1+(需配置HarmonyOS SDK) - 创建`Empty Ability`工程(API Version ≥ 9) 2. **核心能力**: - ArkUI声明式开发范式 - Canvas自定义绘制 - 数据绑定与状态管理 - 动画系统(属性动画/关键帧动画) #### 二、架构设计 ```typescript // 数据模型示例 class WakeUpData { targetTime: string = "07:30" currentTime: string = "06:45" sleepQuality: number = 85 // 百分比 weather: string = "晴" } ``` #### 三、界面实现步骤 **1. 基础布局搭建** ```typescript @Entry @Component struct Dashboard { @State wakeData: WakeUpData = new WakeUpData() build() { Column() { // 顶部时间显示 TimeDisplay(this.wakeData) // 主仪表盘 CircularProgress(this.wakeData.sleepQuality) // 底部信息 WeatherInfo(this.wakeData.weather) } .width('100%') .height('100%') .backgroundGradient({ angle: 180, colors: ['#1a237e', '#0d47a1'] }) } } ``` **2. 自定义圆形进度条** ```typescript @Component struct CircularProgress { @Prop percent: number build() { Canvas() .width(200) .height(200) .onReady((ctx: CanvasRenderingContext2D) => { // 绘制背景环 ctx.beginPath() ctx.arc(100, 100, 90, 0, Math.PI * 2) ctx.strokeStyle = 'rgba(255,255,255,0.2)' ctx.lineWidth = 12 ctx.stroke() // 绘制进度环 ctx.beginPath() ctx.arc(100, 100, 90, -Math.PI/2, (Math.PI*2)*this.percent/100 - Math.PI/2) ctx.strokeStyle = this.getProgressColor() ctx.lineWidth = 12 ctx.stroke() }) } private getProgressColor(): string { return this.percent >= 80 ? '#00e676' : this.percent >= 60 ? '#ffd600' : '#ff3d00' } } ``` **3. 动态时间显示组件** ```typescript @Component struct TimeDisplay { @Link currentTime: string build() { Row() { Text(this.currentTime) .fontSize(32) .fontColor('#ffffff') .onAppear(() => { setInterval(() => { this.currentTime = this.getFormattedTime() }, 1000) }) } } private getFormattedTime(): string { const now = new Date() return `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}` } } ``` #### 四、高级功能扩展 **1. 交互动画实现** ```typescript @Extend(Text) function scaleEffect() { .fontSize(20) .onClick(() => { animate({ duration: 300, iterations: 1 }, () => { this.scale({ x: 1.2, y: 1.2 }) }).then(() => { animate({ duration: 200 }, () => { this.scale({ x: 1, y: 1 }) }) }) }) } ``` **2. 数据持久化** ```typescript // 使用Preferences存储用户设置 async saveWakeUpTime(time: string) { try { const prefs = await dataPreferences.getPreferences(this.context, 'userSettings') await prefs.put('wakeTime', time) await prefs.flush() } catch (err) { console.error('保存失败: ' + err) } } ``` #### 五、最佳实践建议 1. **性能优化**: - 使用`LazyForEach`加载长列表 - 复杂计算使用Web Worker - 避免频繁的UI重绘 2. **设备适配**: ```typescript @Styles function adaptiveFont() { .fontSize(DeviceInfo.screenType === ScreenType.SMALL ? 14 : 18) } ``` 3. **测试方案**: - 使用`ohos-test`框架编写单元测试 - 多设备预览模式验证UI - 真机调试传感器集成 #### 六、延伸开发方向 1. 智能家居联动(通过`@ohos.distributedHardware`) 2. 健康数据接入(使用`@ohos.health`模块) 3. 语音交互集成(`@ohos.multimodalInput`) **学习资源**: - 官方文档:https://developer.harmonyos.com/cn/docs/documentation - 开源案例:Gitee HarmonyOS专区 - 开发者认证:华为开发者学堂HDG课程 通过以上步骤,您可以构建一个具有以下特点的起床仪表盘: - 实时动态数据展示 - 美观的视觉反馈 - 流畅的交互动效 - 跨设备协同能力 - 个性化定制扩展空间
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值