基于HarmonyOS Next的运动健康应用开发实战:从健康数据到云端同步

在万物互联的时代,运动健康应用正成为人们管理自身健康的重要伙伴。HarmonyOS Next以其强大的分布式能力、流畅的性能和丰富的应用服务接口,为开发者打造智能、互联的健康应用提供了绝佳平台。本文将深入探讨如何利用HarmonyOS SDK应用服务(特别是Health Kit、AppGallery Connect的云数据库与云函数)构建一个功能完整的运动健康类应用。

一、 应用核心功能规划

我们将开发一个名为“Harmony健康助手”的应用,核心功能包括:

  1. 步数监测与展示:实时读取设备步数并展示。
  2. 健康数据同步:将用户步数数据安全存储至云端(AppGallery Connect)。
  3. 目标设定与提醒:允许用户设置每日步数目标,并在达成时发送本地通知。
  4. 设备联动(可选):发现附近支持的运动设备(如手环),并展示其状态。

二、 开发环境与前置准备

  1. 安装配置开发工具:确保已安装最新版本的DevEco Studio并完成HarmonyOS SDK的基础配置。
  2. 创建HarmonyOS项目:在DevEco Studio中创建一个新项目,选择"Application" -> “Empty Ability”,模板语言选择ArkTS。
  3. 启用AppGallery Connect服务
    • 在AppGallery Connect控制台创建项目和应用(确保包名与本地项目一致)。
    • 在项目中启用 Cloud DB (云数据库) 和 Cloud Functions (云函数) 服务。按照官方指引完成SDK集成和agconnect-services.json配置文件的下载与放置。
  4. 申请Health Kit权限
    • 在项目module.json5文件中声明所需权限:
      "requestPermissions": [
        {
          "name": "ohos.permission.health.READ_HEALTH_DATA" // 读取健康数据
        },
        {
          "name": "ohos.permission.health.WRITE_HEALTH_DATA" // 写入健康数据(如需要)
        },
        {
          "name": "ohos.permission.NOTIFICATION" // 发送本地通知
        },
        {
          "name": "ohos.permission.DISTRIBUTED_DATASYNC" // 跨设备数据同步(如需要联动设备)
        }
      ]
      
    • 在应用首次使用相关功能时,需动态向用户申请这些权限。

三、 核心功能实现详解 (ArkTS代码)

1. 读取并展示实时步数 (使用Health Kit)

// 导入必要的模块
import health from '@ohos.health';
import common from '@ohos.app.ability.common';
import { BusinessError } from '@ohos.base';

@Component
export struct StepCounterDisplay {
  // 状态变量:当前步数
  @State currentSteps: number = 0;
  // 状态变量:用户设定的目标步数
  @State dailyGoal: number = 10000;
  // 获取Ability上下文,用于权限申请等
  private context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;

  aboutToAppear() {
    // 应用启动时申请健康数据读取权限(实际开发中需检查是否已授权)
    // ... (权限申请逻辑省略,参考ohos.abilityAccessCtrl文档)
    // 开始监听步数变化
    this.startStepCounter();
  }

  // 启动步数计数器
  private startStepCounter() {
    try {
      // 1. 创建健康数据查询选项
      const options: health.HealthDataOptions = {
        startTime: new Date(new Date().setHours(0, 0, 0, 0)), // 今日0点
        endTime: new Date(), // 当前时间
        dataType: health.HealthDataType.STEP_COUNT, // 数据类型:步数
        timeUnit: health.TimeUnit.MILLISECONDS // 时间单位
      };

      // 2. 获取Health Kit Helper实例
      const healthHelper = health.createHealthHelper(this.context);

      // 3. 查询指定时间段内的步数总和
      healthHelper.getSum(options).then((result: health.HealthData) => {
        console.info(`[Harmony健康助手] 获取步数成功: ${result.value}`);
        this.currentSteps = result.value; // 更新UI显示
      }).catch((err: BusinessError) => {
        console.error(`[Harmony健康助手] 获取步数失败: ${err.code}, ${err.message}`);
      });

      // 4. (可选) 注册监听器,实时获取步数变化 (更耗电)
      healthHelper.on(health.HealthType.STEP_COUNT, (data: health.HealthData) => {
        console.info(`[Harmony健康助手] 步数变化: ${data.value}`);
        this.currentSteps = data.value; // 实时更新UI
        // 检查是否达到目标
        if (this.currentSteps >= this.dailyGoal) {
          this.sendGoalAchievedNotification();
        }
      });
    } catch (error) {
      const err: BusinessError = error as BusinessError;
      console.error(`[Harmony健康助手] 启动步数计数器异常: ${err.code}, ${err.message}`);
    }
  }

