NoteSamsung Health SDK for Android partners, please migrate to Samsung Health Data SDK to access additional health data types and continue to utilize existing data types supported via Samsung Health SDK for Android. Samsung Health SDK for Android has been deprecated. Please find instructions to migrate to Samsung Health Data SDK.
Migration Guide from Samsung Health SDK for Android to Samsung Health Data SDK
Following the release of Samsung Health Data SDK, Samsung Health SDK for Android will be deprecated in few months. After this transition, partner apps that currently use Samsung Health SDK for Android need to transition to Samsung Health Data SDK.
Benefits of Migrating to Samsung Health Data SDK
Samsung Health Data SDK enables apps to access health data in the Samsung Health app on Android smartphones. Not only does it offer the functionality as Samsung Health SDK for Android, but it also provides various additional advantages. Compared to Samsung Health SDK for Android, Samsung Health Data SDK applies the service logic displayed in the Samsung Health app's trackers and provides more specialized data from the app. This allows health service providers to gain a better understanding of users' health indicators.
For example, to retrieve the same step count data displayed in the Samsung Health app when using Samsung Health SDK for Android, you need to:
Set the data type as StepDailyTrend.
Set filters for both:
The time period
SOURCE_TYPE_ALL
This ensures that you receive the same step count data that`s displayed in the Samsung Health app.
Samsung Health SDK for Android code
val healthDataResolver = HealthDataResolver(healthDataStore, null)
val date = LocalDate
.now()
.atStartOfDay()
.toInstant(ZoneOffset.UTC)
.toEpochMilli()
val filter = Filter.and(
Filter.eq(StepDailyTrend.DAY_TIME, date),
Filter.eq(StepDailyTrend.SOURCE_TYPE, StepDailyTrend.SOURCE_TYPE_ALL)
)
val stepsRequest = HealthDataResolver.ReadRequest.Builder()
.setDataType(StepDailyTrend.HEALTH_DATA_TYPE)
.setFilter(filter)
.build()
With Samsung Health Data SDK, you can simplify a data request by utilizing the total aggregator and only applying a time filter. This data request allows you to retrieve the daily total step count displayed in the Samsung Health app without considering the potential oversight of setting the source type to `all'.
Samsung Health Data SDK code
val startTime = LocalDate.now().atStartOfDay()
val endTime = LocalDateTime.now()
val localTimeFilter = LocalTimeFilter.of(startTime, endTime)
val stepsRequest = DataType.StepsType.TOTAL.requestBuilder
.setLocalTimeFilter(localTimeFilter)
.build()
Samsung Health Data SDK provides various goal data types, such as step goal, sleep goals, and active calories burned goal. Goal data types help to provide appropriate guidance to users.
Samsung Health Data SDK can read, write, update, and delete health data in the Samsung Health app. It can also retrieve associated data related to specific data. For example, the Samsung Health app continuously measures blood oxygen and skin temperature during sleep. Samsung Health Data SDK allows you to easily retrieve blood oxygen and skin temperature data related to this specific sleep data.
Samsung Health SDK for Android will remain operational for at least 2 years after its deprecation. After a certain period, this SDK will be removed, so we recommend updating your app to use Samsung Health Data SDK instead.
Development process
Previously Samsung Health SDK for Android required developers to submit requires a partner request to get access to be applied for and approved before use. Now with Samsung Health Data SDK you can download and use the SDK in developer mode without submitting a partner request. To enhance the convenience of more developers, the Samsung Health Data SDK has improved its developer mode functionality. If you only need to read the Samsung Health app's data, you can activate the developer mode and proceed with development and testing without requiring the partner request. If you want to test writing data to the Samsung Health app using the Samsung Health Data SDK or to distribute your app, you need to submit a partner request registration is necessary.
If you want to see the detailed process for developing an app with the Samsung Health Data SDK can be found on, please refer to the process page.
Checking supported data types of Samsung Health Data SDK
Before you start using Samsung Health Data SDK, please, compare it with Samsung Health SDK for Android and its existing data types to determine whether the data types you want to use in your app are supported and what additional data can be utilized.
Category
Data type of the Samsung Health SDK for Android SDK
Corresponding data type in the Samsung Health Data SDK
Activity
HealthConstants.Exercise
ExerciseType
HealthConstants.FloorsClimbed
FloorsClimbedType
HealthConstants.StepDailyTrend (read-only)
StepsType (read-only)
HealthConstants.StepCount (read-only)
Not provided
Not provided
StepGoalType (read-only)
Not provided
ActivitySummaryType (read-only)
Not provided
ActiveCaloriesBurnedGoalType (read-only)
Not provided
ActiveTimeGoalType (read-only)
Food intake
HealthConstants.Nutrition
NutritionType
Not provided
NutritionGoalType (read-only)
HealthConstants.WaterIntake
WaterIntakeType
Not provided
WaterIntakeGoalType (read-only)
Rest
HealthConstants.Sleep
SleepType
HealthConstants.SleepStage
Not provided
Not provided
SleepGoalType (read-only)
Healthcare
HealthConstants.BloodGlucose
BloodGlucoseType
HealthConstants.BloodPressure
BloodPressureType
HealthConstants.BodyTemperature
BodyTemperature
HealthConstants.HeartRate
HeartRateType
HealthConstants.OxygenSaturationType
BloodOxygenType
HealthConstants.Weight
BodyCompositionType
Not provided
SkinTemperature
Score
Not provided
EnergyScoreType (read-only)
User profile
HealthUserProfile (read-only)
UserProfileDataType (read-only)
Checking the user experience
To access health data from Samsung Health Data SDK, you need to receive data permissions and obtain user consent. In order to do that, please, follow the same process as Samsung Health SDK for Android. You can request data permissions at requesting data permissions.
Note
When using both SDKs together, the data permissions of each SDK are displayed to the user, which can result in an inconvenient UI for the user. Hence, we recommend to use Samsung Health Data SDK.
2) Enabling Samsung Health Data SDK’s developer mode
If you only need to read data from Samsung Health app, you can enable the developer mode feature without submitting an additional partner request. Refer to the developer mode for instructions on how to enable it.
If you want to write data to Samsung Health app, you need to submit a partner request.
3) Importing Samsung Health Data SDK's library
Remove the library of Samsung Health SDK for Android from your app project.
samsung-health-data-a.b.c.aar
And add Samsung Health Data SDK's library to the app/libs folder.
samsung-health-data-api-a.b.c.aar (Note that 'a.b.c' is the SDK's version.)
4) Update app manifest
If your app's manifest has the element for the Samsung Health app, please remove it.
App manifest - Remove the element for Samsung Health SDK for Android
And apply the kotlin-parcelize plugin to the app/build.gradle.
app/build.gradle - Add the plugin for Samsung Health Data SDK
plugins {
id("kotlin-parcelize")
}
6) Connecting with Samsung Health
To access health data in the Samsung Health app, you need to connect the SDK with the Samsung Health app. If the Samsung Health app is not installed or you have an earlier version of the Samsung Health app than the supported version, an exception occurs after the connection request. If it is a resolvable exception, call the resolve() API is to resolve the exception.
Below is an example code snippet when using Samsung Health SDK for Android.
Connecting with Samsung Health with Samsung Health SDK for Android
lateinit var healthDataStore: HealthDataStore
fun connect(activity: Activity) {
healthDataStore = HealthDataStore(context, object : HealthDataStore.ConnectionListener {
override fun onConnected() {
Log.i(APP_TAG, "Health data service is connected")
}
override fun onConnectionFailed(error: HealthConnectionErrorResult) {
if (error.hasResolution()) {
error.resolve(activity)
} else {
Log.i(APP_TAG, "Health data service is not available")
}
}
override fun onDisconnected() {
Log.i(APP_TAG, "Health data service is disconnected")
}
})
runCatching {
healthDataStore.connectService()
}.onFailure { error ->
error.message?.let { Log.i(APP_TAG, it) }
}
}
To connect to the Samsung Health app using Samsung Health Data SDK, you can do so as shown in the code below.
Connecting with Samsung Health with Samsung Health Data SDK
lateinit var healthDataStore: HealthDataStore
fun connect(activity: Activity) {
runCatching {
healthDataStore = HealthDataService.getStore(context)
}.onSuccess {
Log.i(APP_TAG, "Health data service is connected")
}.onFailure { error ->
if (error is ResolvablePlatformException && error.hasResolution) {
error.resolve(activity)
}
// handle other types of HealthDataException
error.message?.let { Log.i(APP_TAG, it) }
}
}
7) Requesting data permissions
After you have successfully connected to the Samsung Health app, you need to request data permissions for the health data you want to access from the user. Upon obtaining an explicit consent from the user, you will be able to access the health data.
Before requesting data permission, check if the user has already granted the data permission. If the required data permission has not been obtained, proceed to request the necessary data permission.
The following code is an example of requesting data permissions to read daily step count, nutrition, and user profile data when using Samsung Health SDK for Android.
Requesting data permission with Samsung Health SDK for Android
private val permissionListener: HealthResultHolder.ResultListener<PermissionResult> =
HealthResultHolder.ResultListener<PermissionResult> { result ->
if (result.resultMap.values.contains(FALSE)) {
Log.i(APP_TAG, "Not all required permissions granted")
} else {
Log.i(APP_TAG, "All required permissions granted")
}
}
fun requestPermissions(activity: Activity, healthDataStore: HealthDataStore) {
val permissionSet = setOf(
PermissionKey(
StepDailyTrend.HEALTH_DATA_TYPE,
HealthPermissionManager.PermissionType.READ
),
PermissionKey(
Nutrition.HEALTH_DATA_TYPE,
HealthPermissionManager.PermissionType.READ
),
PermissionKey(
HealthConstants.USER_PROFILE_DATA_TYPE,
HealthPermissionManager.PermissionType.READ
)
)
val permissionManager = HealthPermissionManager(healthDataStore)
runCatching {
val grantedPermissions = permissionManager.isPermissionAcquired(permissionSet)
if (grantedPermissions.values.all { it }) {
Log.i(APP_TAG, "All required permissions granted")
} else {
Log.i(APP_TAG, "Not all required permissions granted")
permissionManager.requestPermissions(permissionSet, activity)
.setResultListener(permissionListener)
}
}.onFailure { error ->
error.message?.let { Log.i(APP_TAG, it) }
}
}
When the above code is executed, the following screenshot shows the data permission popup displayed to the user.
When using the Samsung Health Data SDK, you can do the following:
Requesting data permission with Samsung Health Data SDK
suspend fun requestPermissions(healthDataStore: HealthDataStore, activity: Activity) {
val permissionSet = setOf(
Permission.of(DataTypes.STEPS, AccessType.READ),
Permission.of(DataTypes.NUTRITION, AccessType.READ),
Permission.of(DataTypes.USER_PROFILE, AccessType.READ)
)
val grantedPermissions = healthDataStore.getGrantedPermissions(permissionSet)
if (grantedPermissions.containsAll(permissionSet)) {
Log.i(APP_TAG, "All required permissions granted")
} else {
healthDataStore.requestPermissions(permissionSet, activity)
}
}
When requesting data permissions with Samsung Health Data SDK, the following screenshot will be displayed to the user.
8) Data Request
Asynchronous request
Asynchronous operations allow the application to continue processing other tasks without waiting for the current task to complete. It prevents the main thread from being blocked. It enhances user experience by keeping the application interactive during long-running tasks and supports efficient handling of concurrent operations.
Below you can see a code example of when using Samsung Health SDK for Android to make an asynchronous request.
Asynchronous request when with Samsung Health SDK for Android
fun readStepsAsync(healthDataStore: HealthDataStore) {
val healthDataResolver = HealthDataResolver(healthDataStore, null)
val date = LocalDate
.now()
.atStartOfDay()
.toInstant(ZoneOffset.UTC)
.toEpochMilli()
val filter = Filter.and(
Filter.eq(StepDailyTrend.DAY_TIME, date),
Filter.eq(StepDailyTrend.SOURCE_TYPE, StepDailyTrend.SOURCE_TYPE_ALL)
)
val stepsRequest = HealthDataResolver.ReadRequest.Builder()
.setDataType(StepDailyTrend.HEALTH_DATA_TYPE)
.setFilter(filter)
.build()
try {
healthDataResolver.read(stepsRequest).setResultListener { result ->
try {
val iterator = result.iterator()
if (iterator.hasNext()) {
val healthData = iterator.next()
val stepCount = healthData.getInt(StepDailyTrend.COUNT)
Log.i(MainActivity.APP_TAG, "Step count: $stepCount")
}
} finally {
result.close()
}
}
} catch (exception: Exception) {
exception.message?.let { Log.i(MainActivity.APP_TAG, it) }
}
}
When using Samsung Health Data SDK, you can perform the same operation as follows. Use an API that includes Async.
Asynchronous request with Samsung Health Data SDK
fun readStepsAsync(healthDataStore: HealthDataStore, activity: Activity) {
val startTime = LocalDate.now().atStartOfDay()
val endTime = LocalDateTime.now()
val localTimeFilter = LocalTimeFilter.of(startTime, endTime)
val stepsRequest = DataType.StepsType.TOTAL.requestBuilder
.setLocalTimeFilter(localTimeFilter)
.build()
healthDataStore.aggregateDataAsync(stepsRequest).setCallback(
Looper.getMainLooper(),
{ result ->
val stepCount = result.dataList.first().value
Log.i(MainActivity.APP_TAG, "Step count: $stepCount")
}) { error ->
if (error is ResolvablePlatformException && error.hasResolution) {
error.resolve(activity)
}
}
}
Synchronous request
Synchronous operations execute tasks sequentially, requiring the application to wait for the current task to complete before proceeding to the next. While this approach is simple to implement and ensures a predictable execution flow, it can block the main thread. This makes synchronous operations more suitable for straightforward, short tasks rather than complex or concurrent processes.
To perform synchronous operations when using Samsung Health SDK for Android, you can use the await() API.
Synchronous request with Samsung Health SDK for Android
fun readStepsSync(healthDataStore: HealthDataStore) {
val healthDataResolver = HealthDataResolver(healthDataStore, null)
val date = LocalDate
.now()
.atStartOfDay()
.toInstant(ZoneOffset.UTC)
.toEpochMilli()
val filter = Filter.and(
Filter.eq(StepDailyTrend.DAY_TIME, date),
Filter.eq(StepDailyTrend.SOURCE_TYPE, StepDailyTrend.SOURCE_TYPE_ALL)
)
val stepsRequest = HealthDataResolver.ReadRequest.Builder()
.setDataType(StepDailyTrend.HEALTH_DATA_TYPE)
.setFilter(filter)
.build()
try {
healthDataResolver.read(stepsRequest).await().run {
try {
val iterator = iterator()
if (iterator.hasNext()) {
val healthData = iterator.next()
val stepCount = healthData.getInt(StepDailyTrend.COUNT)
Log.i(MainActivity.APP_TAG, "Step count: $stepCount")
}
} finally {
close()
}
}
} catch (exception: Exception) {
exception.message?.let { Log.i(MainActivity.APP_TAG, it) }
}
}
For synchronous operations involving Samsung Health Data SDK, please, use the following approach.
Synchronous request with Samsung Health Data SDK
suspend fun readStepsSync(healthDataStore: HealthDataStore) {
val startTime = LocalDate.now().atStartOfDay()
val endTime = LocalDateTime.now()
val stepsRequest = DataType.StepsType.TOTAL.requestBuilder
.setLocalTimeFilterWithGroup(
LocalTimeFilter.Companion.of(startTime, endTime),
LocalTimeGroup.of(LocalTimeGroupUnit.HOURLY, 1)
)
.build()
try {
val readResult = healthDataStore.aggregateData(stepsRequest)
val stepCount = readResult.dataList.first().value
Log.i(MainActivity.APP_TAG, "Step count: $stepCount")
} catch (e: Exception) {
e.printStackTrace()
}
}
9) Implementing and testing app
Accessing the health data is required by the app to test to ensure the functionality works properly. For detailed information on accessing health data, refer to accessing health data.
10) Partner request before distributing your app
The developer mode of Samsung Health Data SDK is a feature provided only for development purposes. To ensure that an app that`s using Samsung Health Data SDK functions properly without enabling developer mode, you need to submit a partner request through the developer site before distributing your app on app market places. After partner app approval, the app's detailed information will be registered in Samsung's system.
Accessing Health data
Steps
Samsung Health measures step data from smartphones with Samsung Health installed and from connected Galaxy wearable devices, such as the Galaxy Watch, Galaxy Fit, or Galaxy Ring. It aggregates and eliminates duplicate data to provide daily step counts. Step count data is read-only.
The corresponding steps data types in Samsung Health SDK for Android and Samsung Health Data SDK are as following:
Here is an example of code that reads today's total step count when using Samsung Health SDK for Android.
Reading today's total steps with Samsung Health SDK for Android
fun readTodayStepCountData(healthDataStore: HealthDataStore) {
val startTime = LocalDate
.now()
.atStartOfDay()
.toInstant(ZoneOffset.UTC)
.toEpochMilli()
val filter = Filter.and(
Filter.eq(StepDailyTrend.DAY_TIME, startTime),
Filter.eq(StepDailyTrend.SOURCE_TYPE, StepDailyTrend.SOURCE_TYPE_ALL)
)
val healthDataResolver = HealthDataResolver(healthDataStore, null)
val request = HealthDataResolver.ReadRequest.Builder()
.setDataType(StepDailyTrend.HEALTH_DATA_TYPE)
.setFilter(filter)
.build()
try {
healthDataResolver.read(request).setResultListener { result ->
try {
val iterator = result.iterator()
if (iterator.hasNext()) {
val healthData = iterator.next()
val totalCount = healthData.getInt(StepDailyTrend.COUNT)
Log.i(MainActivity.APP_TAG, "Today steps count: $totalCount")
} else {
Log.i(MainActivity.APP_TAG, "No step data available")
The code to retrieve today's total step count when using Samsung Health Data SDK is as follows.
Reading today's total steps with Samsung Health Data SDK
suspend fun readTodayStepCountData(healthDataStore: HealthDataStore) {
val startTime = LocalDate.now().atStartOfDay()
val endTime = LocalDateTime.now()
val readRequest = DataType.StepsType.TOTAL.requestBuilder
.setLocalTimeFilter(LocalTimeFilter.of(startTime, endTime))
.build()
try {
val readResult = healthDataStore.aggregateData(readRequest)
val data = readResult.dataList.first()
val totalCount = data.value
Log.i(MainActivity.APP_TAG, "Today steps count: $totalCount")
} catch (e: Exception) {
e.printStackTrace()
}
}
Exercise
The Samsung Health app records the user's exercise data. When the user wears a Galaxy Watch, Galaxy Fit, or Galaxy Ring and records exercise data, the app records their heart rate, exercise speed, and distance.
The corresponding exercise data types in Samsung Health SDK for Android and Samsung Health Data SDK are as following:
Samsung Health SDK for Android
Samsung Health Data SDK
HealthConstants.Exercise
ExerciseType
Example code for reading today's exercise data when using Samsung Health SDK for Android is as follows.
Reading exercise data with Samsung Health SDK for Android
fun readTodayExercise(healthDataStore: HealthDataStore) {
val startTime = LocalDate.now().atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli()
val endTime =
LocalDate.now().plusDays(1).atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli()
val healthDataResolver = HealthDataResolver(healthDataStore, null)
val readRequest = HealthDataResolver.ReadRequest.Builder()
.setDataType(Exercise.HEALTH_DATA_TYPE)
.setLocalTimeRange(
FloorsClimbed.START_TIME,
FloorsClimbed.TIME_OFFSET,
startTime,
endTime
)
.build()
try {
healthDataResolver.read(readRequest).setResultListener { result ->
try {
val iterator = result.iterator()
iterator.forEach { healthData ->
val exerciseType = healthData.getInt(Exercise.EXERCISE_TYPE)
val duration = healthData.getLong(Exercise.DURATION)
val calories = healthData.getFloat(Exercise.CALORIE)
Log.i(
MainActivity.APP_TAG,
"Exercise type: $exerciseType, duration: $duration, calories: $calories"
)
}
} finally {
result.close()
}
}
} catch (exception: Exception) {
exception.message?.let { Log.i(MainActivity.APP_TAG, it) }
}
}
Example code for reading today's exercise data when using Samsung Health Data SDK is as follows.
Reading exercise data with Samsung Health Data SDK
suspend fun readTodayExercise(healthDataStore: HealthDataStore) {
val startTime = LocalDate.now().atStartOfDay()
val endTime = LocalDateTime.now()
val readRequest = DataTypes.EXERCISE.readDataRequestBuilder
.setLocalTimeFilter(LocalTimeFilter.of(startTime, endTime))
.build()
try {
val readResult = healthDataStore.readData(readRequest)
val dataPoints = readResult.dataList
if (dataPoints.isEmpty()) {
Log.i(MainActivity.APP_TAG, "No exercises today")
return
}
dataPoints.forEach { dataPoint ->
val exerciseType = dataPoint.getValue(DataType.ExerciseType.EXERCISE_TYPE)
val sessions = dataPoint.getValue(DataType.ExerciseType.SESSIONS)
sessions?.forEach { session ->
val exerciseSessionType = session.exerciseType
val exerciseSessionDuration = session.duration
val exerciseSessionCalories = session.calories
Log.i(
MainActivity.APP_TAG,
"Exercise type: $exerciseType, session type: $exerciseSessionType, duration: $exerciseSessionDuration, calories: $exerciseSessionCalories"
)
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
Example code for writing exercise data when using Samsung Health SDK for Android is as follows.
Writing running exercise data with Samsung Health SDK for Android
fun insertRunningExercise(healthDataStore: HealthDataStore) {
val fiveMinutesAsSeconds = 300L
val exerciseType = 1002
val calories = 73f
val distance = 1000f
val deviceId = HealthDeviceManager(healthDataStore).localDevice.uuid
val startTime = Instant.now().minusSeconds(fiveMinutesAsSeconds)
val endTime = Instant.now()
val timeOffset = TimeZone.getDefault().getOffset(endTime.toEpochMilli()).toLong()
val duration = Duration.between(startTime, endTime)
val healthDataResolver = HealthDataResolver(healthDataStore, null)
val liveData = createLiveData(
listOf(
ExerciseLiveData(
start_time = startTime.toEpochMilli(),
heart_rate = 144f,
speed = 1.6f
),
ExerciseLiveData(
start_time = startTime.plusSeconds(30).toEpochMilli(),
heart_rate = 146f,
speed = 1.8f
),
ExerciseLiveData(
start_time = startTime.plusSeconds(60).toEpochMilli(),
heart_rate = 146f,
speed = 1.9f
),
ExerciseLiveData(
start_time = startTime.plusSeconds(90).toEpochMilli(),
heart_rate = 152f,
speed = 2f
),
ExerciseLiveData(
start_time = startTime.plusSeconds(120).toEpochMilli(),
heart_rate = 154f,
speed = 2.1f
),
ExerciseLiveData(
start_time = startTime.plusSeconds(150).toEpochMilli(),
heart_rate = 161f,
speed = 2.2f
),
ExerciseLiveData(
start_time = startTime.plusSeconds(180).toEpochMilli(),
heart_rate = 159f,
speed = 2.1f
),
ExerciseLiveData(
start_time = startTime.plusSeconds(210).toEpochMilli(),
heart_rate = 160f,
speed = 2.2f
),
ExerciseLiveData(
start_time = startTime.plusSeconds(240).toEpochMilli(),
heart_rate = 159f,
speed = 2.1f
),
ExerciseLiveData(
start_time = startTime.plusSeconds(270).toEpochMilli(),
heart_rate = 161f,
speed = 2.2f
),
ExerciseLiveData(
start_time = startTime.plusSeconds(300).toEpochMilli(),
heart_rate = 160f,
speed = 2f
)
)
)
val healthData = HealthData().apply {
sourceDevice = deviceId
putLong(Exercise.START_TIME, startTime.toEpochMilli())
putLong(Exercise.END_TIME, endTime.toEpochMilli())
putLong(Exercise.TIME_OFFSET, timeOffset)
putInt(Exercise.EXERCISE_TYPE, exerciseType)
putLong(Exercise.DURATION, duration.toMillis())
putFloat(Exercise.CALORIE, calories)
putFloat(Exercise.DISTANCE, distance)
putBlob(Exercise.LIVE_DATA, liveData)
}
val insertRequest = HealthDataResolver.InsertRequest.Builder()
.setDataType(Exercise.HEALTH_DATA_TYPE)
.build()
insertRequest.addHealthData(healthData)
try {
val result = healthDataResolver.insert(insertRequest).await()
if (result.status == STATUS_SUCCESSFUL) {
Log.i(
MainActivity.APP_TAG,
"Inserted running exercise. Count of data: ${result.count}"
)
} else {
Log.i(MainActivity.APP_TAG, "Inserting failed")
}
} catch (e: Exception) {
e.printStackTrace()
}
}
private fun createLiveData(liveDataList: List<ExerciseLiveData>): ByteArray {
val zip = HealthDataUtil.getJsonBlob(liveDataList)
return zip
}
data class ExerciseLiveData(
val start_time: Long,
val heart_rate: Float,
val speed: Float
)
Example code for writing exercise data when using Samsung Health Data SDK is as follows. One exercise session of exercise data is writable.
Writing running exercise data with Samsung Health Data SDK
Floors climbed data is one of the activity health data types. It is displayed in the Activity Tracker in the Samsung Health app.
The corresponding floors climbed data types in Samsung Health SDK for Android and Samsung Health Data SDK are as following:
Samsung Health SDK for Android
Samsung Health Data SDK
HealthConstants.FloorsClimbed
FloorsClimbedType
To read today's floors climbed data when using Samsung Health SDK for Android, the following example code can be used.
Reading floors climbed data with Samsung Health SDK for Android
fun readTodayFloorsClimbed(healthDataStore: HealthDataStore) {
val startTime = LocalDate.now().atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli()
val endTime =
LocalDate.now().plusDays(1).atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli()
val healthDataResolver = HealthDataResolver(healthDataStore, null)
val readRequest = HealthDataResolver.ReadRequest.Builder()
.setDataType(FloorsClimbed.HEALTH_DATA_TYPE)
.setLocalTimeRange(
FloorsClimbed.START_TIME,
FloorsClimbed.TIME_OFFSET,
startTime,
endTime
)
.build()
try {
healthDataResolver.read(readRequest).setResultListener { result ->
try {
val iterator = result.iterator()
if (iterator.hasNext()) {
val healthData = iterator.next()
val totalCount = healthData.getFloat(FloorsClimbed.FLOOR)
Log.i(MainActivity.APP_TAG, "Today floors climbed: $totalCount")
} else {
Log.i(MainActivity.APP_TAG, "Today floors climbed: 0")
}
} finally {
result.close()
}
}
} catch (exception: Exception) {
exception.message?.let { Log.i(MainActivity.APP_TAG, it) }
}
}
When using Samsung Health Data SDK to read today's floors climbed data is as follows.
Reading floors climbed data with Samsung Health Data SDK
suspend fun readTodayFloorsClimbed(healthDataStore: HealthDataStore) {
val startTime = LocalDate.now().atStartOfDay()
val endTime = LocalDateTime.now()
val readRequest = DataType.FloorsClimbedType.TOTAL.requestBuilder
.setLocalTimeFilter(LocalTimeFilter.of(startTime, endTime))
.build()
try {
val readResult = healthDataStore.aggregateData(readRequest)
val data = readResult.dataList
val totalCount = if (data.isNotEmpty()) data.first().value else 0
Log.i(MainActivity.APP_TAG, "Today floors climbed: $totalCount")
} catch (e: Exception) {
e.printStackTrace()
}
}
To write floors climbed data when using Samsung Health SDK for Android, the following example code can be used.
Writing floors climbed data with Samsung Health SDK for Android
fun insertTodayFloorsClimbed(healthDataStore: HealthDataStore) {
val oneMinuteAsSeconds = 60L
val floor = 2f
val deviceId = HealthDeviceManager(healthDataStore).localDevice.uuid
val startTime = Instant.now().minusSeconds(oneMinuteAsSeconds).toEpochMilli()
val endTime = Instant.now().toEpochMilli()
val timeOffset = TimeZone.getDefault().getOffset(endTime).toLong()
val healthDataResolver = HealthDataResolver(healthDataStore, null)
val healthData = HealthData().apply {
sourceDevice = deviceId
putLong(FloorsClimbed.START_TIME, startTime)
putLong(FloorsClimbed.END_TIME, endTime)
putLong(FloorsClimbed.TIME_OFFSET, timeOffset)
putFloat(FloorsClimbed.FLOOR, floor)
}
val insertRequest = HealthDataResolver.InsertRequest.Builder()
.setDataType(FloorsClimbed.HEALTH_DATA_TYPE)
.build()
insertRequest.addHealthData(healthData)
try {
val result = healthDataResolver.insert(insertRequest).await()
if (result.status == STATUS_SUCCESSFUL) {
Log.i(
MainActivity.APP_TAG,
"Inserted floor climbed. Count of data: ${result.count}"
)
} else {
Log.i(MainActivity.APP_TAG, "Inserting failed")
}
} catch (e: Exception) {
e.printStackTrace()
}
}
When using Samsung Health Data SDK to write today's floors climbed data is as follows.
Writing floors climbed data with Samsung Health Data SDK
suspend fun insertTodayFloorClimbed(healthDataStore: HealthDataStore) {
val oneMinuteAsSeconds = 60L
val floor = 2f
val startTime = Instant.now().minusSeconds(oneMinuteAsSeconds)
val endTime = Instant.now()
try {
val healthDataPoint = HealthDataPoint.builder()
.setStartTime(startTime)
.setEndTime(endTime)
.addFieldData(DataType.FloorsClimbedType.FLOOR, floor)
.build()
val insertRequest = DataTypes.FLOORS_CLIMBED.insertDataRequestBuilder
.addData(healthDataPoint)
.build()
healthDataStore.insertData(insertRequest)
Log.i(MainActivity.APP_TAG, "Inserted floor climbed")
} catch (e: Exception) {
e.printStackTrace()
}
}
Nutrition
The Samsung Health app provides a Food Tracker that allows users to record and manage their eating data for each meal type, such as breakfast, lunch, and dinner.
The corresponding nutrition data types in Samsung Health SDK for Android and Samsung Health Data SDK are as following:
Samsung Health SDK for Android
Samsung Health Data SDK
HealthConstants.Nutrition
NutritionType
Here is an example code to read today's nutrition data when using Samsung Health SDK for Android.
Reading nutrition data with Samsung Health SDK for Android
fun readTodayNutrition(healthDataStore: HealthDataStore) {
val startTime = LocalDate.now().atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli()
val endTime =
LocalDate.now().plusDays(1).atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli()
val healthDataResolver = HealthDataResolver(healthDataStore, null)
val nutritionRequest = HealthDataResolver.ReadRequest.Builder()
.setDataType(Nutrition.HEALTH_DATA_TYPE)
.setLocalTimeRange(Nutrition.START_TIME, Nutrition.TIME_OFFSET, startTime, endTime)
.build()
try {
healthDataResolver.read(nutritionRequest).setResultListener { result ->
try {
val iterator = result.iterator()
iterator.forEach { healthData ->
val title = healthData.getString(Nutrition.TITLE)
val mealType = healthData.getInt(Nutrition.MEAL_TYPE)
val calories = healthData.getFloat(Nutrition.CALORIE)
Log.i(MainActivity.APP_TAG, "Today nutrition: $title, $mealType,
$calories")
}
} finally {
result.close()
}
}
} catch (exception: Exception) {
exception.message?.let { Log.i(MainActivity.APP_TAG, it) }
}
}
When using Samsung Health Data SDK to read today's nutrition data is as follows.
Reading nutrition data with Samsung Health Data SDK
suspend fun readTodayNutrition(healthDataStore: HealthDataStore) {
val startTime = LocalDate.now().atStartOfDay()
val endTime = LocalDateTime.now()
val readRequest = DataTypes.NUTRITION.readDataRequestBuilder
.setLocalTimeFilter(LocalTimeFilter.of(startTime, endTime))
.build()
try {
val readResult = healthDataStore.readData(readRequest)
if (readResult.dataList.isEmpty()) {
Log.i(MainActivity.APP_TAG, "No nutrition today")
return
}
readResult.dataList.forEach { healthData ->
val title = healthData.getValue(DataType.NutritionType.TITLE)
val mealType = healthData.getValue(DataType.NutritionType.MEAL_TYPE)
val calories = healthData.getValue(DataType.NutritionType.CALORIES)
Log.i(MainActivity.APP_TAG, "Today nutrition: $title, $mealType, $calories")
}
} catch (e: Exception) {
e.printStackTrace()
}
}
Here is an example code to write nutrition data when using Samsung Health SDK for Android.
Writing nutrition data with Samsung Health SDK for Android
fun insertNutrition(healthDataStore: HealthDataStore) {
val myDevice = HealthDeviceManager(healthDataStore)
val mealTitle = "Toast and coffee"
val calories = 66f
val totalFat = 0.8f
val saturatedFat = 0.1f
val protein = 2.1f
val carbohydrate = 11.9f
val totalSugars = 1f
val dietaryFiber = 0.6f
val sodium = 135f
val calcium = 40.3f
val iron = 0.78f
val potassium = 140f
//for females, age 19 - 50, according to https://nap.nationalacademies.org/catalog/11537/dietary-reference-intakes-the-essential-guide-to-nutrient-requirements
val referenceIndexForIronInMilligrams = 8.1f
// for age 19-50, refer to the link above.
val referenceIndexForCalciumInMilligrams = 1000f
val startTime = Instant.now().toEpochMilli()
val timeOffset = TimeZone.getDefault().getOffset(startTime).toLong()
val data = HealthData().apply {
sourceDevice = myDevice.localDevice.uuid
putLong(HealthConstants.Nutrition.START_TIME, startTime);
putLong(HealthConstants.Nutrition.TIME_OFFSET, timeOffset);
putInt(HealthConstants.Nutrition.MEAL_TYPE, MEAL_TYPE_BREAKFAST)
putString(HealthConstants.Nutrition.TITLE, mealTitle)
putFloat(HealthConstants.Nutrition.CALORIE, calories)
putFloat(HealthConstants.Nutrition.TOTAL_FAT, totalFat)
putFloat(HealthConstants.Nutrition.SATURATED_FAT, saturatedFat)
putFloat(HealthConstants.Nutrition.PROTEIN, protein)
putFloat(HealthConstants.Nutrition.CARBOHYDRATE, carbohydrate)
putFloat(HealthConstants.Nutrition.SUGAR, totalSugars)
putFloat(HealthConstants.Nutrition.DIETARY_FIBER, dietaryFiber)
putFloat(HealthConstants.Nutrition.SODIUM, sodium)
putFloat(HealthConstants.Nutrition.POTASSIUM, potassium)
val calciumAsPercentOfReferenceIntake =
calcium / referenceIndexForCalciumInMilligrams * 100
val ironInPercentOfReferenceIntake= iron / referenceIndexForIronInMilligrams * 100
putFloat(HealthConstants.Nutrition.CALCIUM, calciumAsPercentOfReferenceIntake)
putFloat(HealthConstants.Nutrition.IRON, ironInPercentOfReferenceIntake)
}
val insertRequest = HealthDataResolver.InsertRequest.Builder()
.setDataType(HealthConstants.Nutrition.HEALTH_DATA_TYPE)
.build()
val handler = Handler(Looper.getMainLooper())
val healthDataResolver = HealthDataResolver(healthDataStore, handler)
try {
insertRequest.addHealthData(data)
val insertResult = healthDataResolver.insert(insertRequest).await()
Log.i(TAG, "insertNutrition status: ${insertResult.status}")
} catch (e: Exception) {
e.printStackTrace()
}
}
When using Samsung Health Data SDK to write nutrition data is as follows.
Writing nutrition data with Samsung Health Data SDK
suspend fun insertNutrition(healthDataStore: HealthDataStore) {
val startTime = LocalDateTime.now()
val mealTitle = "Toast and coffee"
val calories = 66f
val totalFat = 0.8f
val saturatedFat = 0.1f
val protein = 2.1f
val carbohydrate = 11.9f
val sugar = 1f
val dietaryFiber = 0.6f
val sodium = 135f
val calcium = 40.3f
val iron = 0.78f
val potassium = 140f
try {
val healthDataPoint = HealthDataPoint.builder()
.setLocalStartTime(startTime)
.addFieldData(DataType.NutritionType.MEAL_TYPE, MealType.BREAKFAST)
.addFieldData(DataType.NutritionType.TITLE, mealTitle)
.addFieldData(DataType.NutritionType.CALORIES, calories)
.addFieldData(DataType.NutritionType.TOTAL_FAT, totalFat)
.addFieldData(DataType.NutritionType.SATURATED_FAT, saturatedFat)
.addFieldData(DataType.NutritionType.PROTEIN, protein)
.addFieldData(DataType.NutritionType.CARBOHYDRATE, carbohydrate)
.addFieldData(DataType.NutritionType.SUGAR, sugar)
.addFieldData(DataType.NutritionType.DIETARY_FIBER, dietaryFiber)
.addFieldData(DataType.NutritionType.SODIUM, sodium)
.addFieldData(DataType.NutritionType.CALCIUM, calcium)
.addFieldData(DataType.NutritionType.IRON, iron)
.addFieldData(DataType.NutritionType.POTASSIUM, potassium)
.build()
val insertDataRequest = DataTypes.NUTRITION.insertDataRequestBuilder
.addData(healthDataPoint)
.build()
healthDataStore.insertData(insertDataRequest)
} catch(e: Exception) {
e.printStackTrace()
}
}
Water intake
The data types of Samsung Health SDK for Android and Samsung Health Data SDK are as follows.
Samsung Health SDK for Android
Samsung Health Data SDK
HealthConstants.WaterIntake
WaterIntakeType
Example code for reading today's water intake data when using Samsung Health SDK for Android is as follows.
Reading water intake data with Samsung Health SDK for Android
fun readTodayTotalWaterIntake (
healthDataStore: HealthDataStore
) {
val startTime = LocalDate.now().atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli()
val endTime = LocalDateTime.now().toInstant(ZoneOffset.UTC).toEpochMilli()
val handler = Handler(Looper.getMainLooper())
val healthDataResolver = HealthDataResolver(healthDataStore, handler)
val waterIntakeId = "water_intake_sum"
val aggregateRequest = HealthDataResolver.AggregateRequest.Builder()
.addFunction(
HealthDataResolver.AggregateRequest.AggregateFunction.SUM,
HealthConstants.WaterIntake.AMOUNT,
waterIntakeId
)
.setLocalTimeRange(
HealthConstants.WaterIntake.START_TIME,
HealthConstants.WaterIntake.TIME_OFFSET, startTime, endTime
)
.setDataType(HealthConstants.WaterIntake.HEALTH_DATA_TYPE).build()
try {
healthDataResolver.aggregate(aggregateRequest).setResultListener { result ->
try {
result?.forEach { healthData ->
val waterIntakeSum = healthData.getFloat(waterIntakeId)
}
} finally {
result.close()
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
When using Samsung Health Data SDK to read today's water intake data is as follows.
Reading water intake data with Samsung Health Data SDK
suspend fun readTodayTotalWaterIntake(
healthDataStore: com.samsung.android.sdk.health.data.HealthDataStore
) {
val startTime = LocalDate.now().atStartOfDay()
val endTime = LocalDateTime.now()
val localTimeFilter = LocalTimeFilter.of(startTime, endTime)
val readRequest = DataType.WaterIntakeType.TOTAL.requestBuilder
.setLocalTimeFilter(localTimeFilter)
.build()
try {
val result = healthDataStore.aggregateData(readRequest)
result.dataList.lastOrNull()?.let { dataPoint ->
val waterIntake = dataPoint.value
}
} catch (e: Exception) {
e.printStackTrace()
}
}
Example code for writing water intake data when using Samsung Health SDK for Android is as follows.
Writing water intake data with Samsung Health SDK for Android
fun insertWaterIntake(healthDataStore: HealthDataStore) {
val myDevice = HealthDeviceManager(healthDataStore)
val waterAmountInMilliliters = 250f
val unitAmount = 250f
val startTime = Instant.now().toEpochMilli()
val timeOffset = TimeZone.getDefault().getOffset(startTime).toLong()
val data = HealthData().apply {
sourceDevice = myDevice.localDevice.uuid
putLong(HealthConstants.WaterIntake.START_TIME, startTime);
putLong(HealthConstants.WaterIntake.TIME_OFFSET, timeOffset);
putFloat(HealthConstants.WaterIntake.AMOUNT, waterAmountInMilliliters)
putFloat(HealthConstants.WaterIntake.UNIT_AMOUNT, unitAmount)
}
val insertRequest = HealthDataResolver.InsertRequest.Builder()
.setDataType(HealthConstants.WaterIntake.HEALTH_DATA_TYPE)
.build()
val handler = Handler(Looper.getMainLooper())
val healthDataResolver = HealthDataResolver(healthDataStore, handler)
try {
insertRequest.addHealthData(data)
val insertResult = healthDataResolver.insert(insertRequest).await()
Log.i(TAG, "insertWaterIntake status: ${insertResult.status}")
} catch (e: Exception) {
e.printStackTrace()
}
}
When using Samsung Health Data SDK to write water intake data is as follows.
Writing water intake data with Samsung Health Data SDK
suspend fun insertWaterIntake(healthDataStore: HealthDataStore) {
val startTime = LocalDateTime.now()
val waterAmountInMilliliters = 250f
try {
val healthDataPoint = HealthDataPoint.builder()
.setLocalStartTime(startTime)
.addFieldData(DataType.WaterIntakeType.AMOUNT, waterAmountInMilliliters)
.build()
val insertDataRequest = DataTypes.WATER_INTAKE.insertDataRequestBuilder
.addData(healthDataPoint)
.build()
healthDataStore.insertData(insertDataRequest)
} catch(e: Exception) {
e.printStackTrace()
}
}
Sleep and sleep stage
The data types of Samsung Health SDK for Android and Samsung Health Data SDK are as follows.
Samsung Health SDK for Android
Samsung Health Data SDK
HealthConstants.Sleep HealthConstants.SleepStage
SleepType
Code for reading the last night's sleep data when using Samsung Health SDK for Android is as follows.
Reading the last night's sleep data with Samsung Health SDK for Android
fun readLastSleep(
healthDataStore: HealthDataStore
) {
val handler = Handler(Looper.getMainLooper())
val healthDataResolver = HealthDataResolver(healthDataStore, handler)
val resultCount = 1
val resultOffset = 0
val request: HealthDataResolver.ReadRequest =
HealthDataResolver.ReadRequest.Builder()
.setDataType(HealthConstants.Sleep.HEALTH_DATA_TYPE)
.setSort(HealthConstants.Sleep.START_TIME, SortOrder.DESC)
.setResultCount(resultOffset, resultCount)
.build()
try {
healthDataResolver.read(request).setResultListener { result ->
try {
result.lastOrNull()?.let { healthData ->
val sleepId = healthData.getString(HealthConstants.Sleep.UUID)
val sleepStartTime =
Instant.ofEpochMilli(healthData.getLong(HealthConstants.Sleep.START_TIME))
val sleepEndTime =
Instant.ofEpochMilli(healthData.getLong(HealthConstants.Sleep.END_TIME))
readSleepStagesForSleepId(healthDataStore, sleepId)
}
} finally {
result.close()
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
fun readSleepStagesForSleepId(
healthDataStore: HealthDataStore,
sleepId: String
) {
val handler = Handler(Looper.getMainLooper())
val healthDataResolver = HealthDataResolver(healthDataStore, handler)
val request: HealthDataResolver.ReadRequest =
HealthDataResolver.ReadRequest.Builder()
.setDataType(HealthConstants.SleepStage.HEALTH_DATA_TYPE)
.setFilter(Filter.eq(HealthConstants.SleepStage.SLEEP_ID, sleepId))
.build()
try {
healthDataResolver.read(request).setResultListener { result ->
try {
result?.forEach { sleepStageData ->
val sleepStageName =
sleepStageNameById(sleepStageData.getInt(HealthConstants.SleepStage.STAGE))
val sleepStageStartTime =
Instant.ofEpochMilli(sleepStageData.getLong(HealthConstants.SleepStage.START_TIME))
val sleepStageEndTime =
Instant.ofEpochMilli(sleepStageData.getLong(HealthConstants.SleepStage.END_TIME))
}
} finally {
result.close()
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
fun sleepStageNameById(id: Int): String {
return when (id) {
HealthConstants.SleepStage.STAGE_AWAKE -> "AWAKE"
HealthConstants.SleepStage.STAGE_DEEP -> "DEEP"
HealthConstants.SleepStage.STAGE_LIGHT -> "LIGHT"
HealthConstants.SleepStage.STAGE_REM -> "REM"
else -> ""
}
}
When using Samsung Health Data SDK to read the last night's sleep data is as follows.
Reading the last night's sleep data with Samsung Health Data SDK
suspend fun readSleepTotalDuration(
healthDataStore: HealthDataStore
) {
val daysBackOffset = 400L
val startTime =
LocalDate.now()
.minusDays(daysBackOffset)
val endTime = LocalDate.now()
val localDateFilter = LocalDateFilter.of(startTime, endTime)
val request = DataType.SleepType.TOTAL_DURATION.requestBuilder
.setLocalDateFilter(localDateFilter)
.build()
try {
val result = healthDataStore.aggregateData(request)
result.dataList.forEach { aggregatedData ->
val startTime = aggregatedData.startTime
val endTime = aggregatedData.endTime
val totalDuration = aggregatedData.value
}
} catch (e: Exception) {
e.printStackTrace()
}
}
suspend fun readLastSleep(
healthDataStore: HealthDataStore
) {
val resultCount = 1
val readRequest = DataTypes.SLEEP.readDataRequestBuilder
.setOrdering(Ordering.DESC)
.setLimit(resultCount)
.build()
try {
val result = healthDataStore.readData(readRequest)
result.dataList.lastOrNull()?.let { sleepData ->
val sleepId = sleepData.uid
val sleepStartTime = sleepData.startTime
val sleepEndTime = sleepData.endTime
val sleepSessions = sleepData.getValue(DataType.SleepType.SESSIONS)
sleepSessions?.forEach { sleepSession ->
val sessionDuration = sleepSession.duration
val sessionStartTime = sleepSession.startTime
val sessionEndTime = sleepSession.endTime
val sleepStages = sleepSession.stages
sleepStages?.forEach { sleepStage ->
val sleepStageName = sleepStage.stage.name
val sleepStageStartTime = sleepStage.startTime
val sleepStageEndTime = sleepStage.endTime
}
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
Code for writing sleep data when using Samsung Health SDK for Android is as follows.
Writing the last night's sleep data with Samsung Health SDK for Android
The corresponding weight data types in Samsung Health SDK for Android and Samsung Health Data SDK are as following:
Samsung Health SDK for Android
Samsung Health Data SDK
HealthConstants.Weight
BodyCompositionType
To read the latest weight data when using Samsung Health SDK for Android, the following example code can be used.
Reading the last weight data with Samsung Health SDK for Android
fun readLatestWeight(
healthDataStore: HealthDataStore
) {
val resultCount = 1
val resultOffset = 0
val handler = Handler(Looper.getMainLooper())
val healthDataResolver = HealthDataResolver(healthDataStore, handler)
val request: HealthDataResolver.ReadRequest =
HealthDataResolver.ReadRequest.Builder()
.setDataType(HealthConstants.Weight.HEALTH_DATA_TYPE)
.setSort(HealthConstants.OxygenSaturation.START_TIME, SortOrder.DESC)
.setResultCount(resultOffset, resultCount)
.build()
try {
healthDataResolver.read(request).setResultListener { result ->
try {
result.lastOrNull()?.let { healthData ->
val measurementStartTime =
Instant.ofEpochMilli(healthData.getLong(HealthConstants.Weight.START_TIME))
val weight = healthData.getFloat(HealthConstants.Weight.WEIGHT)
val bodyFat = healthData.getFloat(HealthConstants.Weight.BODY_FAT)
}
} finally {
result.close()
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
When using Samsung Health Data SDK to read the latest weight data is as follows.
Reading the last weight data with Samsung Health Data SDK
suspend fun readLatestWeight(
healthDataStore: HealthDataStore
) {
val resultCount = 1
val readRequest = DataTypes.BODY_COMPOSITION.readDataRequestBuilder
.setOrdering(Ordering.DESC)
.setLimit(resultCount)
.build()
try {
val result = healthDataStore.readData(readRequest)
result.dataList.lastOrNull()?.let { dataPoint ->
val weight = dataPoint.getValue(DataType.BodyCompositionType.WEIGHT)
val bodyFat = dataPoint.getValue(DataType.BodyCompositionType.BODY_FAT)
val measurementStartTime = dataPoint.startTime
}
} catch (e: Exception) {
e.printStackTrace()
}
}
Here is an example code to write weight data when using Samsung Health SDK for Android.
Writing weight data with Samsung Health SDK for Android
fun insertWeightData(
healthDataStore: HealthDataStore
) {
val weight = 75F
val zoneId = ZoneOffset.systemDefault()
val startTime = LocalDate.now().atTime(9, 0).atZone(zoneId).toInstant().toEpochMilli()
val timeOffset = TimeZone.getDefault().getOffset(startTime).toLong()
val mHealthDataResolver =
HealthDataResolver(healthDataStore, Handler(Looper.getMainLooper()))
val healthDeviceManager = HealthDeviceManager(healthDataStore)
val data = HealthData().apply {
putLong(HealthConstants.Weight.START_TIME, startTime)
putLong(HealthConstants.Weight.TIME_OFFSET, timeOffset)
putFloat(HealthConstants.Weight.WEIGHT, weight)
// Register local device as the source of data
sourceDevice = healthDeviceManager.localDevice.uuid
}
try {
val insertRequest = InsertRequest.Builder()
.setDataType(HealthConstants.Weight.HEALTH_DATA_TYPE)
.build()
insertRequest.addHealthData(data)
val result = mHealthDataResolver.insert(insertRequest).await()
Log.i(MainActivity.APP_TAG, "insert result status: ${result.status}")
} catch (e: Exception) {
e.printStackTrace()
}
}
Writing weight data with Samsung Health Data SDK
suspend fun insertWeightData(
healthDataStore: HealthDataStore
) {
val weight = 75F
val localDateTime = LocalDate.now().atTime(9, 0)
val zoneId = ZoneOffset.systemDefault()
val zoneOffset = zoneId.rules.getOffset(localDateTime)
try {
val healthDataPoint = HealthDataPoint.builder()
.addFieldData(DataType.BodyCompositionType.WEIGHT, weight)
.setLocalStartTime(localDateTime, zoneOffset)
.build()
val insertRequest = DataTypes.BODY_COMPOSITION.insertDataRequestBuilder
.addData(healthDataPoint)
.build()
healthDataStore.insertData(insertRequest)
} catch (e: Exception) {
e.printStackTrace()
}
}
Heart rate
The corresponding heart rate data types in Samsung Health SDK for Android and Samsung Health Data SDK are as following:
Samsung Health SDK for Android
Samsung Health Data SDK
HealthConstants.HeartRate
HeartRateType
Example code for reading today's heart rate data when using Samsung Health SDK for Android is as follows.
Reading today's heart rate data with Samsung Health SDK for Android
class ReadHeartRate {
fun readTodayHeartRate(
healthDataStore: HealthDataStore
) {
val startTime = LocalDate.now().atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli()
val endTime = LocalDateTime.now().toInstant(ZoneOffset.UTC).toEpochMilli()
val handler = Handler(Looper.getMainLooper())
val healthDataResolver = HealthDataResolver(healthDataStore, handler)
val request: HealthDataResolver.ReadRequest =
HealthDataResolver.ReadRequest.Builder()
.setDataType(HealthConstants.HeartRate.HEALTH_DATA_TYPE)
.setLocalTimeRange(
HealthConstants.HeartRate.START_TIME,
HealthConstants.HeartRate.TIME_OFFSET, startTime, endTime
).build()
try {
healthDataResolver.read(request).setResultListener { result ->
try {
result?.forEach { healthData ->
val heartRate = healthData.getFloat(HealthConstants.HeartRate.HEART_RATE)
val measurementStartTime =
Instant.ofEpochMilli(healthData.getLong(HealthConstants.HeartRate.START_TIME))
val measurementEndTime =
Instant.ofEpochMilli(healthData.getLong(HealthConstants.HeartRate.END_TIME))
val binningData = healthData.getBlob(HealthConstants.HeartRate.BINNING_DATA)
val liveDataList = HealthDataUtil.getStructuredDataList(
binningData,
HeartRateLiveData::class.java
)
liveDataList.forEach { liveDataPoint ->
val heartRate = liveDataPoint.heart_rate
val startTime = Instant.ofEpochMilli(liveDataPoint.start_time)
}
}
} finally {
result.close()
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
data class HeartRateLiveData(
val heart_rate: Float,
val heart_rate_min: Float,
val heart_rate_max: Float,
val start_time: Long,
val end_time: Long
)
When using Samsung Health Data SDK to read today's heart rate data is as follows.
Reading today's heart rate data with Samsung Health Data SDK
suspend fun readTodayHeartRate (
healthDataStore: HealthDataStore
) {
val startTime = LocalDate.now().atStartOfDay()
val endTime = LocalDateTime.now()
val localTimeFilter = LocalTimeFilter.of(startTime, endTime)
val readRequest = DataTypes.HEART_RATE.readDataRequestBuilder
.setLocalTimeFilter(localTimeFilter)
.build()
try {
val result = healthDataStore.readData(readRequest)
result.dataList.forEach { dataPoint ->
val startTime = dataPoint.startTime
val endTime = dataPoint.endTime
val heartRate = dataPoint.getValue(DataType.HeartRateType.HEART_RATE)
val heartRateSeriesData = dataPoint.getValue(DataType.HeartRateType.SERIES_DATA)
heartRateSeriesData?.forEach { seriesData ->
val startTime = seriesData.startTime
val heartRate = seriesData.heartRate
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
To write heart rate data when using Samsung Health SDK for Android, the following example code can be used.
Writing heart rate data with Samsung Health SDK for Android
fun insertTodayHeartRate(healthDataStore: HealthDataStore) {
val tenMinutesAsSeconds = 600L
val heartRate = 76f
val heartBeatCount = 1
val deviceId = HealthDeviceManager(healthDataStore).localDevice.uuid
val startTime = Instant.now().minusSeconds(tenMinutesAsSeconds).toEpochMilli()
val endTime = Instant.now().toEpochMilli()
val timeOffset = TimeZone.getDefault().getOffset(endTime).toLong()
val healthDataResolver = HealthDataResolver(healthDataStore, null)
val healthData = HealthData().apply {
sourceDevice = deviceId
putLong(HeartRate.START_TIME, startTime)
putLong(HeartRate.END_TIME, endTime)
putLong(HeartRate.TIME_OFFSET, timeOffset)
putFloat(HeartRate.HEART_RATE, heartRate)
putInt(HeartRate.HEART_BEAT_COUNT, heartBeatCount)
}
val insertRequest = HealthDataResolver.InsertRequest.Builder()
.setDataType(HeartRate.HEALTH_DATA_TYPE)
.build()
insertRequest.addHealthData(healthData)
try {
val result = healthDataResolver.insert(insertRequest).await()
if (result.status == STATUS_SUCCESSFUL) {
Log.i(MainActivity.APP_TAG, "Inserted heart rate. Count of data: ${result.count}")
} else {
Log.i(MainActivity.APP_TAG, "Inserting failed")
}
} catch (e: Exception) {
e.printStackTrace()
}
}
When using Samsung Health Data SDK to write heart rate data is as follows.
Writing heart rate data with Samsung Health Data SDK
suspend fun insertTodayHeartRate(healthDataStore: HealthDataStore) {
val tenMinutesAsSeconds = 600L
val heartRate = 76f
val startTime = LocalDateTime.now().minusSeconds(tenMinutesAsSeconds)
val endTime = LocalDateTime.now()
try {
val healthDataPoint = HealthDataPoint.builder()
.setLocalStartTime(startTime)
.setLocalEndTime(endTime)
.addFieldData(DataType.HeartRateType.HEART_RATE, heartRate)
.build()
val insertRequest = DataTypes.HEART_RATE.insertDataRequestBuilder
.addData(healthDataPoint)
.build()
healthDataStore.insertData(insertRequest)
Log.i(MainActivity.APP_TAG, "Inserted heart rate")
} catch (e: Exception) {
e.printStackTrace()
}
}
Blood glucose
The corresponding blood glucose data types in Samsung Health SDK for Android and Samsung Health Data SDK are as following:
Samsung Health SDK for Android
Samsung Health Data SDK
HealthConstants.BloodGlucose
BloodGlucoseType
Here is an example code to read today's blood glucose data when using Samsung Health SDK for Android.
Reading today's blood glucose data with Samsung Health SDK for Android
fun readTodayBloodGlucose (
healthDataStore: HealthDataStore
) {
val startTime = LocalDate.now().atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli()
val endTime = LocalDateTime.now().toInstant(ZoneOffset.UTC).toEpochMilli()
val handler = Handler(Looper.getMainLooper())
val healthDataResolver = HealthDataResolver(healthDataStore, handler)
val request: HealthDataResolver.ReadRequest =
HealthDataResolver.ReadRequest.Builder()
.setDataType(HealthConstants.BloodGlucose.HEALTH_DATA_TYPE)
.setLocalTimeRange(
HealthConstants.OxygenSaturation.START_TIME,
HealthConstants.OxygenSaturation.TIME_OFFSET, startTime, endTime
).build()
try {
healthDataResolver.read(request).setResultListener { result ->
try {
result.forEach { healthData ->
val measurementStartTime =
Instant.ofEpochMilli(healthData.getLong(HealthConstants.BloodGlucose.START_TIME))
val bloodGlucose = healthData.getFloat(HealthConstants.BloodGlucose.GLUCOSE)
//Refer to the documentation for MEAL_TYPE, MEASUREMENT_TYPE, SAMPLE_SOURCE_TYPE mapping
val mealType = healthData.getInt(HealthConstants.BloodGlucose.MEAL_TYPE)
val measurementType =
healthData.getInt(HealthConstants.BloodGlucose.MEASUREMENT_TYPE)
val sampleSourceType =
healthData.getInt(HealthConstants.BloodGlucose.SAMPLE_SOURCE_TYPE)
}
} finally {
result.close()
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
When using Samsung Health Data SDK to read today's blood glucose data is as follows.
Reading today's blood glucose data with Samsung Health Data SDK
fun readTodayBloodGlucose(
healthDataStore: HealthDataStore
) {
val startTime = LocalDate.now().atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli()
val endTime = LocalDateTime.now().toInstant(ZoneOffset.UTC).toEpochMilli()
val handler = Handler(Looper.getMainLooper())
val healthDataResolver = HealthDataResolver(healthDataStore, handler)
val request: HealthDataResolver.ReadRequest =
HealthDataResolver.ReadRequest.Builder()
.setDataType(HealthConstants.BloodGlucose.HEALTH_DATA_TYPE)
.setLocalTimeRange(
HealthConstants.OxygenSaturation.START_TIME,
HealthConstants.OxygenSaturation.TIME_OFFSET, startTime, endTime
).build()
try {
healthDataResolver.read(request).setResultListener { result ->
try {
result.forEach { healthData ->
val measurementStartTime =
Instant.ofEpochMilli(healthData.getLong(HealthConstants.BloodGlucose.START_TIME))
val bloodGlucose = healthData.getFloat(HealthConstants.BloodGlucose.GLUCOSE)
//Refer to the documentation for MEAL_TYPE, MEASUREMENT_TYPE, SAMPLE_SOURCE_TYPE mapping
val mealType = healthData.getInt(HealthConstants.BloodGlucose.MEAL_TYPE)
val measurementType =
healthData.getInt(HealthConstants.BloodGlucose.MEASUREMENT_TYPE)
val sampleSourceType =
healthData.getInt(HealthConstants.BloodGlucose.SAMPLE_SOURCE_TYPE)
}
} finally {
result.close()
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
Code for writing sleep data when using Samsung Health SDK for Android is as follows.
Writing blood glucose data with Samsung Health SDK for Android
fun insertBloodGlucoseData(healthDataStore: HealthDataStore) {
val handler = Handler(Looper.getMainLooper())
val healthDataResolver = HealthDataResolver(healthDataStore, handler)
val healthDeviceManager = HealthDeviceManager(healthDataStore)
val tenMinutesAsSeconds = 600L
val startTime = Instant.now().minusSeconds(tenMinutesAsSeconds)
val timeOffset = TimeZone.getDefault().getOffset(startTime.toEpochMilli())
val glucose = 4.8f
val bloodGlucoseData = HealthData().apply {
sourceDevice = healthDeviceManager.localDevice.uuid
putLong(
HealthConstants.BloodPressure.START_TIME, startTime.toEpochMilli()
)
putLong(HealthConstants.BloodGlucose.TIME_OFFSET, timeOffset.toLong())
putFloat(HealthConstants.BloodGlucose.GLUCOSE, glucose)
putInt(
HealthConstants.BloodGlucose.MEASUREMENT_TYPE,
HealthConstants.BloodGlucose.MEASUREMENT_TYPE_WHOLE_BLOOD
)
putInt(
HealthConstants.BloodGlucose.MEAL_TYPE,
HealthConstants.BloodGlucose.MEAL_TYPE_FASTING
)
}
val insertRequest = InsertRequest.Builder()
.setDataType(HealthConstants.BloodGlucose.HEALTH_DATA_TYPE)
.build()
insertRequest.addHealthData(bloodGlucoseData)
try {
val insertResult = healthDataResolver.insert(insertRequest).await()
if (insertResult.status != BaseResult.STATUS_SUCCESSFUL) {
Log.i(
MainActivity.APP_TAG,
"Error inserting blood glucose data. Error code: ${insertResult.status}"
)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
Example code for writing blood glucose data when using Samsung Health Data SDK is as follows.
Writing blood glucose data with Samsung Health Data SDK
suspend fun insertBloodGlucoseData(healthDataStore: HealthDataStore) {
val startTime = LocalDateTime.now().minusMinutes(10)
val glucose = 4.8f
try {
val healthDataPoint = HealthDataPoint.builder()
.setLocalStartTime(startTime)
.setLocalEndTime(startTime)
.addFieldData(DataType.BloodGlucoseType.GLUCOSE_LEVEL, glucose)
.addFieldData(
DataType.BloodGlucoseType.MEASUREMENT_TYPE,
DataType.BloodGlucoseType.MeasurementType.WHOLE_BLOOD
)
.addFieldData(
DataType.BloodGlucoseType.MEAL_STATUS,
DataType.BloodGlucoseType.MealStatus.FASTING
)
.build()
val insertDataRequest = DataTypes.BLOOD_GLUCOSE.insertDataRequestBuilder
.addData(healthDataPoint)
.build()
healthDataStore.insertData(insertDataRequest)
} catch (e: Exception) {
e.printStackTrace()
}
}
Blood oxygen
The corresponding blood oxygen data types in Samsung Health SDK for Android and Samsung Health Data SDK are as following:
Samsung Health SDK for Android
Samsung Health Data SDK
HealthConstants.OxygenSaturationType
BloodOxygenType
Example code for reading the latest blood oxygen data when using Samsung Health SDK for Android is as follows.
Reading the latest blood oxygen data with Samsung Health SDK for Android
fun readLatestBloodOxygen(
healthDataStore: HealthDataStore
) {
val resultOffset = 0;
val resultCount = 1
val handler = Handler(Looper.getMainLooper())
val healthDataResolver = HealthDataResolver(healthDataStore, handler)
val request: HealthDataResolver.ReadRequest =
HealthDataResolver.ReadRequest.Builder()
.setDataType(HealthConstants.OxygenSaturation.HEALTH_DATA_TYPE)
.setSort(HealthConstants.OxygenSaturation.START_TIME, SortOrder.DESC)
.setResultCount(resultOffset, resultCount)
.build()
try {
healthDataResolver.read(request).setResultListener { result ->
try {
result.lastOrNull()?.let { healthData ->
val bloodOxygen = healthData.getFloat(HealthConstants.OxygenSaturation.SPO2)
val measurementStartTime =
Instant.ofEpochMilli(healthData.getLong(HealthConstants.OxygenSaturation.START_TIME))
}
} finally {
result.close()
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
When using Samsung Health Data SDK to read the latest blood oxygen data is as follows.
Reading the latest blood oxygen data with Samsung Health Data SDK
suspend fun readLatestBloodOxygen(
healthDataStore: HealthDataStore
) {
val resultCount = 1
val readRequest = DataTypes.BLOOD_OXYGEN.readDataRequestBuilder
.setOrdering(Ordering.DESC)
.setLimit(resultCount)
.build()
try {
val result = healthDataStore.readData(readRequest)
result.dataList.lastOrNull()?.let { dataPoint ->
val bloodOxygen = dataPoint.getValue(DataType.BloodOxygenType.OXYGEN_SATURATION)
val measurementStartTime = dataPoint.startTime
}
} catch (e: Exception) {
e.printStackTrace()
}
}
Here is an example code to write blood oxygen data when using Samsung Health SDK for Android.
Writing blood oxygen data with Samsung Health SDK for Android
fun insertBloodOxygenData(
healthDataStore: HealthDataStore
) {
val bloodOxygen = 98F
val tenMinutesAsSeconds = 10L * 60L
val zoneId = ZoneOffset.systemDefault()
val time = LocalDateTime.now().minusSeconds(tenMinutesAsSeconds).atZone(zoneId)
.toInstant().toEpochMilli()
val timeOffset = TimeZone.getDefault().getOffset(time).toLong()
val mHealthDataResolver =
HealthDataResolver(healthDataStore, Handler(Looper.getMainLooper()))
val healthDeviceManager = HealthDeviceManager(healthDataStore)
val data = HealthData().apply {
putLong(HealthConstants.OxygenSaturation.START_TIME, time)
putLong(HealthConstants.OxygenSaturation.END_TIME, time)
putLong(HealthConstants.OxygenSaturation.TIME_OFFSET, timeOffset)
putFloat(HealthConstants.OxygenSaturation.SPO2, bloodOxygen)
// Register local device as the source of data
sourceDevice = healthDeviceManager.localDevice.uuid
}
try {
val insertRequest = InsertRequest.Builder()
.setDataType(HealthConstants.OxygenSaturation.HEALTH_DATA_TYPE)
.build()
insertRequest.addHealthData(data)
val result = mHealthDataResolver.insert(insertRequest).await()
Log.i(MainActivity.APP_TAG, "insert result status: ${result.status}")
} catch (e: Exception) {
e.printStackTrace()
}
}
Example code for writing blood oxygen data when using Samsung Health Data SDK is as follows.
Writing blood oxygen data with Samsung Health Data SDK
suspend fun insertBloodOxygenData(
healthDataStore: HealthDataStore
) {
val bloodOxygen = 98F
val tenMinutesAsSeconds = 10L * 60L
val time = LocalDateTime.now().minusSeconds(tenMinutesAsSeconds)
val zoneId = ZoneOffset.systemDefault()
val zoneOffset = zoneId.rules.getOffset(time)
try {
val healthDataPoint = HealthDataPoint.builder()
.addFieldData(DataType.BloodOxygenType.OXYGEN_SATURATION, bloodOxygen)
.setLocalStartTime(time, zoneOffset)
.setLocalEndTime(time, zoneOffset)
.build()
val insertRequest = DataTypes.BLOOD_OXYGEN.insertDataRequestBuilder
.addData(healthDataPoint)
.build()
healthDataStore.insertData(insertRequest)
} catch (e: Exception) {
e.printStackTrace()
}
}
Blood pressure
The corresponding blood pressure data types in Samsung Health SDK for Android and Samsung Health Data SDK are as following:
Samsung Health SDK for Android
Samsung Health Data SDK
HealthConstants.BloodPressure
BloodPressureType
Code for reading the latest blood pressure data when using Samsung Health SDK for Android is as follows.
Reading the latest blood pressure data with Samsung Health SDK for Android
fun readLatestBloodPressure(
healthDataStore: HealthDataStore
) {
val resultOffset = 0;
val resultCount = 1
val handler = Handler(Looper.getMainLooper())
val healthDataResolver = HealthDataResolver(healthDataStore, handler)
val request: HealthDataResolver.ReadRequest =
HealthDataResolver.ReadRequest.Builder()
.setDataType(HealthConstants.BloodPressure.HEALTH_DATA_TYPE)
.setSort(HealthConstants.BloodPressure.START_TIME, SortOrder.DESC)
.setResultCount(resultOffset, resultCount)
.build()
try {
healthDataResolver.read(request).setResultListener { result ->
try {
result?.lastOrNull()?.let { healthData ->
val startTime =
Instant.ofEpochMilli(healthData.getLong(HealthConstants.BloodPressure.START_TIME))
val systolicPressure =
healthData.getFloat(HealthConstants.BloodPressure.SYSTOLIC)
val diastolicPressure =
healthData.getFloat(HealthConstants.BloodPressure.DIASTOLIC)
val mean = healthData.getFloat(HealthConstants.BloodPressure.MEAN)
val pulse = healthData.getInt(HealthConstants.BloodPressure.PULSE)
val sourcePackageName =
healthData.getString(HealthConstants.Common.PACKAGE_NAME)
val sourceDeviceID =
healthData.getString(HealthConstants.Common.DEVICE_UUID)
}
} finally {
result.close()
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
When using Samsung Health Data SDK to read the latest blood pressure data is as follows.
Reading the latest blood pressure data with Samsung Health Data SDK
suspend fun readLatestBloodPressure(
healthDataStore: HealthDataStore
) {
val resultCount = 1
val readRequest = DataTypes.BLOOD_PRESSURE.readDataRequestBuilder
.setOrdering(Ordering.DESC)
.setLimit(resultCount)
.build()
try {
val result = healthDataStore.readData(readRequest)
result.dataList.lastOrNull()?.let { dataPoint ->
val startTime = dataPoint.startTime
val systolicPressure = dataPoint.getValue(DataType.BloodPressureType.SYSTOLIC)
val diastolicPressure = dataPoint.getValue(DataType.BloodPressureType.DIASTOLIC)
val mean = dataPoint.getValue(DataType.BloodPressureType.MEAN)
val pulse = dataPoint.getValue(DataType.BloodPressureType.PULSE_RATE)
val sourcePackageName = dataPoint.dataSource?.appId
val sourceDeviceId = dataPoint.dataSource?.deviceId
}
} catch (e: Exception) {
e.printStackTrace()
}
}
Code for writing blood pressure data when using Samsung Health SDK for Android is as follows.
Writing blood pressure data with Samsung Health SDK for Android
fun insertBloodPressureData(healthDataStore: HealthDataStore) {
val handler = Handler(Looper.getMainLooper())
val healthDataResolver = HealthDataResolver(healthDataStore, handler)
val healthDeviceManager = HealthDeviceManager(healthDataStore)
val tenMinutesAsSeconds = 600L
val startTime = Instant.now().minusSeconds(tenMinutesAsSeconds)
val timeOffset = TimeZone.getDefault().getOffset(startTime.toEpochMilli())
val systolic = 119f
val diastolic = 87f
val mean = 0f
val bloodPressureData = HealthData().apply {
sourceDevice = healthDeviceManager.localDevice.uuid
putLong(HealthConstants.BloodPressure.START_TIME, startTime.toEpochMilli())
putLong(HealthConstants.BloodPressure.TIME_OFFSET, timeOffset.toLong())
putFloat(HealthConstants.BloodPressure.SYSTOLIC, systolic)
putFloat(HealthConstants.BloodPressure.DIASTOLIC, diastolic)
putFloat(HealthConstants.BloodPressure.MEAN, mean)
}
val insertRequest = InsertRequest.Builder()
.setDataType(HealthConstants.BloodPressure.HEALTH_DATA_TYPE)
.build()
insertRequest.addHealthData(bloodPressureData)
try {
val insertResult = healthDataResolver.insert(insertRequest).await()
if (insertResult.status != BaseResult.STATUS_SUCCESSFUL) {
Log.i(
MainActivity.APP_TAG,
"Error inserting blood pressure data. Error code: ${insertResult.status}"
)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
Example code for writing blood pressure data when using Samsung Health Data SDK is as follows.
Writing blood pressure data with Samsung Health Data SDK
suspend fun insertBloodPressureData(healthDataStore: HealthDataStore) {
val startTime = LocalDateTime.now().minusMinutes(10)
val systolic = 119f
val diastolic = 87f
val mean = 0f
try {
val healthDataPoint = HealthDataPoint.builder()
.setLocalStartTime(startTime)
.addFieldData(DataType.BloodPressureType.SYSTOLIC, systolic)
.addFieldData(DataType.BloodPressureType.DIASTOLIC, diastolic)
.addFieldData(DataType.BloodPressureType.MEAN, mean)
.build()
val insertDataRequest = DataTypes.BLOOD_PRESSURE.insertDataRequestBuilder
.addData(healthDataPoint)
.build()
healthDataStore.insertData(insertDataRequest)
} catch (e: Exception) {
e.printStackTrace()
}
}
Body Temperature
The corresponding body temperature data types in Samsung Health SDK for Android and Samsung Health Data SDK are as following:
Samsung Health SDK for Android
Samsung Health Data SDK
HealthConstants.BodyTemperature
BodyTemperatureType
Here is an example of code that reads today's body temperature data when using Samsung Health SDK for Android.
Reading today's body temperature data with Samsung Health SDK for Android
fun readTodayBodyTemperature(
healthDataStore: HealthDataStore
) {
val startTime = LocalDate.now().atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli()
val endTime = LocalDateTime.now().toInstant(ZoneOffset.UTC).toEpochMilli()
val handler = Handler(Looper.getMainLooper())
val healthDataResolver = HealthDataResolver(healthDataStore, handler)
val readRequest: HealthDataResolver.ReadRequest =
HealthDataResolver.ReadRequest.Builder()
.setDataType(HealthConstants.BodyTemperature.HEALTH_DATA_TYPE)
.setLocalTimeRange(
HealthConstants.BodyTemperature.START_TIME,
HealthConstants.BodyTemperature.TIME_OFFSET,
startTime,
endTime
).build()
try {
healthDataResolver.read(readRequest).setResultListener { result ->
try {
result.lastOrNull()?.let { healthData ->
val measurementStartTime =
Date(healthData.getLong(HealthConstants.BodyTemperature.START_TIME))
val bodyTemperature =
healthData.getFloat(HealthConstants.BodyTemperature.TEMPERATURE)
}
} finally {
result.close()
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
When using Samsung Health Data SDK to read today's body temperature data is as follows.
Reading today's body temperature Samsung Health Data SDK
suspend fun readTodayBodyTemperature(
healthDataStore: com.samsung.android.sdk.health.data.HealthDataStore
) {
val startTime = LocalDate.now().atStartOfDay()
val endTime = LocalDateTime.now()
val localTimeFilter = LocalTimeFilter.of(startTime, endTime)
val readRequest = DataTypes.BODY_TEMPERATURE.readDataRequestBuilder
.setLocalTimeFilter(localTimeFilter)
.build()
try {
val result = healthDataStore.readData(readRequest)
result.dataList.lastOrNull()?.let { dataPoint ->
val measurementStartTime = dataPoint.startTime
val bodyTemperature =
dataPoint.getValue(DataType.BodyTemperatureType.BODY_TEMPERATURE)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
Example code for writing body temperature data when using Samsung Health SDK for Android is as follows.
Writing body temperature data with Samsung Health SDK for Android
fun insertBodyTemperatureData(
healthDataStore: HealthDataStore
) {
val bodyTemperature = 37F
val tenMinutesAsSeconds = 10L * 60L
val zoneId = ZoneOffset.systemDefault()
val startTime = LocalDateTime.now().minusSeconds(tenMinutesAsSeconds).atZone(zoneId)
.toInstant().toEpochMilli()
val timeOffset = TimeZone.getDefault().getOffset(startTime).toLong()
val mHealthDataResolver =
HealthDataResolver(healthDataStore, Handler(Looper.getMainLooper()))
val healthDeviceManager = HealthDeviceManager(healthDataStore)
val data = HealthData().apply {
putLong(HealthConstants.BodyTemperature.START_TIME, startTime)
putLong(HealthConstants.BodyTemperature.TIME_OFFSET, timeOffset)
putFloat(HealthConstants.BodyTemperature.TEMPERATURE, bodyTemperature)
// Register local device as the source of data
sourceDevice = healthDeviceManager.localDevice.uuid
}
try {
val insertRequest = InsertRequest.Builder()
.setDataType(HealthConstants.BodyTemperature.HEALTH_DATA_TYPE)
.build()
insertRequest.addHealthData(data)
val result = mHealthDataResolver.insert(insertRequest).await()
Log.i(MainActivity.APP_TAG, "insert result status: ${result.status}")
} catch (e: Exception) {
e.printStackTrace()
}
}
When using Samsung Health Data SDK to write body temperature data is as follows.
Writing body temperature data with Samsung Health Data SDK
suspend fun insertBodyTemperatureData(
healthDataStore: HealthDataStore
) {
val bodyTemperature = 37F
val tenMinutesAsSeconds = 10L * 60L
val time = LocalDateTime.now().minusSeconds(tenMinutesAsSeconds)
val zoneId = ZoneOffset.systemDefault()
val zoneOffset = zoneId.rules.getOffset(time)
try {
val healthDataPoint = HealthDataPoint.builder()
.addFieldData(DataType.BodyTemperatureType.BODY_TEMPERATURE, bodyTemperature)
.setLocalStartTime(time, zoneOffset)
.setLocalEndTime(time, zoneOffset)
.build()
val insertRequest = DataTypes.BODY_TEMPERATURE.insertDataRequestBuilder
.addData(healthDataPoint)
.build()
healthDataStore.insertData(insertRequest)
} catch (e: Exception) {
e.printStackTrace()
}
}
User profile
The corresponding user profile data types in Samsung Health SDK for Android and Samsung Health Data SDK are as following:
Samsung Health SDK for Android
Samsung Health Data SDK
HealthUserProfile
UserProfileDataType
Example code for getting user profile data when using Samsung Health SDK for Android is as follows.
Getting user profile data with Samsung Health SDK for Android
fun readUserProfile(
healthDataStore: HealthDataStore
) {
val userProfile = HealthUserProfile.getProfile(healthDataStore)
val gender = genderNameById(userProfile.gender)
val height = userProfile.height
val weight = userProfile.weight
}
fun genderNameById(id: Int): String {
return when (id) {
HealthUserProfile.GENDER_MALE -> "MALE"
HealthUserProfile.GENDER_FEMALE -> "FEMALE"
else -> "UNKNOWN"
}
}
Example code for getting user profile data when using Samsung Health Data SDK is as follows.
Getting user profile data with Samsung Health Data SDK
suspend fun readUserProfile(
healthDataStore: HealthDataStore
) {
val readRequest = DataTypes.USER_PROFILE.readDataRequestBuilder
.build()
try {
val result = healthDataStore.readData(readRequest)
result.dataList.lastOrNull()?.let { dataPoint ->
val gender = dataPoint.getValue(DataType.UserProfileDataType.GENDER)
val height = dataPoint.getValue(DataType.UserProfileDataType.HEIGHT)
val weight = dataPoint.getValue(DataType.UserProfileDataType.WEIGHT)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
Getting data's source device
Code for getting source device information that provided sleep data when using Samsung Health SDK for Android is as follows.
Getting data's source device information with Samsung Health SDK for Android
fun getSourceDeviceInfoOfSleepData(
healthDataStore: HealthDataStore
) {
val resultCount = 1
val resultOffset = 0
val handler = Handler(Looper.getMainLooper())
val healthDataResolver = HealthDataResolver(healthDataStore, handler)
val request: HealthDataResolver.ReadRequest =
HealthDataResolver.ReadRequest.Builder()
.setDataType(HealthConstants.Sleep.HEALTH_DATA_TYPE)
.setSort(HealthConstants.Sleep.START_TIME, SortOrder.DESC)
.setResultCount(resultOffset, resultCount)
.build()
try {
healthDataResolver.read(request).setResultListener { result ->
try {
result?.forEach { healthData ->
val deviceId = healthData.getString(HealthConstants.Sleep.DEVICE_UUID)
val healthDevice =
HealthDeviceManager(healthDataStore).getDeviceByUuid(deviceId)
val deviceName = healthDevice.customName
val deviceType = deviceGroupNameById(healthDevice.group)
}
} finally {
result.close()
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
fun deviceGroupNameById(id: Int): String {
return when (id) {
HealthDevice.GROUP_MOBILE -> "MOBILE"
HealthDevice.GROUP_EXTERNAL -> "EXTERNAL"
HealthDevice.GROUP_COMPANION -> "COMPANION or WATCH"
else -> "UNKNOWN"
}
}
To get source device information that provided sleep data when using Samsung Health Data SDK, the following example code can be used.
Getting data's source device information with Samsung Health Data SDK
suspend fun getSourceDeviceInfoOfSleepData(
healthDataStore: HealthDataStore
) {
val resultCount = 1
val readRequest = DataTypes.SLEEP.readDataRequestBuilder
.setOrdering(Ordering.DESC)
.setLimit(resultCount)
.build()
try {
val result = healthDataStore.readData(readRequest)
result.dataList.forEach { sleepData ->
val deviceManager = healthDataStore.getDeviceManager()
sleepData.dataSource?.let { dataSource ->
val device = deviceManager.getDevice(dataSource.deviceId)
val deviceId = device?.id
val deviceName = device?.name
val deviceType = device?.deviceType
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
Having a Trouble?
We are operating a developer support channel on the Samsung Developer site. If you encounter any issue or any question, please visit https://developer.samsung.com/dev-support and submit your query after logging in your Samsung account.
Manage Your Cookies
We use cookies to improve your experience on our website and to show you relevant
advertising. Manage you settings for our cookies below.
Essential Cookies
These cookies are essential as they enable you to move around the website. This
category cannot be disabled.
Company
Domain
Samsung Electronics
.samsungdeveloperconference.com
Analytical/Performance Cookies
These cookies collect information about how you use our website. for example which
pages you visit most often. All information these cookies collect is used to improve
how the website works.
Company
Domain
LinkedIn
.linkedin.com
Meta (formerly Facebook)
.samsungdeveloperconference.com
Google Inc.
.samsungdeveloperconference.com
Functionality Cookies
These cookies allow our website to remember choices you make (such as your user name, language or the region your are in) and
tailor the website to provide enhanced features and content for you.
Company
Domain
LinkedIn
.ads.linkedin.com, .linkedin.com
Advertising Cookies
These cookies gather information about your browser habits. They remember that
you've visited our website and share this information with other organizations such
as advertisers.
Company
Domain
LinkedIn
.linkedin.com
Meta (formerly Facebook)
.samsungdeveloperconference.com
Google Inc.
.samsungdeveloperconference.com
Preferences Submitted
You have successfully updated your cookie preferences.