Usage: Sync health data manually
Sync Samsung Health data by yourself.
The automatic implementation is faster and easier to integrate and is what most developers need, try to use it before attempting to create a custom sync process.
Sync health data manually
There are 2 types of health data Summaries and Events.
Health Data | Timezone | Oldest date of retrieval | Latest date of retrieval |
---|---|---|---|
Summary | UTC | 29 days | Yesterday |
Event | UTC | 29 days | Today |
Sync summaries
Use sync(enableLogs: Boolean)
to sync the last 29 days of SLEEP_SUMMARY, PHYSICAL_SUMMARY and BODY_SUMMARY (not
including today).
rookSamsung.sync(enableLogs = isDebug).fold(
{
// Historic summaries sync started
},
{
// Handle error
},
)
Use sync(date: LocalDate)
to sync SLEEP_SUMMARY, PHYSICAL_SUMMARY and BODY_SUMMARY for the provided date
.
rookSamsung.sync(date = localDate).fold(
{
// Summaries synced successfully
},
{
// Handle error
},
)
Use sync(date: LocalDate, summary: SHSyncType.Summary)
to sync the summary
of choice for the provided date
.
rookSamsung.sync(date = localDate, summary = summary).fold(
{
// Summary synced successfully
},
{
// Handle error
},
)
Sync events
Use syncEvents(date: LocalDate, event: SHSyncType.Event)
to sync the event
of choice for the provided date
.
rookSamsung.syncEvents(date = localDate, event = event).fold(
{
// Event synced successfully
},
{
// Handle error
},
)
Sync current day events
Current day events allow to send small amounts of health data, but they also return the data that was sent, you can use this data to update your UI without waiting for the webhook event.
Steps events
Retrieve and upload current day steps count of Samsung Health.
rookSamsung.getTodayStepsCount().fold(
{
when (it) {
SHSyncStatusWithData.RecordsNotFound -> {
// No steps events found
}
is SHSyncStatusWithData.Synced -> {
val steps: Int = it.data
// Update the UI with steps count
}
}
},
{
// Handle error
}
)
Calories events
Retrieve and upload current day calories count of Samsung Health.
rookSamsung.getTodayCaloriesCount().fold(
{
when (it) {
SHSyncStatusWithData.RecordsNotFound -> {
// No calories events found
}
is SHSyncStatusWithData.Synced -> {
val dailyCalories: SHCalories = it.data
// Update the UI with calories count
}
}
},
{
// Handle error
}
)
Sync and display
If you want to sync and get a copy of the summary/event that was uploaded you can call any of the following functions:
Sleep Summary
rookSamsung.getSleepSummary(localDate).fold(
{
when (it) {
SHSyncStatusWithData.RecordsNotFound -> {
// No records found
}
is SHSyncStatusWithData.Synced<List<SHSleepSummary>> -> {
val sleepSummaries = it.data
// Update UI
}
}
},
{
// Handle error
},
)
The returned SleepSummary has the following definition:
// Properties not supported by Samsung Health or not processed by this SDK are commented out and will always be null.
// Commented properties are updated with the latest public version of the SDK.
data class SHSleepSummary(
val dateTime: Instant,
val sourceOfData: String,
val wasTheUserUnderPhysicalActivity: Boolean,
val sleepStartDateTime: Instant,
val sleepEndDateTime: Instant,
val sleepDate: LocalDate,
val sleepDurationSeconds: Int?,
val timeInBedSeconds: Int?,
val lightSleepDurationSeconds: Int?,
val remSleepDurationSeconds: Int?,
val deepSleepDurationSeconds: Int?,
// val timeToFallAsleepSeconds: Int?,
val timeAwakeDuringSleepSeconds: Int?,
// val sleepQualityRating1To5Score: Int?,
val sleepEfficiency1To100Score: Int?,
// val sleepGoalSeconds: Int?,
// val sleepContinuity1To5Score: Int?,
// val sleepContinuity1To5Rating: Int?,
val hrMaximumBpm: Int?,
val hrMinimumBpm: Int?,
val hrAvgBpm: Int?,
// val hrRestingBpm: Int?,
// val hrBasalBpm: Int?,
val hrGranularData: List<HrGranularData>?,
// val hrvAvgRmssd: Double?,
// val hrvAvgSdnn: Double?,
// val hrvSdnnGranularData: List<HrvSdnnGranularData>?,
// val hrvRmssdGranularData: List<HrvRmssdGranularData>?,
// val temperatureMinimum: TemperatureObject?,
// val temperatureAvg: TemperatureObject?,
// val temperatureMaximum: TemperatureObject?,
// val temperatureGranularData: List<TemperatureGranularData>?,
// val temperatureDelta: TemperatureObject?,
// val breathsMinimumPerMin: Double?,
// val breathsAvgPerMin: Double?,
// val breathsMaximumPerMin: Double?,
// val breathingGranularData: List<BreathingGranularData>?,
// val snoringEventsCount: Int?,
// val snoringDurationTotalSeconds: Int?,
// val snoringGranularData: List<SnoringGranularData>?,
val saturationAvgPercentage: Double?,
val saturationMinimumPercentage: Double?,
val saturationMaximumPercentage: Double?,
val saturationGranularData: List<SaturationGranularData>?,
)
Physical Summary
rookSamsung.getPhysicalSummary(localDate).fold(
{
when (it) {
SHSyncStatusWithData.RecordsNotFound -> {
// No records found
}
is SHSyncStatusWithData.Synced<SHPhysicalSummary> -> {
val phyiscalSummary = it.data
// Update UI
}
}
},
{
// Handle error
},
)
The returned PhysicalSummary has the following definition:
// Properties not supported by Samsung Health or not processed by this SDK are commented out and will always be null.
// Commented properties are updated with the latest public version of the SDK.
data class SHPhysicalSummary(
val dateTime: Instant,
val sourceOfData: String,
val wasTheUserUnderPhysicalActivity: Boolean,
val activeSeconds: Int?,
// val restSeconds: Int?,
// val lowIntensitySeconds: Int?,
// val moderateIntensitySeconds: Int?,
// val vigorousIntensitySeconds: Int?,
// val inactivitySeconds: Int?,
// val activityLevelGranularData: List<ActivityLevelGranularData>?,
// val continuousInactivePeriods: Int?,
val caloriesNetIntakeKcal: Double?,
val caloriesExpenditureKcal: Double?,
val caloriesNetActiveKcal: Double?,
// val caloriesBasalMetabolicRateKcal: Double?,
val steps: Int?,
// val stepsGranularData: List<StepsGranularData>?,
// val activeSteps: Int?,
// val activeStepsGranularData: List<ActiveStepsGranularData>?,
// val walkedDistanceMeters: Double?,
val traveledDistanceMeters: Double?,
// val traveledDistanceGranularData: List<TraveledDistanceGranularData>?,
val floorsClimbed: Double?,
// val floorsClimbedGranularData: List<FloorsClimbedGranularData>?,
// val elevationAvgAltitudeMeters: Double?,
// val elevationMinimumAltitudeMeters: Double?,
// val elevationMaximumAltitudeMeters: Double?,
// val elevationLossActualAltitudeMeters: Double?,
// val elevationGainActualAltitudeMeters: Double?,
// val elevationPlannedGainMeters: Double?,
// val elevationGranularData: List<ElevationGranularData>?,
// val swimmingNumStrokes: Int?,
// val swimmingNumLaps: Int?,
// val swimmingPoolLengthMeters: Double?,
// val swimmingTotalDistanceMeters: Double?,
// val swimmingDistanceGranularData: List<SwimmingDistanceGranularData>?,
val hrMaximumBpm: Int?,
val hrMinimumBpm: Int?,
val hrAvgBpm: Int?,
// val hrRestingBpm: Int?,
val hrGranularData: List<HrGranularData>?,
// val hrvAvgRmssd: Double?,
// val hrvAvgSdnn: Double?,
// val hrvSdnnGranularData: List<HrvSdnnGranularData>?,
// val hrvRmssdGranularData: List<HrvRmssdGranularData>?,
val saturationAvgPercentage: Double?,
val saturationGranularData: List<SaturationGranularData>?,
// val vo2MaxMlPerMinPerKg: Double?,
// val vo2GranularData: List<Vo2GranularData>?,
// val stressAtRestDurationSeconds: Int?,
// val stressDurationSeconds: Int?,
// val lowStressDurationSeconds: Int?,
// val mediumStressDurationSeconds: Int?,
// val highStressDurationSeconds: Int?,
// val stressGranularData: List<StressGranularData>?,
// val stressAvgLevel: Int?,
// val stressMaximumLevel: Int?,
)
Body Summary
rookSamsung.getBodySummary(localDate).fold(
{
when (it) {
SHSyncStatusWithData.RecordsNotFound -> {
// No records found
}
is SHSyncStatusWithData.Synced<SHBodySummary> -> {
val bodySummary = it.data
// Update UI
}
}
},
{
// Handle error
},
)
The returned BodySummary has the following definition:
// Properties not supported by Samsung Health or not processed by this SDK are commented out and will always be null.
// Commented properties are updated with the latest public version of the SDK.
data class SHBodySummary(
val dateTime: Instant,
val sourceOfData: String,
val wasTheUserUnderPhysicalActivity: Boolean,
// val waistCircumferenceCm: Double?,
// val hipCircumferenceCm: Double?,
// val chestCircumferenceCm: Double?,
// val boneCompositionPercentage: Double?,
// val muscleCompositionPercentage: Double?,
// val waterCompositionPercentage: Double?,
val weightKg: Double?,
val heightCm: Double?,
val bmi: Double?,
val bloodGlucoseAvgMgPerDl: Double?,
val bloodGlucoseGranularData: List<BloodGlucoseGranularData>?,
val bloodPressureAvg: BloodPressureObject?,
val bloodPressureGranularData: List<BloodPressureGranularData>?,
val waterTotalConsumptionMl: Double?,
val hydrationAmountGranularData: List<HydrationAmountGranularData>?,
// val hydrationLevelGranularData: List<HydrationLevelGranularData>?,
val hrMaximumBpm: Int?,
val hrMinimumBpm: Int?,
val hrAvgBpm: Int?,
// val hrRestingBpm: Int?,
val hrGranularData: List<HrGranularData>?,
// val hrvAvgRmssd: Double?,
// val hrvAvgSdnn: Double?,
// val hrvSdnnGranularData: List<HrvSdnnGranularData>?,
// val hrvRmssdGranularData: List<HrvRmssdGranularData>?,
// val moodMinimumScale: Double?,
// val moodAvgScale: Double?,
// val moodMaximumScale: Double?,
// val moodGranularData: List<MoodGranularData>?,
// val moodDeltaScale: Double?,
// val foodIntake: Double?,
val caloriesIntakeKcal: Double?,
val proteinIntakeG: Double?,
val sugarIntakeG: Double?,
val fatIntakeG: Double?,
val transFatIntakeG: Double?,
val carbohydratesIntakeG: Double?,
val fiberIntakeG: Double?,
// val alcoholIntakeG: Double?,
val sodiumIntakeMg: Double?,
val cholesterolIntakeMg: Double?,
val saturationAvgPercentage: Double?,
val saturationGranularData: List<SaturationGranularData>?,
// val vo2MaxMlPerMinPerKg: Double?,
// val vo2GranularData: List<Vo2GranularData>?,
// val temperatureMinimum: TemperatureObject?,
// val temperatureAvg: TemperatureObject?,
// val temperatureMaximum: TemperatureObject?,
// val temperatureGranularData: List<TemperatureGranularData>?,
// val temperatureDelta: TemperatureObject?,
// val lastUpdatedDatetime: Instant?,
// val periodStartDate: LocalDate?,
// val cycleDay: Int?,
// val cycleLengthDays: Int?,
// val predictedCycleLengthDays: Int?,
// val currentPhase: String?,
// val lengthOfCurrentPhaseDays: Int?,
// val daysUntilNextPhase: Int?,
// val isAPredictedCycle: Boolean?,
// val menstruationFlowGranularData: List<MenstruationFlowGranularData>?,
)
Activity event
rookSamsung.getActivityEvents(localDate).fold(
{
when (it) {
SHSyncStatusWithData.RecordsNotFound -> {
// No records found
}
is SHSyncStatusWithData.Synced<List<SHActivityEvent>> -> {
val activityEvents = it.data
// Update UI
}
}
},
{
// Handle error
},
)
The returned ActivityEvent has the following definition:
// Properties not supported by Samsung Health or not processed by this SDK are commented out and will always be null.
// Commented properties are updated with the latest public version of the SDK.
data class SHActivityEvent(
val dateTime: Instant,
val sourceOfData: String,
val wasTheUserUnderPhysicalActivity: Boolean,
val activityStartDateTime: Instant,
val activityEndDateTime: Instant,
val activityDurationSeconds: Int,
val activityTypeName: String,
val activeSeconds: Int?,
// val restSeconds: Int?,
// val lowIntensitySeconds: Int?,
// val moderateIntensitySeconds: Int?,
// val vigorousIntensitySeconds: Int?,
// val inactivitySeconds: Int?,
// val activityLevelGranularData: List<ActivityLevelGranularData>?,
// val continuousInactivePeriods: Int?,
// val activityStrainLevel: Int?,
// val activityWorkKilojoules: Double?,
// val activityEnergyKilojoules: Double?,
// val activityEnergyPlannedKilojoules: Double?,
val caloriesNetIntakeKcal: Double?,
val caloriesExpenditureKcal: Double?,
val caloriesNetActiveKcal: Double?,
// val caloriesBasalMetabolicRateKcal: Double?,
// val fatPercentageOfCalories: Double?,
// val carbohydratePercentageOfCalories: Double?,
// val proteinPercentageOfCalories: Double?,
val steps: Int?,
// val stepsGranularData: List<StepsGranularData>?,
// val walkedDistanceMeters: Double?,
val traveledDistanceMeters: Double?,
// val traveledDistanceGranularData: List<TraveledDistanceGranularData>?,
val floorsClimbed: Double?,
// val floorsClimbedGranularData: List<FloorsClimbedGranularData>?,
val elevationAvgAltitudeMeters: Double?,
val elevationMinimumAltitudeMeters: Double?,
val elevationMaximumAltitudeMeters: Double?,
val elevationLossActualAltitudeMeters: Double?,
val elevationGainActualAltitudeMeters: Double?,
// val elevationPlannedGainMeters: Double?,
// val elevationGranularData: List<ElevationGranularData>?,
val swimmingNumStrokes: Int?,
// val swimmingNumLaps: Int?,
val swimmingPoolLengthMeters: Double?,
val swimmingTotalDistanceMeters: Double?,
// val swimmingDistanceGranularData: List<SwimmingDistanceGranularData>?,
val hrMaximumBpm: Int?,
val hrMinimumBpm: Int?,
val hrAvgBpm: Int?,
// val hrRestingBpm: Int?,
val hrGranularData: List<HrGranularData>?,
// val hrvAvgRmssd: Double?,
// val hrvAvgSdnn: Double?,
// val hrvSdnnGranularData: List<HrvSdnnGranularData>?,
// val hrvRmssdGranularData: List<HrvRmssdGranularData>?,
val speedNormalizedMetersPerSecond: Double?,
val speedAvgMetersPerSecond: Double?,
val speedMaximumMetersPerSecond: Double?,
// val speedGranularData: List<SpeedGranularData>?,
// val velocityAvg: VelocityObject?,
// val velocityMaximum: VelocityObject?,
// val paceAvgMinPerKm: Double?,
// val paceMaximumMinPerKm: Double?,
val cadenceAvgRpm: Double?,
val cadenceMaximumRpm: Double?,
// val cadenceGranularData: List<CadenceGranularData>?,
// val torqueAvgNewtonMeters: Double?,
// val torqueMaximumNewtonMeters: Double?,
// val torqueGranularData: List<TorqueGranularData>?,
// val lapGranularData: List<LapGranularData>?,
val saturationAvgPercentage: Double?,
val saturationGranularData: List<SaturationGranularData>?,
// val vo2MaxMlPerMinPerKg: Double?,
// val vo2GranularData: List<Vo2GranularData>?,
val positionStart: PositionObject?,
val positionCentroid: PositionObject?,
val positionEnd: PositionObject?,
val positionGranularData: List<PositionGranularData>?,
// val positionPolylineMapDataSummary: String?,
val powerAvgWatts: Double?,
val powerMaximumWatts: Double?,
// val powerGranularData: List<PowerGranularData>?,
// val stressAtRestDurationSeconds: Int?,
// val stressDurationSeconds: Int?,
// val lowStressDurationSeconds: Int?,
// val mediumStressDurationSeconds: Int?,
// val highStressDurationSeconds: Int?,
// val tssGranularData: List<TssGranularData>?,
// val stressAvgLevel: Int?,
// val stressMaximumLevel: Int?,
)