Access rich sleep data from Samsung Health measured by Galaxy wearables
Objective
Create a health app for Android devices, utilizing the Samsung Health Data SDK to obtain Samsung Health's rich sleep data.
Overview
Samsung Health offers various features to monitor user health data, including automatic sleep recording. The Samsung Health Data SDK grants access to the collected data, allowing developers to filter it based on factors such as the device used or a specific timeframe. This SDK obtains comprehensive sleep information, including sleep scores, sleep sessions, sleep stages, and associated data such as skin temperature and blood oxygen levels.
You can retrieve rich sleep data from Samsung Health using the Samsung Health Data SDK and apply device and local time filters to refine your queries effectively.
Set up your environment
You will need the following:
- Android Studio (latest version recommended)
- Java SE Development Kit (JDK) 17 or later
- Android mobile device compatible with the latest Samsung Health version
Sample Code
Here is a sample code for you to start coding in this Code Lab. Download it and start your learning experience!
Health Data Sleep Sample Code (588.3 KB)
Set up your Android device
Click on the following links to set up your Android device:
Activate Samsung Health's Developer Mode
To enable the Developer mode in the Samsung Health app, follow these steps:
- Go to Settings > About Samsung Health.
- Then, tap the version number quickly 10 times or more. If you are successful, the Developer mode (new) button is shown.
- Tap Developer mode (new) and choose On.
Now, you can test your app with Samsung Health.
NoteThe Samsung Health Developer mode is only intended for testing or debugging your application. It is not for application users.
Start your project
- In Android Studio, click Open to open an existing project.
- Locate the downloaded Android project (SleepDiary) from the directory and click OK.
Check Gradle settings
Before using the Samsung Health Data SDK library, certain configurations are necessary. These steps are already applied in the sample code provided:
- The
samsung-health-data-api-1.0.0b1.aar
library is added to the app\libs folder, and included as a dependency in the module-level build.gradle
file.
In the same file, the gson
library is also added as a dependency.
dependencies {
implementation(files("libs/samsung-health-data-api-1.0.0b1.aar"))
implementation(libs.gson)
}
- Next, the kotlin-parcelize plugin is applied.
plugins {
id("kotlin-parcelize")
}
- Lastly, the following entries are also added in the gradle > libs.version.toml file.
[versions]
gson = "2.11.0"
[libraries]
gson = { module = "com.google.code.gson:gson", version.ref = "gson" }
Request sleep data permissions
The application requires the appropriate permissions and the user's agreement to share their health data for the app to read their sleep data from Samsung Health. While this Code Lab focuses solely on DataTypes.SLEEP
, it is important to recognize that other data types such as skin temperature and blood oxygen levels are also available during sleep. These additional data types can be accessed using DataTypes.SKIN_TEMPERATURE
and DataTypes.BLOOD_OXYGEN
respectively.
Go to app > kotlin+java > com.samsung.health.sleepdiary > repository.
In the HealthDataStoreRepository.kt
file, navigate to the preparePermissionSet()
function.
Create a Permission
object consisting of sleep data type and read access type, and assign it to the sleepPermission
variable.
Permission
Indicates the unit of permission to obtain user consent to share data with the Samsung Health's data store.
It's a pair of DataType and AccessType .
|
Permission
|
companion object of (dataType: DataType, accessType: AccessType)
Creates a permission.
|
/******************************************************************************************
* [Practice 1] Prepare permission set to receive sleep data
*
* ----------------------------------------------------------------------------------------
*
* Use the provided variable 'sleepPermission' which is currently null and replace "TODO 1"
* Create a Permission object of type 'DataTypes.SLEEP' and of 'AccessType.READ' and
* assign it to 'sleepPermission' variable
******************************************************************************************/
fun preparePermissionSet(): MutableSet<Permission> {
val permissionSet: MutableSet<Permission> = mutableSetOf()
var sleepPermission: Permission? = null
// TODO 1
sleepPermission?.let {
permissionSet.add(sleepPermission)
}
return permissionSet
}
Prepare a read request for sleep data
In order to retrieve sleep data from Samsung Health, the client app should prepare a ReadDataRequest
object and send it to the HealthDataStore
. This read request includes filters such as LocalTimeFilter
or ReadSourceFilter
to ensure that only the desired data is received. Moreover, if the user wears both a Galaxy Watch and a Galaxy Ring while sleeping, Samsung Health combines the data from both devices to create an integrated sleep session, providing the most accurate sleep data. Not setting the device filter allows access to the combined data.
In the HealthDataStoreRepository.kt
file, navigate to the prepareReadSleepRequest()
function.
Prepare a read request that retrieves data from a specific day within the past week and includes the option to specify a device filter for either a ring or a watch.
Using the provided LocalTimeFilter
object, update the readRequestBuilder
object. You can take your time to familiarize yourself with the ReadDataRequest
builder creation:
DataTypes.SLEEP.readDataRequestBuilder
function creates a builder for sleep data type.
.setLocalTimeFilter()
function, called on a builder object, adds a time filter to the request.
.setSourceFilter()
function, called on a builder object, adds a read source filter to the request. It can be either an application filter, device filter, or both.
.build()
function, called on a builder object, builds ReadDataRequest
from the configuration of this builder.
ReadDataRequest It represents a request for read query over a period of time to get a list of original HealthDataPoints .
|
ReadDataRequest.DualTimeBuilder<T>
|
setLocalTimeFilter(localTimeFilter: LocalTimeFilter) Sets the local time filter of the request.
|
ReadDataRequest.DualTimeBuilder<T>
|
setSourceFilter(sourceFilter: ReadSourceFilter) Sets the source filter of the request.
|
ReadDataRequest
|
build() Builds ReadDataRequest from the configuration of this builder.
|
/******************************************************************************************
* [Practice 2] Prepare a read request for sleep data
*
* ----------------------------------------------------------------------------------------
*
* Use the provided variable 'localTimeFilter' and replace "TODO 2"
* Set a time filter by calling '.setLocalTimeFilter(localTimeFilter)' on 'readRequestBuilder'
******************************************************************************************/
fun prepareReadSleepRequest(
localTimeFilter: LocalTimeFilter,
readSourceFilter: ReadSourceFilter?
): ReadDataRequest<HealthDataPoint> {
val readRequestBuilder = DataTypes.SLEEP.readDataRequestBuilder
// TODO 2
readSourceFilter?.let {
readRequestBuilder.setSourceFilter(readSourceFilter)
}
return readRequestBuilder.build()
}
Learn how to receive a response from Samsung Health
Receiving sleep data from Samsung Health is done by sending a ReadDataRequest
query to the HealthDataStore
.
NoteThis is a blocking call and should not be called from the main thread.
HealthDataStore It is a proxy which provides a way to access Samsung Health data. An application can access the data through operations HealthDataStore provides, such as inserting, updating, deleting, reading, and aggregating data. A HealthDataStore instance can be obtained by HealthDataService.getStore method.
|
DataResponse<T>
|
abstract suspend fun <T : DataPoint> readData(request: ReadDataRequest<T>) Reads a set of data from Samsung Health according to the given request. This method returns the original data point which is not processed or aggregated.
|
The code below, which is already included in the project file, shows how to receive a response from Samsung Health.
val healthDataList = healthDataStore.readData(readRequest).dataList
Understand how the collected sleep data is processed
A Sleep HealthDataPoint
is a specific type of HealthDataPoint
that contains Samsung Health sleep data. It includes various fields that can be accessed by calling getValue()
function on the data point. Some of the fields include:
- Duration - returns a
Duration
object that indicates how long the sleep lasted.
- Sleep score - returns the calculated quality of the sleep.
- Sessions - returns a list of sessions during the sleep period.
If the user wakes up during sleep for an extended period, multiple sleep sessions may be generated within a single sleep data point. Additionally, each session can consist of various sleep stages including Light, REM (Rapid Eye Movement), Deep, or Awake.
The code below, which is already included in the project file, shows how the collected sleep data is processed.
private fun prepareSleepResult(healthData: HealthDataPoint): SleepData {
healthData.let {
val score: Int
score = prepareSleepScore(it) ?: 0
val duration = it.getValue(DataType.SleepType.DURATION) ?: Duration.ZERO
val sleepSessionList = it.getValue(DataType.SleepType.SESSIONS) ?: emptyList()
return SleepData(
score,
sleepSessionList.size,
duration.toHours().toInt(),
duration.minusHours(duration.toHours()).toMinutes().toInt(),
it.startTime,
it.endTime,
extractSessions(sleepSessionList)
)
}
}
NoteSamsung Health can also measure the user's Blood Oxygen level and Skin Temperature during sleep, if supported by the wearable device. These values are associated to the sleep data in the Samsung Health Data SDK. An application can use the HealthDataPoint
’s unique ID (uid) to create an AssociatedReadRequest
and retrieve the Blood Oxygen level and Skin Temperature data associated with the sleep data point.
Most of the data accessible through the Samsung Health Data SDK is stored as fields within data points. These fields can be extracted by specifying the appropriate keys in the getValue()
function.
In the HealthDataStoreRepository.kt
file, navigate to the prepareSleepScore()
function.
Read the sleep score field from the HealthDataPointby
by calling the getValue()
function with the key DataType.SleepType.SLEEP_SCORE
.
HealthDataPoint It indicates each health data record saved in the Samsung Health's data store.
|
<T> T?
|
getValue(field: Field<T>) Returns the value of the given field.
|
/************************************************************************************
* [Practice 3] Extract a sleep score from the Sleep Data
*
* -----------------------------------------------------------------------------------
*
* Obtain a sleep score from health data point by calling 'healthDataPoint.getValue()'
* and passing 'DataType.SleepType.SLEEP_SCORE' as an argument
* Assign the obtained sleep score to 'sleepScore' variable
***********************************************************************************/
@Suppress("VARIABLE_WITH_REDUNDANT_INITIALIZER")
fun prepareSleepScore(healthDataPoint: HealthDataPoint): Int? {
var sleepScore: Int? = null
// TODO 3
return sleepScore
}
Run unit tests
For your convenience, an additional Unit Tests package is provided. This package lets you verify your code changes even without using a physical phone.
- Right-click on com.samsung.health.sleepdiary (test) > Run 'Tests in 'com.samsung.health.sleepdiary'.
- If you completed all the tasks correctly, you can see that all the unit tests passed successfully.
Run the app
After building the APK, you can run the application on a connected device to read your sleep data.
- Once the app starts, allow All permissions to read sleep data from Samsung Health and tap Done.
- Afterwards, the app's main screen appears, displaying today's sleep data from all connected devices. You can use the calendar or device filter to show sleep data from a different day or a specific device.
- You can tap on any sleep data to see the list of sessions.
- You can tap on any session to see details such as sleep stages.
You're done!
Congratulations! You have successfully achieved the goal of this Code Lab. Now, you can create a mobile health app that reads Samsung Health rich sleep data by yourself! If you are having trouble, you may download this file:
Health Data Sleep Complete Code (588.1 KB)
To learn more about Samsung Health, visit:
developer.samsung.com/health