鸿蒙健身计划制定(动作视频指导/进度跟踪)
【摘要】 一、引言在健康生活理念日益普及的背景下,越来越多的人开始通过健身改善体质。然而,缺乏专业指导(如动作不规范导致受伤)和 难以坚持(如无进度反馈导致动力不足)是用户健身的两大痛点。传统健身APP虽提供视频教程,但存在跨设备协同差(如手机看教程、手表无提醒)、进度跟踪不直观(如手动记录训练数据)等问题。鸿蒙操作系统(HarmonyOS)凭借 分布式设备协同、多媒体能力...
一、引言
二、技术背景
1. 鸿蒙核心技术支撑
-
分布式设备协同(Distributed Device Collaboration):支持手机、平板、智能手表、智慧屏等设备间的无缝互联。例如,手机播放健身视频时,手表可同步显示当前动作的关键提示(如“保持核心收紧”),智慧屏可作为大屏播放器提供沉浸式体验。 -
多媒体能力(Media Kit):提供视频播放(支持MP4、AVI等格式)、音频解码、图像渲染等API(如 @ohos.multimedia.medialibrary
和@ohos.avplayer
),确保健身视频的高清流畅播放。 -
数据持久化与分布式数据库(Data Management):通过 @ohos.data.preferences
(轻量级键值存储)或@ohos.data.relationalstore
(关系型数据库)存储用户的健身计划、训练进度(如每日训练次数、完成度),并支持跨设备同步。 -
传感器与健康数据(Sensor & Health Kit):智能手表/手环的加速度传感器、心率传感器可实时监测用户运动状态(如动作幅度、心率变化),结合鸿蒙的 @ohos.sensors
和@ohos.health
API,为进度跟踪提供客观数据(如实际消耗卡路里)。 -
原子化服务(Atomic Service):健身计划功能可封装为独立的原子化服务卡片(如“今日训练”卡片),用户通过负一屏或桌面快捷入口快速查看当日计划、训练记录,无需打开完整APP。
2. 健身计划的核心需求
-
个性化计划制定:根据用户目标(如减脂、增肌)、体能水平(如初级、中级)生成定制化的训练方案(包含动作序列、组数、时长)。 -
动作视频指导:提供高清、分步骤的动作演示视频(如“深蹲标准动作”),支持暂停、倍速播放,并通过文字/语音提示关键要点(如“膝盖不超过脚尖”)。 -
进度可视化跟踪:记录每次训练的完成情况(如完成的组数、实际用时、主观感受),并通过图表(如折线图展示每周训练次数增长)直观反馈进步。 -
跨设备协同提醒:手机端制定计划后,手表端同步提醒训练时间(如“晚上7点,今日腿部训练”),训练中通过振动提醒动作节奏(如“每组间隔30秒”)。
三、应用使用场景
1. 日常家庭健身(手机+手表协同)
2. 健身房辅助训练(平板+智慧屏)
3. 长期健身管理(进度跟踪与激励)
四、不同场景下详细代码实现
场景1:基础功能(视频播放与进度记录)
1.1 核心代码实现(VideoTraining.ets)
// src/main/ets/pages/VideoTraining.ets
import mediaLibrary from '@ohos.multimedia.medialibrary';
import preferences from '@ohos.data.preferences';
import { BusinessError } from '@ohos.base';
@Entry
@Component
struct VideoTraining {
@State private videoUrl: string = ''; // 视频文件路径(如本地或网络URL)
@State private currentPlan: string = '肩部训练'; // 当前训练计划名称
@State private completedSets: number = 0; // 已完成的组数
@State private trainingDuration: number = 0; // 训练用时(秒)
@State private isPlaying: boolean = false; // 视频播放状态
private prefs: preferences.Preferences | null = null;
aboutToAppear() {
this.loadVideoAndInitProgress();
}
// 加载视频路径并初始化进度记录
private async loadVideoAndInitProgress() {
// 假设视频路径为本地资源(实际可从网络或数据库获取)
this.videoUrl = '/resources/videos/shoulder_training.mp4';
await this.initProgressStorage();
}
// 初始化分布式数据库(存储训练进度)
private async initProgressStorage() {
try {
this.prefs = await preferences.getPreferences(this.context, `training_progress_${this.currentPlan}`);
// 读取历史数据(如上次完成的组数)
const lastSets = await this.prefs.get('completedSets', '0');
this.completedSets = parseInt(lastSets) || 0;
} catch (error) {
const err = error as BusinessError;
console.error('初始化进度存储失败:', err.code, err.message);
this.completedSets = 0;
}
}
// 保存训练进度到分布式数据库
private async saveProgress() {
if (!this.prefs) return;
try {
await this.prefs.put('completedSets', this.completedSets.toString());
await this.prefs.put('lastDuration', this.trainingDuration.toString());
await this.prefs.flush(); // 同步到存储
console.info('训练进度已保存: 组数=${this.completedSets}, 用时=${this.trainingDuration}s');
} catch (error) {
const err = error as BusinessError;
console.error('保存进度失败:', err.code, err.message);
}
}
// 视频播放控制(模拟)
private toggleVideoPlay() {
this.isPlaying = !this.isPlaying;
if (this.isPlaying) {
this.startTimer(); // 开始计时
} else {
this.stopTimer(); // 停止计时
}
}
// 开始计时(模拟训练用时)
private timer: number | null = null;
private startTimer() {
this.timer = setInterval(() => {
this.trainingDuration += 1; // 每秒增加1秒
}, 1000);
}
// 停止计时
private stopTimer() {
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
}
// 增加完成的组数(用户点击“完成一组”按钮)
private addCompletedSet() {
this.completedSets += 1;
}
// 结束训练(保存数据并重置计时器)
private finishTraining() {
this.stopTimer();
this.saveProgress();
promptAction.showToast({ message: '本次训练已完成,数据已保存!' });
}
aboutToDisappear() {
this.stopTimer();
this.saveProgress(); // 确保退出时保存数据
}
build() {
Column() {
Text(`当前计划: ${this.currentPlan}`)
.fontSize(20)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 20 });
// 视频播放器(简化:实际使用avplayer组件)
Video() {
// 视频内容(实际需配置src为this.videoUrl)
}
.width('100%')
.height(200)
.controls(true)
.onClick(() => {
this.toggleVideoPlay();
});
// 训练进度显示
Column() {
Text(`已完成组数: ${this.completedSets}`)
.fontSize(16)
.margin({ bottom: 10 });
Text(`本次用时: ${Math.floor(this.trainingDuration / 60)}分${this.trainingDuration % 60}秒`)
.fontSize(16);
}
.margin({ bottom: 20 });
// 操作按钮
Row() {
Button('完成一组')
.onClick(() => {
this.addCompletedSet();
})
.margin({ right: 10 });
Button('结束训练')
.onClick(() => {
this.finishTraining();
});
}
.width('60%');
}
.width('100%')
.height('100%')
.padding(20);
}
}
1.2 原理解释(视频与进度跟踪)
-
视频播放:通过 Video
组件(或鸿蒙的@ohos.avplayer
API)播放本地/网络健身视频,支持用户控制播放/暂停(模拟逻辑)。 -
进度记录:用户每完成一组训练,点击“完成一组”按钮, completedSets
状态变量递增;训练过程中通过计时器(setInterval
)记录用时(trainingDuration
)。 -
数据持久化:使用 @ohos.data.preferences
将当前计划的训练进度(组数、用时)存储到本地键值数据库(键名为training_progress_肩部训练
),确保下次打开应用时数据不丢失。
场景2:跨设备协同(手机+手表提醒)
2.1 核心代码实现(DistributedReminder.ets)
// src/main/ets/pages/DistributedReminder.ets
import distributedData from '@ohos.data.distributedData';
import { BusinessError } from '@ohos.base';
@Entry
@Component
struct DistributedReminder {
@State private planName: string = '腿部训练'; // 当前训练计划
@State private startTime: string = '18:00'; // 计划开始时间
@State private isTraining: boolean = false; // 是否正在训练
private distributedPrefs: any = null;
aboutToAppear() {
this.syncPlanToWatch();
this.startTrainingTimer();
}
// 同步训练计划到分布式数据库(手表端可读取)
private async syncPlanToWatch() {
try {
this.distributedPrefs = await distributedData.getPreferences(this.context, 'EMR_TrainingPlan');
await this.distributedPrefs.put('currentPlan', this.planName);
await this.distributedPrefs.put('startTime', this.startTime);
await this.distributedPrefs.flush();
console.info('训练计划已同步到分布式数据库');
} catch (error) {
const err = error as BusinessError;
console.error('同步计划失败:', err.code, err.message);
}
}
// 模拟训练计时(实际可结合系统时间判断是否到达startTime)
private startTrainingTimer() {
// 简化:假设当前时间为18:00时自动开始训练(实际需用定时器检查系统时间)
setTimeout(() => {
if (this.checkIfTimeReached()) {
this.isTraining = true;
this.notifyWatchStartTraining();
}
}, 1000); // 1秒后模拟检查(实际需更精确的定时逻辑)
}
// 检查是否到达计划开始时间(简化逻辑)
private checkIfTimeReached(): boolean {
// 实际需解析startTime(如'18:00')并与当前系统时间比较
return true; // 假设时间已到
}
// 通知手表开始训练(通过分布式数据库写入标志)
private notifyWatchStartTraining() {
if (!this.distributedPrefs) return;
try {
this.distributedPrefs.put('isTrainingNow', 'true');
this.distributedPrefs.flush();
console.info('已通知手表开始训练');
} catch (error) {
const err = error as BusinessError;
console.error('通知手表失败:', err.code, err.message);
}
}
// 训练中振动提醒(模拟每组间隔30秒)
private remindDuringTraining() {
if (!this.isTraining) return;
setInterval(() => {
if (this.isTraining) {
// 实际项目中调用手表振动API(如@ohos.vibrator)
console.info('振动提醒:下一组准备!');
}
}, 30000); // 每30秒提醒一次
}
aboutToDisappear() {
this.isTraining = false;
}
build() {
Column() {
Text(`训练计划: ${this.planName}`)
.fontSize(20)
.fontWeight(FontWeight.Bold);
Text(`开始时间: ${this.startTime}`)
.fontSize(16)
.margin({ bottom: 20 });
Text(this.isTraining ? '🔥 正在训练中...' : '⏳ 等待开始')
.fontSize(18)
.fontColor(this.isTraining ? '#dc3545' : '#6c757d');
}
.width('100%')
.height('100%')
.padding(20);
}
}
2.2 原理解释(跨设备协同)
-
分布式数据同步:手机端通过 @ohos.data.distributedData
将当前训练计划(名称、开始时间)写入分布式数据库(键名为EMR_TrainingPlan
),手表端可实时读取该数据(通过相同的键名)。 -
训练状态通知:当手机端检测到当前时间到达计划开始时间(如18:00),通过分布式数据库写入 isTrainingNow=true
标志,手表端监听该标志变化后触发振动提醒(实际需调用@ohos.vibrator
API)。 -
训练中提醒:训练开始后,手机端通过定时器(如每30秒)模拟振动提醒(实际手表端实现振动逻辑),提示用户下一组动作准备。
五、原理解释
1. 鸿蒙健身计划的核心流程
-
计划制定与视频加载:用户选择健身目标(如减脂)和体能水平(如初级),应用生成定制化训练计划(包含动作序列、视频链接、组数/时长)。视频通过鸿蒙的 Media Kit
API(如@ohos.avplayer
)播放,支持高清流畅渲染。 -
动作指导与提示:视频播放时,关键动作节点(如“深蹲时膝盖不超过脚尖”)通过文字叠加或语音提示展示;手表端同步显示当前动作的简短提醒(如“保持核心收紧”)。 -
进度跟踪与存储:用户每完成一组训练,应用记录组数、用时、主观感受(如“轻松”“吃力”),并通过 Preferences
或RelationalStore
将数据持久化到本地或云端(分布式数据库)。 -
跨设备协同:手机端制定计划后,通过分布式软总线将计划信息(如开始时间、动作序列)同步至手表/智慧屏;训练中手表通过振动提醒动作节奏,智慧屏作为大屏播放器提供沉浸式体验。
2. 关键技术点
-
多媒体能力:鸿蒙的 @ohos.avplayer
支持多种视频格式(如MP4、AVI),提供播放控制(暂停、倍速)、音量调节等功能,确保健身视频的高清播放。 -
分布式设备协同:通过 @ohos.data.distributedData
实现手机、手表、智慧屏间的数据同步(如训练计划、进度),无需手动传输,提升用户体验。 -
传感器与健康数据:手表的加速度传感器可监测用户动作幅度(如深蹲时下肢运动轨迹),结合心率传感器数据(如训练时心率变化),为进度跟踪提供客观指标(如实际消耗卡路里)。 -
原子化服务:健身计划功能可封装为原子化服务卡片(如“今日训练”卡片),显示当日计划、剩余组数,用户通过负一屏快速查看和启动训练。
六、核心特性
|
|
---|---|
|
|
|
|
|
|
|
|
|
|
七、原理流程图及原理解释
原理流程图(健身计划完整流程)
+-----------------------+ +-----------------------+ +-----------------------+
| 用户选择健身计划 | | 视频播放与指导 | | 进度跟踪与存储 |
| (目标+体能水平) | ----> | (高清视频+提示) | ----> | (组数/用时记录) |
+-----------------------+ +-----------------------+ +-----------------------+
| | |
| 生成定制化方案 | 播放动作视频 | 写入分布式数据库 |
| (动作序列+视频) | (关键节点提示) | (训练数据持久化) |
|----------------------->|----------------------->| |
| | | 跨设备同步 |
| | | (手表/智慧屏接收) |
| | v |
| | +-----------------------+ |
| | | 手表振动提醒 | |
| | | (动作节奏提示) | |
| | +-----------------------+ |
v v v
+-----------------------+ +-----------------------+ +-----------------------+
| 用户开始训练 | | 训练中实时反馈 | | 可视化进度展示 |
| (跟随视频跟练) | | (传感器监测) | | (图表/成就徽章) |
+-----------------------+ +-----------------------+ +-----------------------+
原理解释
-
计划制定:用户输入健身目标(如减脂)和体能水平(如初级),应用根据内置算法生成包含动作序列(如深蹲、俯卧撑)、视频链接、组数/时长 的定制化训练计划。 -
视频指导:用户点击训练计划后,应用通过 @ohos.avplayer
播放对应高清视频,视频中关键动作节点(如“膝盖不超过脚尖”)通过文字叠加或语音提示展示;同时,手表端通过分布式数据库同步当前动作的简短提醒(如“保持核心收紧”)。 -
进度跟踪:用户每完成一组训练,应用更新 completedSets
和trainingDuration
状态变量,并通过@ohos.data.preferences
或@ohos.data.relationalstore
将数据持久化到本地或云端;手表端实时读取训练状态(如isTrainingNow
),通过振动提醒动作节奏。 -
跨设备协同:手机端通过分布式软总线将训练计划(如开始时间、动作序列)和进度(如已完成组数)同步至手表/智慧屏;智慧屏作为大屏播放器提供沉浸式视频体验,手表作为便携提醒设备确保用户不错过训练时间。
八、环境准备
1. 开发环境
-
操作系统:Windows 10/11、macOS 或 Linux。 -
开发工具:DevEco Studio(鸿蒙官方IDE,支持HarmonyOS应用开发)。 -
SDK与工具链:安装HarmonyOS SDK(版本 ≥ 3.2),包含多媒体( @ohos.multimedia.medialibrary
)、数据管理(@ohos.data.preferences
)、分布式能力(@ohos.data.distributedData
)、传感器(@ohos.sensors
)等模块。 -
设备:鸿蒙手机(如P系列、Mate系列)、智能手表(如Watch GT系列)、智慧屏(如鸿蒙TV),需开启开发者模式并配对调试。
2. 权限配置
-
多媒体权限:在 config.json
中声明ohos.permission.MEDIA_PLAYBACK
权限,用于视频播放。 -
分布式数据权限:声明 ohos.permission.DISTRIBUTED_DATASYNC
权限,确保跨设备数据同步合法。 -
传感器权限:若使用手表加速度/心率传感器,需声明 ohos.permission.SENSOR
和ohos.permission.HEALTH_DATA
权限。
九、实际详细应用代码示例实现
完整代码结构(基于场景1和场景2)
-
视频播放与进度跟踪( VideoTraining.ets
):实现健身视频播放、组数/用时记录、数据持久化到分布式数据库。 -
跨设备协同提醒( DistributedReminder.ets
):实现手机端同步训练计划至手表,手表端接收提醒并振动提示。 -
分布式数据库配置:通过 @ohos.data.preferences
或@ohos.data.relationalstore
管理训练计划和进度数据。
-
在DevEco Studio中创建鸿蒙应用项目,分别开发手机端(视频播放)和手表端(协同提醒)页面。 -
配置权限( config.json
)并确保设备开启开发者模式。 -
运行手机端应用(选择训练计划并播放视频),观察手表端是否同步提醒;训练结束后检查数据是否持久化。
十、运行结果
正常情况(视频播放与进度跟踪)
-
用户打开手机端应用,选择“肩部训练计划”,视频自动加载并播放;用户每完成一组训练,点击“完成一组”按钮,进度条更新(如“已完成3/4组”),训练用时实时显示(如“用时12分30秒”)。 -
训练结束后,数据自动保存至分布式数据库,下次打开应用时显示历史进度(如“上次肩部训练完成4组,用时15分钟”)。
跨设备协同(手机+手表)
-
手机端设置今日18:00开始“腿部训练”,手表端在18:00准时振动并显示“开始腿部训练”;训练中每30秒振动一次,提示“下一组准备”。
十一、测试步骤及详细代码
测试场景1:视频播放与进度记录
-
步骤: -
启动手机端应用,选择任意训练计划,点击播放视频。 -
模拟完成3组训练(点击“完成一组”按钮3次),观察进度显示(如“已完成3/4组”)和用时更新。 -
退出应用后重新打开,检查历史进度是否保留。
-
-
预期结果: -
视频播放流畅,进度数据(组数、用时)正确记录并持久化。
-
测试场景2:跨设备协同提醒
-
步骤: -
在手机端设置训练计划开始时间为当前时间+1分钟(模拟),观察手表端是否在1分钟后振动并显示计划名称。 -
训练中观察手表是否每30秒振动一次(模拟动作节奏提醒)。
-
-
预期结果: -
手表端准时接收训练开始提醒,训练中按时振动提示。
-
十二、部署场景
1. 手机端发布
-
应用商店上架:将健身计划应用打包为鸿蒙APP(.hap文件),提交至华为应用市场,用户通过手机下载安装。 -
独立安装:开发者可通过DevEco Studio生成调试版APP,直接安装到测试手机(需开启“允许安装未知来源应用”)。
2. 手表端协同
-
分布式配对:手机端与智能手表通过蓝牙/Wi-Fi配对,确保分布式软总线连通(可在手机的“设置→鸿蒙→设备管理”中查看配对状态)。 -
手表应用安装:手表端应用通过分布式能力自动同步(或手动安装调试版),与手机端实时协同。
3. 智慧屏扩展
-
投屏播放:用户将手机端的健身视频投屏至智慧屏(通过鸿蒙的“多屏协同”功能),享受大屏沉浸式训练体验。
十三、疑难解答
问题1:视频无法播放
/resources/videos/
目录)、格式不支持(如FLV格式)。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)