Location>code7788 >text

HarmonyOS motion development: How to monitor user motion step data

Popularity:372 ℃/2025-04-29 09:16:12

Preface

When developing motion applications, accurately monitoring and recording the number of motion steps of users is a key feature. HarmonyOS provides a powerful sensor framework that allows developers to easily obtain device motion data. This article will explore in-depth how to implement step monitoring function in HarmonyOS applications, and share some experiences and techniques from the development process to help you better understand and implement this function.

1. Understand the HarmonyOS sensor framework

HarmonyOS provides a variety of sensors, among whichPEDOMETER(Peobacter) sensor is the core sensor used to obtain the number of user's movement steps. This sensor returns the cumulative number of steps since the device is started, not the incremental number of steps. This means we need to process the initial value and incremental calculation of the number of steps in the application logic.

2. Core code implementation

2.1 Initialize the sensor

Before we start, we need to request the necessary permissions and initialize the sensor. Here is the code to initialize the sensor:

import { sensor } from '@';
 import { BusinessError } from '@';
 import abilityAccessCtrl from '@';
 import { common } from '@';

 export class StepCounterService {
   private static instance: StepCounterService;
   private stepCount: number = 0; // Current cumulative number of steps
   private initialStepCount: number = 0; // Initial number of steps (cumulative number of steps after device startup)
   private isMonitoring: boolean = false; // Whether it is being monitored
   private isPaused: boolean = false; // Whether to pause
   private listeners: Array<(steps: number) => void> = [];
   private context: ;
   private pausedIntervals: Array<PauseCounter> = [];
   private deviceTotalSteps: number = 0;

   private constructor(context: ) {
      = context;
   }

   public static getInstance(context: ): StepCounterService {
     if (!) {
        = new StepCounterService(context);
     }
     return ;
   }

   private async requestMotionPermission(): Promise<boolean> {
     const atManager = ();
     try {
       const result = await (
         ,
         ['.ACTIVITY_MOTION']
       );
       return [0] === '.ACTIVITY_MOTION' &&
         [0] === 0;
     } catch (err) {
       ('Application permission failed:', err);
       return false;
     }
   }

   public async startStepCounter(): Promise<void> {
     if () return;

     const hasPermission = await ();
     if (!hasPermission) {
       throw new Error('Motion sensor permission is not granted');
     }

     try {
       (, (data: ) => {
          = ;

         if ( === 0) {
            = ;
         }

         const deltaSteps = - ;

         if () {
           // When paused, only the total number of equipment steps will be updated, and no changes to the number of business steps will be changed.
         } else {
           // Calculate the total number of steps in all pause intervals
           const totalPausedSteps = ((sum, interval) => {
             return sum + ( - );
           }, 0);

            = deltaSteps - totalPausedSteps;
           ();
         }
       });

        = true;
     } catch (error) {
       const e = error as BusinessError;
       (`Pedometer subscription failed: Code=${}, Message=${}`);
       throw error as Error;
     }
   }
 }

2.2 Pause and Recovery Functions

During exercise, the user may need to pause and resume the exercise. To handle this, we need to record the number of steps during pause and recovery, and calculate the increment of steps during pause during recovery. The following are implementations of the pause and recovery function:

public pauseStepCounter(): void {
  if (! || ) return;
  ({
    start: ,
    end: 0
  });
   = true;
}

public resumeStepCounter(): void {
  if (! || !) return;

  const lastInterval = [ - 1];
   = ;

   = false;
}

2.3 Stop monitoring

When the user completes the movement, we need to stop listening to the steps and clean up the relevant resources:

public stopStepCounter(): void {
   if (!) return;

    = 0;
    = 0;
    = false;
    = []; // Clear all pause records
   try {
     ();
      = false;
   } catch (error) {
     const e = error as BusinessError;
     (`Pedometer unsubscribe failed: Code=${}, Message=${}`);
   }
 }

3. Notify the listener

