[Huawei Developers] Mike-mei:
As a busy developer, I can hardly spare the time to go to the gym, but I know that I should. Then I came across the videos of Pamela Reif, a popular fitness blogger, which gave me the idea of working out from home. I followed a home workout regimen, but found it hard to track my training load systematically, such through heart rate and calories burned. And that's exactly how my app, Fitness Manager came into being. I developed this app by harnessing the extended capabilities in HMS Core Health Kit. Next, I'll show you how you can do the same!

Demo​

View attachment 5626065

About Health Kit​

Health Kit offers both basic and extended capabilities to be integrated. Its basic capabilities allow your app to add, delete, modify, and query user fitness and health data upon obtaining the user's authorization, so that you can provide a rich array of fitness and health services. Its extended capabilities open a greater range of real-time fitness and health data and solutions.

Fitness Manager was solely developed from the extended capabilities in Health Kit.

Development Process​

Environment Requirements​

Android platform:

Android Studio: 3.X or later

JDK 1.8.211 or later

SDK and Gradle:

minSdkVersion 24

targetSdkVersion 29

compileSdkVersion 29

Gradle: 4.6 or later

Test device: You'll need a Huawei phone that runs Android 6.0 or later, and has installed the HUAWEI Health app.

Development Procedure​

Here I'll detail the entire process for developing an app using the extended capabilities mentioned above.

Before getting started, register and apply for the HUAWEI ID service, and then apply for the Health Kit service on HUAWEI Developers. You can skip this step if you have already created an app using the kit's basic capabilities. Then, apply for the data read and write scopes you need for your app. If you have any special needs, send an email to hihealth@huawei.com.

Now, integrate the SDK for the extended capabilities to your project in Android Studio. Before building the APK, make sure that you have configured the obfuscation script to prevent the HMS Core SDK from being obfuscated. Once the integration is complete, test your app against the test cases, and submit it for review. After passing the review, your app will obtain the formal scopes, and can be finally released.

Now, I'll show you how to implement some common features in your app using the kit's capabilities.

Starting and Stopping a Workout​

To control workouts and obtain real-time workout data, call the following APIs in sequence:

registerSportData: Starts obtaining real-time workout data.

startSport: Starts a workout.

stopSport: Stops a workout.

unregisterSportData: Stops obtaining real-time workout data.

Key Code​

1. Starting obtaining real-time workout data

Call the registerSportData method of the HiHealthDataStore object to start obtaining real-time workout data.

Obtain the workout data through HiSportDataCallback.

HiHealthDataStore.registerSportData(context, new HiSportDataCallback() {
@Override
public void onResult(int resultCode) {
// API calling result.
Log.i(TAG, "registerSportData onResult resultCode:" + resultCode);
}

@Override
public void onDataChanged(int state, Bundle bundle) {
// Real-time data change callback.
Log.i(TAG, "registerSportData onChange state: " + state);
StringBuffer stringBuffer = new StringBuffer("");
if (state == HiHealthKitConstant.SPORT_STATUS_RUNNING) {
Log.i(TAG, "heart rate : " + bundle.getInt(HiHealthKitConstant.BUNDLE_KEY_HEARTRATE));
Log.i(TAG, "distance : " + bundle.getInt(HiHealthKitConstant.BUNDLE_KEY_DISTANCE));
Log.i(TAG, "duration : " + bundle.getInt(HiHealthKitConstant.BUNDLE_KEY_DURATION));
Log.i(TAG, "calorie : " + bundle.getInt(HiHealthKitConstant.BUNDLE_KEY_CALORIE));
Log.i(TAG, "totalSteps : " + bundle.getInt(HiHealthKitConstant.BUNDLE_KEY_TOTAL_STEPS));
Log.i(TAG, "totalCreep : " + bundle.getInt(HiHealthKitConstant.BUNDLE_KEY_TOTAL_CREEP));
Log.i(TAG, "totalDescent : " + bundle.getInt(HiHealthKitConstant.BUNDLE_KEY_TOTAL_DESCENT));
}
}
});

2. Starting a workout

The following table lists supported workout constants.

Open Data Type​

Constant​

Outdoor walking​

HiHealthKitConstant.SPORT_TYPE_WALK

Outdoor running​

HiHealthKitConstant.SPORT_TYPE_RUN

Outdoor cycling​

HiHealthKitConstant.SPORT_TYPE_BIKE

Indoor running​

HiHealthKitConstant.SPORT_TYPE_TREADMILL

Call the startSport method of the HiHealthDataStore object to start a specific type of workout.

Obtain the calling result through ResultCallback.

// Outdoor running.
int sportType = HiHealthKitConstant.SPORT_TYPE_RUN;
HiHealthDataStore.startSport(context, sportType, new ResultCallback() {
@Override
public void onResult(int resultCode, Object message) {
if (resultCode == HiHealthError.SUCCESS) {
Log.i(TAG, "start sport success");
}
}
});

3. Stopping a workout

Call the stopSport method of the HiHealthDataStore object to stop a specific type of workout.

Obtain the calling result through ResultCallback.

HiHealthDataStore.stopSport(context, new ResultCallback() {
@Override
public void onResult(int resultCode, Object message) {
if (resultCode == HiHealthError.SUCCESS) {
Log.i(TAG, "stop sport success");
}
}
});

4. Stopping obtaining real-time workout data

Call the unregisterSportData method of the HiHealthDataStore object to stop obtaining the real-time workout data.

Obtain the calling result through HiSportDataCallback.

HiHealthDataStore.unregisterSportData(context, new HiSportDataCallback() {
@Override
public void onResult(int resultCode) {
// API calling result.
Log.i(TAG, "unregisterSportData onResult resultCode:" + resultCode);
}

@Override
public void onDataChanged(int state, Bundle bundle) {
// The API is not called at the moment.
}
});

