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:

  1. Go to Settings > About Samsung Health.
  2. Then, tap the version number quickly 10 times or more. If you are successful, the Developer mode (new) button is shown.

  1. Tap Developer mode (new) and choose On.

Now, you can test your app with Samsung Health.

Start your project

  1. In Android Studio, click Open to open an existing project.

  1. 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:

  1. 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)
} 
  1. Next, the kotlin-parcelize plugin is applied.
plugins { 
    id("kotlin-parcelize") 
} 
  1. 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.

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)
        )
    }
}

Extract sleep score from a health 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.

  1. Right-click on com.samsung.health.sleepdiary (test) > Run 'Tests in 'com.samsung.health.sleepdiary'.

  1. 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.

  1. Once the app starts, allow All permissions to read sleep data from Samsung Health and tap Done.

  1. 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.

  1. You can tap on any sleep data to see the list of sessions.

  1. 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