  // 发送目标达成通知
  private sendGoalAchievedNotification() {
    // 使用@ohos.notificationManager发送本地通知
    // ... (通知发送逻辑省略,参考notificationManager文档)
    console.info(`[Harmony健康助手] 恭喜!您已完成今日步数目标:${this.dailyGoal}步!`);
  }

  build() {
    Column() {
      // 展示当前步数
      Text(`今日步数: ${this.currentSteps}`)
        .fontSize(30)
        .margin(20)
      // 展示目标步数(可编辑)
      TextInput({ placeholder: '输入目标步数', text: this.dailyGoal.toString() })
        .onChange((value: string) => {
          this.dailyGoal = parseInt(value) || 10000; // 更新目标值
        })
        .width('80%')
        .margin(10)
      Button('保存目标')
        .onClick(() => {
          // 这里可以添加将目标保存到本地或云端的逻辑
          console.info(`[Harmony健康助手] 目标已更新为: ${this.dailyGoal}`);
        })
        .margin(10)
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

2. 同步步数数据到云端 (使用AppGallery Connect Cloud DB)

步骤 1:定义云数据库对象类型 (Object Type)
在AppGallery Connect控制台的Cloud DB区域,创建一个名为StepRecord的对象类型,包含字段:

  • id (String, 主键)
  • userId (String, 用户标识,建议使用AGC Auth的用户UID)
  • date (String, 日期,格式如’YYYY-MM-DD’)
  • steps (Integer, 步数)
  • deviceId (String, 记录来源的设备ID)

步骤 2:在应用中初始化Cloud DB

// 导入Cloud DB模块
import cloud from '@hw-agconnect/cloud';
import '@hw-agconnect/instance';

// 在应用入口或合适的地方初始化AGC
// 通常在Ability的onCreate中
// import agconnect from '@hw-agconnect/core';
// agconnect.instance().init(context);

// 定义StepRecord类对应云数据库对象
export class StepRecord {
  id?: string; // Cloud DB自动生成主键
  userId?: string;
  date?: string;
  steps?: number;
  deviceId?: string;

  // 构造函数
  constructor(userId: string, date: string, steps: number, deviceId: string) {
    this.userId = userId;
    this.date = date;
    this.steps = steps;
    this.deviceId = deviceId;
  }
}

// 获取Cloud DB区域和Zone
const cloudDBZone = cloud.CloudDBZoneConfig.getCloudDBZoneConfig('your_clouddb_zone_name'); // 替换为你的Zone名

步骤 3:将当日步数上传到Cloud DB

// 假设在StepCounterDisplay组件中有一个同步按钮
Button('同步到云端')
  .onClick(async () => {
    try {
      // 1. 获取当前用户ID (需要集成AGC Auth,此处简化)
      const currentUser = 'user123'; // 实际应从AGC Auth获取

      // 2. 获取当前日期
      const today = new Date().toISOString().split('T')[0]; // 'YYYY-MM-DD'

      // 3. 创建要上传的记录对象
      const recordToUpload = new StepRecord(
        currentUser,
        today,
        this.currentSteps,
        'HarmonyPhone' // 设备标识,可获取真实设备ID
      );

      // 4. 获取CloudDBZone实例
      const cloudDBZone = await cloud.CloudDBZone.open(cloudDBZone);

      // 5. 执行插入操作
      const result = await cloudDBZone.executeUpsert([recordToUpload]);
      console.info(`[Harmony健康助手] 步数记录同步成功! 影响记录数: ${result}`);
      // 可以在这里给用户一个成功提示
    } catch (error) {
      const err: BusinessError = error as BusinessError;
      console.error(`[Harmony健康助手] 同步失败: ${err.code}, ${err.message}`);
      // 处理错误,提示用户
    }
  })

步骤 4:从云端查询历史步数数据

// 在另一个页面或组件中查询历史数据
async function queryHistorySteps(userId: string) {
  try {
    const cloudDBZone = await cloud.CloudDBZone.open(cloudDBZone);

    // 1. 构建查询条件:查询特定用户的所有记录,按日期倒序
    const query = cloud.CloudDBZoneQuery.where(StepRecord)
      .equalTo('userId', userId)
      .orderByDesc('date');

    // 2. 执行查询
    const queryResult = await cloudDBZone.executeQuery(query, cloud.CloudDBZoneQueryPolicy.POLICY_QUERY_FROM_CLOUD_ONLY);

    // 3. 处理查询结果
    const records: StepRecord[] = [];
    if (queryResult && queryResult.getSnapshotObjects) {
      const snapshot = queryResult.getSnapshotObjects();
      for (let i = 0; i < snapshot.size(); i++) {
        records.push(snapshot.get(i)); // 将结果放入数组
      }
    }
    console.info(`[Harmony健康助手] 查询到${records.length}条历史记录`);
    return records; // 返回记录数组用于UI展示(折线图、列表等)
  } catch (error) {
    const err: BusinessError = error as BusinessError;
    console.error(`[Harmony健康助手] 查询历史记录失败: ${err.code}, ${err.message}`);
    return []; // 返回空数组
  }
}

3. 设备联动:发现并展示附近运动设备 (使用DeviceManager)

// 导入分布式设备管理模块
import deviceManager from '@ohos.distributedDeviceManager';

@Entry
@Component
struct NearbyDevicesPage {
  @State discoveredDevices: Array<deviceManager.DeviceBasicInfo> = []; // 存储发现的设备

  // 开始扫描附近设备
  startDiscovery() {
    try {
      // 1. 获取设备管理器实例
      const dmInstance = deviceManager.createDeviceManager('com.example.healthapp');

      // 2. 订阅设备状态变化(发现、离线)
      dmInstance.on('deviceStateChange', (data: { action: number, device: deviceManager.DeviceBasicInfo }) => {
        if (data.action === deviceManager.DeviceStateChangeAction.ONLINE) {
          // 新设备上线,添加到列表(去重)
          if (!this.discoveredDevices.some(dev => dev.deviceId === data.device.deviceId)) {
            this.discoveredDevices = [...this.discoveredDevices, data.device];
          }
        } else if (data.action === deviceManager.DeviceStateChangeAction.OFFLINE) {
          // 设备离线,从列表中移除
          this.discoveredDevices = this.discoveredDevices.filter(dev => dev.deviceId !== data.device.deviceId);
        }
      });

      // 3. 开始发现设备 (指定设备类型,如智能手环)
      const discoverParams: deviceManager.DiscoverParam = {
        mode: deviceManager.DiscoverMode.DISCOVER_MODE_ACTIVE,
        filter: {
          deviceType: [deviceManager.DeviceType.WEARABLE] // 关注可穿戴设备
        }
      };
      dmInstance.startDeviceDiscovery(discoverParams);
      console.info('[Harmony健康助手] 开始扫描附近设备...');

      // 4. 设置超时停止扫描(例如10秒后)
      setTimeout(() => {
        dmInstance.stopDeviceDiscovery();
        console.info('[Harmony健康助手] 设备扫描停止');
      }, 10000);
    } catch (error) {
      const err: BusinessError = error as BusinessError;
      console.error(`[Harmony健康助手] 设备扫描失败: ${err.code}, ${err.message}`);
    }
  }

  build() {
    Column() {
      Button('扫描附近运动设备')
        .onClick(() => this.startDiscovery())
        .margin(20)

      // 列表展示发现的设备
      List({ space: 10 }) {
        ForEach(this.discoveredDevices, (device: deviceManager.DeviceBasicInfo) => {
          ListItem() {
            Text(`${device.deviceName} (${device.deviceId})`)
              .fontSize(18)
              .padding(10)
          }
        }, (device) => device.deviceId) // 使用deviceId作为唯一键
      }
      .width('100%')
      .layoutWeight(1)
    }
  }
}

四、 进阶功能与优化考虑

  1. 数据可视化:利用<Canvas>组件或第三方图表库绘制步数趋势折线图、柱状图。
  2. 目标达成云函数触发:使用AppGallery Connect Cloud Functions,在Cloud DB中StepRecord表的数据插入/更新时触发云函数。云函数判断是否达到目标,如果达到,可以向用户的设备推送一条Push Notification(需集成Push Kit),即使应用不在前台也能收到祝贺。
  3. 多设备数据聚合:利用HarmonyOS的分布式数据管理,将从手机、手表等多个设备读取的步数在本地进行汇总,再将汇总结果同步到云端。
  4. 健康数据分析:利用AppGallery Connect的Serverless 数据分析服务对累积的步数数据进行分析,为用户提供周报、月报和个性化建议。
  5. 性能与功耗优化
    • 合理设置Health Kit监听器的频率。
    • 批量上传数据而非单条频繁上传。
    • 在设备联动时,按需扫描,及时停止。
  6. 隐私与安全
    • 清晰告知用户健康数据的使用目的,获取明确授权。
    • 使用HTTPS传输数据。
    • 利用Cloud DB的细粒度权限控制保护用户数据。
    • 在本地设备上存储敏感信息(如用户ID)时进行加密处理。

五、 总结

通过结合HarmonyOS Next强大的本地能力(如Health Kit、DeviceManager)与AppGallery Connect便捷的云服务(Cloud DB、Cloud Functions、Auth、Push等),开发者能够高效构建功能丰富、体验流畅、安全可靠的智能运动健康应用。本文提供的ArkTS代码示例和关键步骤解析,为开发此类应用奠定了坚实的基础。开发者可以在此基础上,充分发挥HarmonyOS分布式架构的优势,探索更多创新性的健康管理场景,为用户带来更智能、更贴心的健康生活体验。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