To ensure that the interface can update the steps in real time, we need to notify the listener when the steps change. To avoid excessively frequent notifications, you can use the anti-shake mechanism:

private debounceTimer?: number;

 private notifyListeners(): void {
   if () clearTimeout();
    = setTimeout(() => {
     (listener => listener());
   }, 500); // Notify every 500ms
 }

4. Reset steps

In some cases, the user may need to reset the number of steps. Here is the implementation of resetting the number of steps:

public resetStepCounter(): void {
   = ;
   = [];
   = 0;
}

5. Use examples

Here is how to use it in the pageStepCounterServiceExample:

@Component
 export struct KeepRunningPage {
   @State isRunning: boolean = false;
   @State stepCount: number = 0;

   private stepCounterService?: StepCounterService;

   build() {
     Column() {
       Text('Running pedometer')
         .fontSize(24)
         .textAlign()
         .margin({ top: 20 })

       Text(`steps: ${}`)
         .fontSize(18)
         .textAlign()
         .margin({ top: 20 })

       Button('Start Run')
         .onClick(() => ())
         .margin({ top: 20 })

       Button('Suspend the running')
         .onClick(() => ())
         .margin({ top: 20 })

       Button('Resume Running')
         .onClick(() => ())
         .margin({ top: 20 })

       Button('Stop running')
         .onClick(() => ())
         .margin({ top: 20 })
     }
     .width('100%')
     .height('100%')
     .justifyContent()
     .alignItems()
   }

   aboutToAppear(): void {
      = (().uiAbilityContext);
     ((steps) => {
        = steps;
     });
   }

   aboutToDisappear(): void {
     !.removeStepListener((steps) => {
        = steps;
     });
   }

   async startRunning(): Promise<void> {
     if (!) {
        = true;
       await !.startStepCounter();
     }
   }

   pauseRunning(): void {
     if () {
       !.pauseStepCounter();
     }
   }

   resumeRunning(): void {
     if () {
       !.resumeStepCounter();
     }
   }

   stopRunning(): void {
     if () {
        = false;
       !.stopStepCounter();
     }
   }
 }

6. Core point sorting

6.1 Authorization application

Before using the sensor, you must apply.ACTIVITY_MOTIONPermissions. This can be doneTo achieve it.

6.2 Initial step processing

PEDOMETERThe sensor returns the cumulative number of steps since the device is started. Therefore, we need to record the initial steps when the data is first fetched

6.3 Pause and recovery mechanism

To handle possible pauses and recovery operations for users, we introducedpausedIntervalsArray to record the number of start and end steps for each pause. In this way, we can accurately calculate the increment of the step during the pause during recovery and deduct this part of the step from the total number of steps.

6.4 Anti-shake mechanism

To avoid performance problems caused by frequent notification of listeners, wenotifyListenersThe anti-shake mechanism is added to the method. By setting a timer, ensure that the listener is notified only once within a certain time interval (such as 500ms), thereby reducing unnecessary updates.

6.5 Reset function

In some scenarios, the user may need to reset the step counter. passresetStepCounterMethod, we can set the initial step count to the total step count of the current device and clear all pause records to achieve a reset of the step count.

7. Things to note during development

7.1 Permission Management

In practical applications, permission application is a link that cannot be ignored. If the user refuses permission application, the application should prompt the user friendly and provide the option to reapply permission.

7.2 Resource Management

Sensor monitoring is an ongoing process that, if not managed correctly, may lead to resource leakage. Therefore, when listening is not required, be sure to callMethod to cancel listening.

7.3 Data Accuracy

becausePEDOMETERThe sensor returns the cumulative number of steps, so when processing pauses and recovery, special attention should be paid to the accuracy of the data. Ensure that step increments are correctly recorded and calculated during pause and recovery to avoid data bias.

8. Summary

We have discussed in detail how to implement step monitoring in HarmonyOS applications. From initialization and permission application of sensors to implementations of pause, recovery and stop listening. I hope these contents can help you become more handy when developing sports applications.