Querying Daily Activities​

You can allow your users to query their daily activities in your app, such as step count details and statistics, distance, calories burned, and medium- and high-intensity activities. These data comes from Huawei phones or Huawei wearable devices. Before data query, you'll need to apply for the corresponding permissions, and obtain authorization from users. Otherwise, your API calling will fail.

1. Querying daily activity data by calling execQuery

Call the execQuery method of the HiHealthDataStore object to query user's daily activities.

Obtain the query result through ResultCallback.

The following takes querying step statistics as an example:

int timeout = 0;
// Query the step count of the current day.
Calendar currentDate = Calendar.getInstance();
currentDate.set(Calendar.HOUR_OF_DAY, 0);
currentDate.set(Calendar.MINUTE, 0);
currentDate.set(Calendar.SECOND, 0);
long startTime = currentDate.getTimeInMillis();
long endTime = System.currentTimeMillis();
// Query the step count.
HiHealthDataQuery hiHealthDataQuery = new HiHealthDataQuery(HiHealthPointType.DATA_POINT_STEP_SUM, startTime,
endTime, new HiHealthDataQueryOption());
HiHealthDataStore.execQuery(context, hiHealthDataQuery, timeout, new ResultCallback() {
@Override
public void onResult(int resultCode, Object data) {
Log.i(TAG, "query steps resultCode: " + resultCode);
if (resultCode == HiHealthError.SUCCESS && data instanceof List) {
List dataList = (ArrayList) data;
for (Object obj : dataList) {
HiHealthPointData pointData = (HiHealthPointData) obj;
Log.i(TAG, "start time : " + pointData.getStartTime());
Log.i(TAG, "query steps : " + String.valueOf(pointData.getValue()));
}
}
}
});

Parameters required for query and the query results

Open Data Type	Parameter for Query	Method for Obtaining the Result	Result Value Type	Result Description
Daily activities	Step count statistics	HiHealthPointType.DATA_POINT_STEP_SUM	HiHealthPointData.getValue()	int	Step count (unit: step). For the current day, the value is updated in real time. For each of the previous days, the value is the total step count of that day.
Step count details	HiHealthPointType.DATA_POINT_STEP	Step count per minute (unit: step).
Distance	HiHealthPointType.DATA_POINT_DISTANCE_SUM	Distance (unit: meter). For the current day, the value is updated in real time. For each of the previous days, the value is the total distance of that day.
Calories burned	HiHealthPointType.DATA_POINT_CALORIES_SUM	Calories burned (unit: kcal). For the current day, the value is updated in real time. For each of the previous days, the value is the total calories burned of that day.
Medium- and high-intensity activities	HiHealthPointType.DATA_POINT_EXERCISE_INTENSITY	Intensity (unit: minute). For the current day, the value is updated in real time. For each of the previous days, the value is the total intensity of that day.

Querying Workout Records​

The following is an example of querying workout records in the last 30 days:

Call the execQuery method of the HiHealthDataStore object to query user's workout records.

Obtain the query result through ResultCallback.

int timeout = 0;
long endTime = System.currentTimeMillis();
// The time range for the query is the past 30 days.
long startTime = endTime - 1000 * 60 * 60 * 24 * 30L;
// Query the running data.
HiHealthDataQuery hiHealthDataQuery = new HiHealthDataQuery(HiHealthSetType.DATA_SET_RUN_METADATA, startTime,
endTime, new HiHealthDataQueryOption());
HiHealthDataStore.execQuery(context, hiHealthDataQuery, timeout, new ResultCallback() {
@Override
public void onResult(int resultCode, Object data) {
if (resultCode == HiHealthError.SUCCESS && data instanceof List){
List dataList = (List) data;
for (Object obj : dataList) {
HiHealthSetData hiHealthData = (HiHealthSetData) obj;
Map map = hiHealthData.getMap();
Log.i(TAG, "start time : " + hiHealthData.getStartTime());
Log.i(TAG, "total_time : " + map.get(HiHealthKitConstant.BUNDLE_KEY_TOTAL_TIME));
Log.i(TAG, "total_distance : " + map.get(HiHealthKitConstant.BUNDLE_KEY_TOTAL_DISTANCE));
Log.i(TAG, "total_calories : " + map.get(HiHealthKitConstant.BUNDLE_KEY_TOTAL_CALORIES));
Log.i(TAG, "step : " + map.get(HiHealthKitConstant.BUNDLE_KEY_STEP));
Log.i(TAG, "average_pace : " + map.get(HiHealthKitConstant.BUNDLE_KEY_AVERAGEPACE));
Log.i(TAG, "average_speed : " + map.get(HiHealthKitConstant.BUNDLE_KEY_AVERAGE_SPEED));
Log.i(TAG, "average_step_rate : " + map.get(HiHealthKitConstant.BUNDLE_KEY_AVERAGE_STEP_RATE));
Log.i(TAG, "step_distance : " + map.get(HiHealthKitConstant.BUNDLE_KEY_STEP_DISTANCE));
Log.i(TAG, "average_heart_rate : " + map.get(HiHealthKitConstant.BUNDLE_KEY_AVERAGE_HEART_RATE));
Log.i(TAG, "total_altitude : " + map.get(HiHealthKitConstant.BUNDLE_KEY_TOTAL_ALTITUDE));
Log.i(TAG, "total_descent : " + map.get(HiHealthKitConstant.BUNDLE_KEY_TOTALDESCENT));
Log.i(TAG, "data source : " + map.get(HiHealthKitConstant.BUNDLE_KEY_DATA_SOURCE));
}
}
}
});

References

HUAWEI Developers

HUAWEI Health Kit