As of July 2025, Samsung Health SDK for Android has been deprecated. While existing functionality will continue to operate for now, developers are strongly encouraged to migrate to Samsung Health Data SDK to ensure long-term compatibility and continued support.
Both SDKs provide access to health data, stored in Samsung Health app. This data may originate directly from the app itself, as is the case for steps, or from connected wearable devices such as the ring, watch or dedicated medical equipment. Samsung Health Data SDK offers several advantages over its predecessor:
More user-friendly API
Support for more features such as suspend functions
The steps on this page help you easily understand the overall process of migrating your app that reads and inserts exercise data to use the Samsung Health Data SDK.
Prerequisites
Set up your environment
Before you begin the integration, make sure that you have the following installed and ready:
Android Studio
Java JDK 17 or higher
Android mobile device compatible with the latest version of Samsung Health
Set up your Android device
Refer to the following resources to set up your Android device:
When your app is ready for public release, you must become a Samsung Health partner and register the app in Samsung Health’s systems by providing the required information, including the app package name and signature (SHA-256). You can submit a request for partnership here.
However, you can enable developer mode for testing with an app whose signature is not registered in Samsung Health’s systems. An access code is additionally required to test inserting exercise data into Samsung Health. The access code is provided after partnership approval.
Project setup
Import SDK library
Replace Samsung Health SDK for Android AAR file in your project:
Navigate to app/libs in your project.
Replace samsung-health-data-1.5.1.aar with samsung-health-data-api-1.0.0.aar from the downloaded SDK package.
App manifest
When using Samsung Health Data SDK, your app’s manifest should no longer include any entries related to health data permissions.
Gradle settings
SDK dependency
Update your module-level build.gradle to include the correct dependency.
Apply the kotlin-parcelize plugin to the module-level build.gradle:
plugins {
id("kotlin-parcelize")
}
Additionally, check the module-level build.gradle file and include any other dependencies required by your implementation.
Connect with Samsung Health
After completing the initial setup, you are ready to connect your app to Samsung Health to access exercise data.
In the following paragraphs, we are going to show you how to migrate specific elements of logic from Samsung Health SDK for Android to Samsung Health Data SDK.
Samsung Health SDK for Android
With Samsung Health SDK for Android, establishing a connection requires the following:
NoteThe class name HealthDataStore class is the same as in Samsung Health SDK for Android. However, their import directories differ. Make sure that you are using the correct path.
We can now establish the connection and obtain a HealthDataStore instance by calling:
HealthDataService.getStore(context)
Here, context can be your app context.
Request permissions
Upon successful connection to Samsung Health, your app must ensure that it has permissions to access the health data from Samsung Health. Since Samsung SDKs enforce data access control, defining and checking permissions must be done before any data operations are performed.
Samsung Health SDK for Android
In Samsung Health SDK for Android, you must first create a permission set, specifying which data type your app intends to access and the access permission (read or write). For example, to request read and write permissions for Exercise data:
Then, to check existing permissions and request any that are missing, use the HealthPermissionManager class:
val permissionManager = HealthPermissionManager(healthDataStore)
runCatching {
val grantedPermissions = permissionManager.isPermissionAcquired(PERMISSIONS)
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(PERMISSIONS, context)
.setResultListener(permissionListener)
}
}.onFailure { error ->
error.message?.let { Log.i(APP_TAG, it) }
}
Samsung Health Data SDK
In Samsung Health Data SDK, requesting data access permissions is simpler.
For example, to request read and write permissions for Exercise data:
val PERMISSIONS = setOf(
Permission.of(DataTypes.EXERCISE, AccessType.READ),
Permission.of(DataTypes.EXERCISE, AccessType.WRITE)
)
Then, to check if all necessary permissions have been granted:
val grantedPermissions =
healthDataStore.getGrantedPermissions(PERMISSIONS)
val areAllPermissionsGranted =
grantedPermissions.containsAll(PERMISSIONS)
If there are any missing permissions, prompt the user to grant them:
try {
val result = healthDataStore.requestPermissions(PERMISSIONS, context)
// …
} // catch any error
Read exercise data
Samsung Health SDK for Android
In Samsung Health SDK for Android, to read exercise data, you need to create a read request by defining the data type and time range.
Set the data type using HealthConstants.Exercise.HEALTH_DATA_TYPE and specify the local time range using setLocalTimeRange, which accepts the start and end time in Longs:
Next, initialize a HealthDataResolver object using the previously obtained healthDataStore instance (and handler) and launch the prepared readRequest to process the results. For example, you can retrieve the device ID associated with each recorded Exercise. This is useful when you want to determine which device the data originates from.
To achieve this, you can create an iterator to access healthData that represents an Exercise record.
val healthDataResolver = HealthDataResolver(healthDataStore, handler)
try {
healthDataResolver.read(readRequest).await().run {
try {
val iterator = iterator()
while (iterator.hasNext()) {
val healthData = iterator.next()
val deviceId =
healthData.getString(HealthConstants.Exercise.DEVICE_UUID)
// process obtained deviceId or other data
}
} finally {
close()
}
}
} catch (exception: Exception) {
exception.message?.let { Log.i(TAG, it) }
}
Samsung Health Data SDK
In Samsung Health Data SDK, you can achieve the same result with simpler and more concise code. As before, you need to create a read request.
First, create a LocalTimeFilter to access data for the current day:
val startTime = LocalDate.now().atStartOfDay()
val endTime = LocalDateTime.now()
val localTimeFilter = LocalTimeFilter.of(startTime, endTime)
Then, apply it to the prepared request:
val readRequest = DataTypes.EXERCISE.readDataRequestBuilder
.setLocalTimeFilter(localTimeFilter)
.build()
To launch the request, simply call the readData() method of the HealthDataStore instance, passing readRequest as an argument. The result includes a dataList, which you can iterate through to access exercise data:
val exerciseDataList = healthDataStore.readData(readRequest).dataList
exerciseDataList.forEach { healthDataPoint ->
val deviceId = healthDataPoint.dataSource?.deviceId
// process obtained deviceId or other data
}
Read aggregated data
For data types that represent summarized values, such as total, minimum, maximum or last values, you can use aggregate requests to compute these results.
Samsung Health SDK for Android
In Samsung Health SDK for Android, to read aggregated data for a specific period, you need to create AggregateRequest with a defined time range and aggregation function.
For example, to read the total calories burned from exercise since the start of the day, you can call:
addFunction() with AggregateFunction.SUM
setLocalTimeRange() with startTime as the start of the day and endTime as the current time
setDataType() with HealthConstants.Exercise.HEALTH_DATA_TYPE
Below is an implementation of AggregateRequest that reads the total exercise calories since the start of the day.
Note that you also need to define the key ID to retrieve the aggregated data later.
To get the total exercise duration, the logic remains the same. The only difference is the property argument of the request’s addFunction(), as well as the key to retrieve the aggregated data:
In Samsung Health Data SDK, it is simpler to get the aggregated data. First, you need to create LocalTimeFilter to define the time range:
val startTime = LocalDate.now().atStartOfDay()
val endTime = LocalDateTime.now()
val localTimeFilter = LocalTimeFilter.of(startTime, endTime)
Then, build an AggregateRequest instance by calling requestBuilder on the desired aggregate data type. For exercise data, this could be either DataType.ExerciseType.TOTAL_CALORIES or DataType.ExerciseType.TOTAL_DURATION.
The full request is shown below:
val aggregateRequest = DataType.ExerciseType.TOTAL_CALORIES.requestBuilder
.setLocalTimeFilter(localTimeFilter)
.build()
To obtain the aggregated data, create an aggregate request and access the datalist. Since this type of request returns a single-element list containing the aggregated value, you can use Kotlin’s mapNotNull() function to extract it safely, ensuring it’s not null:
Let's explore how to insert prepared exercise data into Samsung Health.
Samsung Health SDK for Android
To insert data in Samsung Health SDK for Android, you first need to create a HealthData instance that contains the exercise data to be inserted. The health data includes the start time, end time, exercise type or duration, and live data (time-series data across different exercise stages). The LiveData placeholder contains the user’s heart rate or speed across each exercise phase.
Let's prepare a set of dummy data to insert. In real-world scenarios, HealthData includes real-time measurements captured from wearable devices or other health and fitness equipment.
Prepare data to be inserted
First, create LiveData - a list of objects of your custom data class ExerciseLiveData.
According to the documentation for Samsung Health SDK for Android, it is recommended to provide start_time and at least one additional field for each instance of LiveData. For more details, please refer to LiveData.
Declare the start_time, heart_rate and speed data:
Next, convert the LiveData list to JsonBlob (ByteArray) format by using the SDK function getJsonBlob(). This function takes a list of ExerciseLiveData as an argument and returns ByteArray. You can simply create a helper function for this task:
private fun createLiveData(liveDataList: List<ExerciseLiveData>): ByteArray {
val zip = HealthDataUtil.getJsonBlob(liveDataList)
return zip
}
Create HealthData object.
Create a HealthData object that holds all exercise data, including timestamps, calories, distance, duration and LiveData. The LiveData is attached using the putBlob() function. In addition to the standard fields start_time, end_time, and time_offset, it is necessary to specify the Exercise type. Based on the Predefined Exercise Type table, setting the value to 1002 represents a running exercise:
val calories = 73f
val distance = 1000f
val exerciseType = 1002
val startTime = Instant.ofEpochSecond(1766394000)
val endTime = Instant.ofEpochSecond(1766394300)
val duration = Duration.between(startTime, endTime)
val timeOffset = TimeZone.getDefault().getOffset(endTime.toEpochMilli()).toLong()
val healthData = HealthData().apply {
sourceDevice = deviceId
putLong(HealthConstants.Exercise.START_TIME, startTime.toEpochMilli())
putLong(HealthConstants.Exercise.END_TIME, endTime.toEpochMilli())
putLong(HealthConstants.Exercise.TIME_OFFSET, timeOffset)
putInt(HealthConstants.Exercise.EXERCISE_TYPE, exerciseType)
putLong(HealthConstants.Exercise.DURATION, duration.toMillis())
putFloat(HealthConstants.Exercise.CALORIE, calories)
putFloat(HealthConstants.Exercise.DISTANCE, distance)
putBlob(HealthConstants.Exercise.LIVE_DATA, createLiveData(liveDataList))
}
Insert the prepared data
Use a HealthDataResolver class to build an insertRequest. Initialize a HealthDataResolver instance and pass in the already connected healthDataStore.
Utilize a Builder() function and set HealthConstants.Exercise.HEALTH_DATA_TYPE as the data type.
Retrieve the local device ID using the HealthDeviceManager instance, as you need to specify the source device that provides this data.
Call the insert() function with the prepared insertRequest and wait for the result.
Below is an implementation example:
val handler = Handler(Looper.getMainLooper())
val healthDataResolver = HealthDataResolver(healthDataStore, handler)
try {
val localDevice = HealthDeviceManager(healthDataStore).localDevice.uuid
val data = ExerciseInsertData.getExerciseData(endTime, localDevice)
if (data != null) {
val insertRequest = HealthDataResolver.InsertRequest.Builder()
.setDataType(HealthConstants.Exercise.HEALTH_DATA_TYPE)
.build()
insertRequest.addHealthData(data)
val result = healthDataResolver.insert(insertRequest).await()
if (result.status == HealthResultHolder.BaseResult.STATUS_SUCCESSFUL) {
Log.i(TAG, "Inserted running exercise. Count of data: ${result.count}")
} else {
Log.i(TAG, "Inserting failed")
}
}
} catch (e: Exception) {
throw e
}
Samsung Health Data SDK
In Samsung Health Data SDK, preparing LiveData to be inserted into Samsung Health app is simplified by the help of the ExerciseLog class. With predefined fields such as timestamp, heartrate, cadence and more, this class is ready to capture information for each phase of an exercise session. This eliminates the need to manually encode it to JsonBlob (ByteArray) format. Instead, you can simply create a list of ExerciseLog objects, each representing a phase of the exercise.
Another key difference in Samsung Health Data SDK is that, instead of creating a HealthData instance, the SDK provides a HealthDataPoint object that represents the entire exercise.
Before creating a HealthDataPoint instance, you need the following:
List of ExerciseLog objects.
Predefined exercise type.
Use addFieldData() function to set the exercise type property with a predefined enum value and include list of DataType.ExerciseType.SESSIONS.
ExerciseSession object.
In the Running exercise, there will always be a single-element list - an ExerciseSession element created based on a previously defined list of ExerciseLog objects. To create an ExerciseSession object, use ExerciseSession.builder() and set the relevant data, such as start time, end time, exercise type, calories and duration.
Once the relevant information is prepared, you can call the builder() method to initialize a HealthDataPoint instance and set the properties, such as start time, end time, and exercise type, by calling the addFieldData() function. The code is shown below:
val calories = 73f
val distance = 1000f
val startTime = Instant.ofEpochSecond(1766394000)
val endTime = Instant.ofEpochSecond(1766394300)
val duration = Duration.between(startTime, endTime)
var healthDataPoint: HealthDataPoint?
try {
val session = ExerciseSession.builder()
.setStartTime(startTime)
.setEndTime(endTime)
.setExerciseType(DataType.ExerciseType.PredefinedExerciseType.RUNNING)
.setDuration(duration)
.setCalories(calories)
.setDistance(distance)
.setComment("Routine running")
.setLog(exerciseLog)
.build()
healthDataPoint = HealthDataPoint.builder()
.setStartTime(startTime)
.setEndTime(endTime)
.addFieldData(
DataType.ExerciseType.EXERCISE_TYPE,
DataType.ExerciseType.PredefinedExerciseType.RUNNING
)
.addFieldData(DataType.ExerciseType.SESSIONS, listOf(session))
.build()
} catch (e: Exception) {
throw e
}
Insert the prepared data
To insert the prepared data, simply build insertRequest by calling the insertDataRequestBuilder method on DataTypes.EXERCISE. Attach the created data (HealthDataPoint instance) by calling the addData() function. Finalize the request with the build() method.
Next, call the insertData() method of the HealthDataStore instance and pass the created insertRequest as an argument:
val insertRequest = DataTypes.EXERCISE.insertDataRequestBuilder
.addData(data)
.build()
healthDataStore.insertData(insertRequest)
Exception handling
Robust health apps can recover when things go wrong. Let's examine the differences between both SDKs when handling such scenarios.
Samsung Health SDK for Android
In the case of Samsung Health SDK for Android, the methods for handling errors depend on the exception types.
For example, connection exceptions with Samsung Health are handled by the HealthDataStore.ConnectionListener's event handler. You can use the HealthConnectionError class to check whether the error has a resolution. Based on the error type, you can implement different handling strategies.
For exceptions related to requests such as reading or writing data, refer to the HealthResultHolder.BaseResult class and its getStatus() method. However, since there are no dedicated exception class, developers must handle the exceptions that are part of the standard Java language, such as IllegalArgumentException, SecurityException or IllegalStateException.
Samsung Health Data SDK
When working with Samsung Health Data SDK, key functions such as aggregateData(), requestPermissions(), or getGrantedPermissions() may throw exceptions under certain conditions.
To prevent unexpected crashes or blank screens, it’s best to funnel these exceptions into a central error handler.
You can do so by wrapping every API invocation with:
HealthDataException is the main exception class for Samsung Health Data SDK.
The handleHealthDataException() function:
• Shows an error log.
• Tries to “resolve” the exception
Some HealthDataException instances include a resolution intent. You can check if the exception has a resolution by checking the hasResolution property of the exception object and trying to fix it by invoking resolve().
Examples of such exceptions:
• ERR_OLD_VERSION_PLATFORM: Indicates Samsung Health app is outdated.
• ERR_PLATFORM_NOT_INSTALLED: Signals that Samsung Health app is not installed.
In both cases, the resolution involves opening the device’s app marketplace to prompt the user to install or update Samsung Health app. Once the issue is fixed, control returns to the app so it can continue functioning.
This approach not only keeps your UI clean, but allows for a consistent, guided error experience. When something goes wrong, users can see a clear message of what happened and how to fix it.
Summary
We have covered how to migrate an app that uses the Samsung Health SDK for Android to the Samsung Health Data SDK.
When migrating your app to the Samsung Health Data SDK, you can follow the described process and code examples to complete the migration.
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.