Tracking sweat loss

Samsung Health Sensor SDK provides tracking sweat loss after an exercise. Implementation of the Sweat loss tracker differs a little from other tracker types, as it requires one more step – feeding the tracker with additional data (the ‘steps per minute’ value) provided from another source such as Wear OS’s Health Services library.

In addition, the tracker object requires one more element – TrackerUserProfile which includes weight, height, age, and gender.
The following steps describe how to track sweat loss data.

Getting a HealthTracker instance for sweat loss

After successfully connecting to the HealthTrackingService, a starting point is to get a HealthTracker instance.

  • HealthTrackingService.getHealthTracker HealthTrackerType, TrackerUserProfile, ExerciseType)

The TrackerUserProfile should be set with TrackerUserProfile.Builder().

private TrackerUserProfile profile;

    // Set the user profile.
    profile = new TrackerUserProfile.Builder()
        .setHeight(height)
        .setWeight(weight)
        .setGender(gender)
        .setAge(age)
        .build();

Create a HealthTracker instance for sweat loss with the user profile (from the example above) and the ExerciseType.RUNNING.

private HealthTracker sweatLossTracker = null;

// After HealthTrackingService.connectService() is called
private final ConnectionListener connectionListener = new ConnectionListener() {
    @Override
    public void onConnectionSuccess() {
        try {
            // Get a HealthTracker instance for sweat loss.
            sweatLossTracker = 
                healthTrackingService.getHealthTracker(HealthTrackerType.SWEAT_LOSS, 
                profile, 
                com.samsung.android.service.health.tracking.data.ExerciseType.RUNNING);
        } catch (final IllegalArgumentException e) {
            // Exception handling.
        } catch (final UnsupportedOperationException e) {
            // Exception handling.
        }
    }
    
    // Override other functions of the listener

};

Set the event listener. We discuss the listener later.

// Set an event listener for getting sweat loss data
sweatLossTracker.setEventListener(trackerEventListener);

Starting an exercise with Health Services

During the exercise, you should keep feeding sweat loss tracker with STEPS_PER_MINUTE. Such data is available through Health Services. Create an ExerciseClient and set the event listener for an exercise data update.

private ExerciseClient exerciseClient;

private void initExerciseClient() {
    if (exerciseClient == null) {
        exerciseClient = 
            HealthServicesClientProvider.getClient(context).getExerciseClient();
        exerciseClient.setUpdateCallback(exerciseUpdateCallback);
    }
}

Configure a running exercise so that it can track STEPS_PER_MINUTE and DISTANCE.

STEPS_PER_MINUTE is later sent to health tracker using HealthTracker.setExerciseData() and DISTANCE is helpful to check an error case when a sweat loss’s status is not zero.

final ExerciseConfig.Builder exerciseConfigBuilder =
        ExerciseConfig.builder(ExerciseType.RUNNING)
                .setDataTypes(new HashSet<>(Arrays.asList(DataType.DISTANCE, STEPS_PER_MINUTE)))
                .setIsAutoPauseAndResumeEnabled(false)
                .setIsGpsEnabled(false);

The data from Health Services comes in ExerciseUpdateCallback.

private final ExerciseUpdateCallback exerciseUpdateCallback =
    new ExerciseUpdateCallback() {

        @Override
        public void onExerciseUpdateReceived(ExerciseUpdate update) {
            // ‘Steps per minute’ values are represented as Sample Data Points
            extractStepsPerMinute(update.getLatestMetrics().getSampleDataPoints());
            // Use update.getLatestMetrics().getIntervalDataPoints() to get access
             // to such data as ‘distance’
        }

	// Override other functions of the callback

    };

Setting the exercise state to START

Start the exercise using ExerciseClient.startExerciseAsync(). After configuring and starting the exercise in Health Services, it is time to set the exercise state to START on the sweat loss tracker.

try {
    // Set the exercise state to START.
    sweatLossTracker.setExerciseState(ExerciseState.START);
} catch (final IllegalStateException e) {
    // Exception handling.
}

Extracting exercise data and sending them to the Tracker

The example below shows how to extract ‘steps per minute’ from onExerciseUpdateReceived(ExerciseUpdate exerciseUpdate) (they reside in exerciseUpdate.getLatestMetrics().getSampleDataPoints()).

private void extractStepsPerMinute(List<SampleDataPoint<?>> dataPoints) {
    final int listSize = dataPoints.size();

    final float[] spmData = new float[listSize];
    final long[] timeStamp = new long[listSize];

    for (SampleDataPoint<?> element : dataPoints) {
        if (element.getDataType().equals(STEPS_PER_MINUTE)) {

            spmData[dataPoints.indexOf(element)] = (Long)
                Objects.requireNonNull(element).getValue();
            timeStamp[dataPoints.indexOf(element)] = getUtcTimeFromSystemElapsedTime(Objects.requireNonNull(element).getTimeDurationFromBoot().toMillis());
        }
    }
    if (listSize > 0) {
        sweatLossTracker.setExerciseData(STEPS_PER_MINUTE, stepsPerMinuteValues, stepsPerMinuteTimeStamps);
    }
}

We send the exercise data - STEPS_PER_MINUTE to Samsung Health Sensor SDK’s sweat loss tracker using HealthTracker.setExerciseData().
Monitoring the distance and duration of the exercise is helpful. If the exercise’s duration is less than 5 minutes or the distance is less than 2 kilometers, Samsung Health Sensor SDK gives an error in a sweat loss’ STATUS.

For more errors of SweatLossSet.STATUS, see Samsung Health Sensor SDK’s API Reference.

Setting the exercise state with STOP

If you decide to finish the exercise, set the exercise state to STOP on the tracker.

@Override
public void endExercise(boolean exception, String state) {
    try {
        sweatLossTracker.setExerciseState(ExerciseState.STOP);
    } catch (final IllegalStateException e) {
        // Exception handling
    }
}

You should also stop the exercise in the context of Health Services using ExerciseClient.endExerciseAsync().

Checking the Tracker event listener

If the running exercise is finished, sweat loss data is available in HealthTracker.TrackerEventListener. Check a sweat loss’s value and its status.

private final HealthTracker.TrackerEventListener trackerEventListener = new HealthTracker.TrackerEventListener() {
    @Override
    public void onDataReceived(@NonNull List<DataPoint> list) {
        if (list.size() != 0) {
            float sweatLoss = list.get(0).getValue(ValueKey.SweatLossSet.SWEAT_LOSS);
            int status = list.get(0).getValue(ValueKey.SweatLossSet.STATUS);
                if (status == 0) 
                    // No error
                else
                    // Check status and handle an error.
            });
        } else {
            // No data
        }
    }

    @Override
    public void onFlushCompleted() {
        // ...
    }

    @Override
    public void onError(HealthTracker.TrackerError trackerError) {
        if (trackerError == HealthTracker.TrackerError.PERMISSION_ERROR) {
            // Permission handling
        }
        if (trackerError == HealthTracker.TrackerError.SDK_POLICY_ERROR) {
            // Check a device’s network or submit a query in Samsung dev site.
        }
        // ...
    }
};

Unsetting the Tracker event listener

After getting the final sweat loss tracker, unset the registered tracker’s event listener.

sweatLossTracker.unsetEventListener();

For more information about sweat loss tracking, refer to the Sweat Loss Monitor sample app.