This content originally appeared on DEV Community and was authored by linzhongxue
Developing Fitness and Health Applications Based on HarmonyOS Next: From Sensors to Cloud Sync
This hands-on guide will walk you through building core modules of a "HealthTracker" fitness app, covering motion data collection, local storage, cross-device sync, cloud backup, and dynamic card display using ArkTS and AppGallery Connect (AGC) services.
1. Project Initialization and Permission Configuration
1.1 Project Setup & Dependencies
Create a "HealthTracker" project in DevEco Studio (Type: Application, Model: Stage). Add health service and distributed data dependencies in oh-package.json5
:
"dependencies": {
"@ohos.sensor": "2.0", // Sensor service
"@ohos.distributedData": "1.0", // Distributed data
"@agconnect/database": "1.0" // AGC cloud database
}
1.2 Permission Declaration
Declare permissions in module.json5
:
"requestPermissions": [
{
"name": "ohos.permission.HEALTH_DATA" // Health data access
},
{
"name": "ohos.permission.DISTRIBUTED_DATASYNC" // Cross-device sync
},
{
"name": "ohos.permission.ACTIVITY_MOTION" // Motion recognition
}
]
2. Core Function Implementation
2.1 Real-time Step Counting
Create StepCounterService.ets
for step monitoring:
import sensor from '@ohos.sensor';
// Step counter service
export class StepCounterService {
private sensorId: number | null = null;
private stepCount: number = 0;
// Start step monitoring
startStepCounter(callback: (step: number) => void): void {
try {
// Get pedometer sensor
const sensorType = sensor.SensorType.SENSOR_TYPE_PEDOMETER;
this.sensorId = sensor.on(sensorType, (data) => {
this.stepCount = data.steps;
callback(this.stepCount); // Real-time callback
});
console.info('Step counter activated');
} catch (error) {
console.error(`Activation failed: ${error.code}, ${error.message}`);
}
}
// Stop monitoring
stopStepCounter(): void {
this.sensorId && sensor.off(this.sensorId);
}
}
2.2 Heart Rate Monitoring (Hardware-dependent)
In HeartRateMonitor.ets
:
import sensor from '@ohos.sensor';
export class HeartRateMonitor {
private sensorId: number | null = null;
// Start heart rate monitoring
startMonitoring(callback: (bpm: number) => void): void {
try {
const sensorType = sensor.SensorType.SENSOR_TYPE_HEART_RATE;
this.sensorId = sensor.on(sensorType, (data) => {
if (data.heartRate > 0) callback(data.heartRate);
});
} catch (error) {
console.error(`Monitoring error: ${error.message}`);
}
}
// Stop monitoring
stopMonitoring(): void {
this.sensorId && sensor.off(this.sensorId);
}
}
3. Data Storage and Synchronization
3.1 Local Device Storage
Store daily fitness data using distributed objects:
import distributedData from '@ohos.distributedData';
// Create distributed data object
const context = getContext(this) as common.UIAbilityContext;
let kvManager = distributedData.createKVManager({
context,
bundleName: 'com.example.healthtracker'
});
// Health data structure
interface HealthData {
steps: number;
heartRate?: number;
lastUpdate: string;
}
// Save data locally
async function saveLocalData(data: HealthData): Promise<void> {
const key = `health_${new Date().toLocaleDateString()}`;
const kvStore = await kvManager.getKVStore('healthStore');
await kvStore.put(key, JSON.stringify(data));
}
3.2 Cross-Device Sync
Synchronize data across devices:
// Sync data to other devices
async function syncDataAcrossDevices(): Promise<void> {
const allDevices = distributedData.getAvailableDevicesInfo();
const deviceIds = allDevices.map(device => device.deviceId);
if (deviceIds.length > 0) {
const kvStore = await kvManager.getKVStore('healthStore');
await kvStore.sync(deviceIds, distributedData.SyncMode.PUSH_PULL);
}
}
3.3 Cloud Backup (AGC CloudDB)
Persist data using AppGallery Connect:
import cloudDB from '@agconnect/database';
// Initialize cloud database
const agcCloudDB = cloudDB.initialize({
zoneName: "HealthDataZone", // Data zone
persistenceEnabled: true // Enable persistence
});
// Define cloud data object
@cloudDB.object()
class CloudHealthData {
userId: string = ''; // AGC user ID
date: string = ''; // Date
steps: number = 0; // Steps
avgHeartRate: number = 0; // Avg heart rate
}
// Upload to cloud
async function uploadToCloud(data: HealthData): Promise<void> {
const cloudObject = new CloudHealthData();
cloudObject.userId = getUserId(); // Get logged-in user
cloudObject.date = new Date().toISOString().split('T')[0];
cloudObject.steps = data.steps;
const store = await agcCloudDB.getCloudDBZone();
await store.upsert(cloudObject); // Insert/update
}
4. Dynamic Card Display
4.1 Card UI Layout (StepCard.ets
)
// Step display card
@Component
export struct StepCard {
@LocalStorageProp('currentSteps') steps: number = 0;
build() {
Column() {
Text("Today's Steps")
.fontSize(16)
.fontColor(Color.Gray)
Text(`${this.steps}`)
.fontSize(36)
.margin({ top: 8 })
Progress({ value: this.steps, total: 10000 }) // 10k goal
.height(10)
.margin({ top: 15 })
}
.padding(20)
}
}
4.2 Real-time Card Updates
In card provider FormAbility.ts
:
import formBindingData from '@ohos.app.form.formBindingData';
// Update card data
onUpdateForm(formId: string): void {
let stepData = { 'currentSteps': 6850 }; // Get live data
let formData = formBindingData.createFormBindingData(stepData);
formProvider.updateForm(formId, formData)
.catch(err => console.error('Update failed: ' + err));
}
5. Troubleshooting Guide
-
Sensor Best Practices
- Request
ohos.permission.KEEP_BACKGROUND_RUNNING
for background ops - Wrap sensor operations in
try/catch
blocks
- Request
Sync Optimization
// Low-power sync strategy:
const options = {
syncMode: distributedData.SYNC_MODE_LOW_POWER,
delay: 500 // Batch sync every 500ms
};
kvStore.sync(deviceIds, distributedData.SyncMode.PUSH, options);
- Cloud Security Configure data access rules in AGC console:
{
"read": "auth != null", // Authenticated users only
"write": "auth.uid == userId" // Data owner only
}
6. Complete Example: Fitness Dashboard
// HealthDashboard.ets
import { StepCounterService } from './StepCounterService';
@Entry
@Component
struct HealthDashboard {
@State steps: number = 0;
private stepService: StepCounterService = new StepCounterService();
aboutToAppear() {
this.stepService.startStepCounter((step) => {
this.steps = step;
// Sync every 10 minutes
if (step % 10 === 0) {
saveLocalData({ steps, lastUpdate: new Date().toISOString() });
uploadToCloud({ steps });
}
});
}
build() {
Column() {
// Step progress ring
Progress({
value: this.steps,
total: 10000,
type: ProgressType.Ring
}).width(200)
// Sync button
Button("Sync to Watch")
.onClick(() => syncDataAcrossDevices())
}
}
}
Conclusion
You've now mastered core HarmonyOS fitness app development:
- Hardware sensor data acquisition
- Distributed data flow
- Cloud persistence solutions
- Real-time card visualization
Leveraging HarmonyOS Next's distributed architecture and AGC's backend capabilities, developers can seamlessly create consistent cross-device fitness experiences. Always test sensor features on real devices and configure detailed data security policies in the AGC console.
This content originally appeared on DEV Community and was authored by linzhongxue

linzhongxue | Sciencx (2025-06-11T03:34:48+00:00) Developing Fitness and Health Applications Based on HarmonyOS Next: From Sensors to Cloud Sync. Retrieved from https://www.scien.cx/2025/06/11/developing-fitness-and-health-applications-based-on-harmonyos-next-from-sensors-to-cloud-sync/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.