Android Pedometer-API

android

#1

I need to create an app to show how many meters the user walked, but just accessing to the internal Android Pedometer API.

Have somebody used Pedometer-API in Android?


#2

I understand this would be needed.
https://plugins.nativescript.rocks/plugin/nativescript-health-data

Somebody used it ?


#3

I use the HealthData plugin for that purpose in an app to query historic data.

There’s also https://github.com/EddyVerbruggen/nativescript-pedometer which is for ‘live’ data.


#4

Thank you, what I need is to get historical data, not to track data with the app, I guess the HealthData plugin would work.

I would like to see your app running? Would you share the app link?


#5

If you have access to the Dutch appstore you can :slight_smile:, but you’d also need a login which I’m not allowed to give you.

But I can share the code with you I guess. This is the class responsible for anything related to the health plugin (and uploading the data to our backend):

import { Injectable } from "@angular/core";
import { Http } from "@angular/http";

import * as nsApp from "application";
import { LogService } from "../../../app/modules/core/services/logging/log.service";
import { StorageService } from "../../../app/modules/core/services/storage.service";
import { IHealthData } from "../../../app/modules/core/interfaces/ihealthdata";
import { HealthData, HealthDataType } from "nativescript-health-data";
import { BaseRequestService } from "../../../app/modules/sample/services/base-request.service";
import { RouterExtensions } from "../../../app/modules/core/services";
import { StorageKey } from "../../../app/modules/core/interfaces/istorage";
import { getTimeAtStartOfDay } from "../../../app/utils/date-util";
import { isIOS } from "tns-core-modules/platform";
import { formatDateYYYYMMDD } from "../../../app/modules/core/utils/date-util";
import { TranslateService } from "@ngx-translate/core";

@Injectable()
export class HealthDataNativeService extends BaseRequestService<void> implements IHealthData {

  private static HealthDataTypes: Array<HealthDataType> = [{name: "steps", accessType: "read"}];

  private healthData: HealthData;

  constructor(protected storage: StorageService,
              protected log: LogService,
              protected routerExtensions: RouterExtensions,
              protected http: Http,
              private translateService: TranslateService) {
    super(storage, log, routerExtensions, http);
    this.healthData = new HealthData();
    this.wireSyncOnResume();
  }

  isDeviceConfigured(): boolean {
    return this.storage.getItem(StorageKey.HEALTHDATA_CONFIGURED, false);
  }

  isAvailable(autoUpdatePlayServices = false): Promise<boolean> {
    return this.healthData.isAvailable(autoUpdatePlayServices);
  }

  requestAuthorization(): Promise<boolean> {
    return this.healthData.requestAuthorization(HealthDataNativeService.HealthDataTypes);
  }

  markDeviceAsAuthorized(): void {
    this.storage.setItem(StorageKey.HEALTHDATA_CONFIGURED, true);
    // let's sync as well
    this.wireSyncOnResume();
    // Android will already fire a resume event because of the consent dialog
    if (isIOS) {
      this.sync();
    }
  }

  /**
   * Sync all data since last sync (if not set, just sync today)
   */
  private async sync(): Promise<void> {
    if (this.isDeviceConfigured() && await this.isAvailable()) {
      const now = new Date();
      this.healthData.query({
        dataType: "steps",
        unit: "count",
        startDate: getTimeAtStartOfDay(new Date(this.storage.getItem(StorageKey.HEALTHDATA_SYNCED_UNTIL, now.getTime(), false))),
        endDate: new Date(),
        aggregateBy: "sourceAndDay"
      }).then(result => {
        const provider = this.translateService.instant(isIOS ? "EXERCISE_CONNECTDEVICES.TITLE_APPLEHEALTH" : "EXERCISE_CONNECTDEVICES.TITLE_GOOGLEFIT");
        const promises: Array<Promise<void>> = [];
        result.forEach(responseItem => {
          console.log(">>>> saving " + responseItem.source + " = " + responseItem.value);
          promises.push(this.save(
            provider,
            responseItem.source,
            formatDateYYYYMMDD(responseItem.end),
            responseItem.value
          ));
        });
        Promise.all(promises).then(() => {
          this.storage.setItem(StorageKey.HEALTHDATA_SYNCED_UNTIL, now.getTime(), false);
        });
      }).catch(err => console.log(err));
    }
  }

  private wireSyncOnResume(): void {
    nsApp.on(nsApp.resumeEvent, (eventData: nsApp.ApplicationEventData) => {
      // give the app a bit of time to start
      setTimeout(this.sync.bind(this), 1000);
    });
  }

  private save(provider: string, source: string, dateYYYYMMDD: string, steps: number): Promise<void> {
    return super.post(
      `tracker_activities/${encodeURIComponent(provider)}/${encodeURIComponent(source)}/on/${dateYYYYMMDD}`,
      `steps=${steps}`
    );
  }
}

#6

Thank you very much.