Measure blood oxygen on Galaxy Watch


Objective

Create a health app for Galaxy Watch, operating on Wear OS powered by Samsung, utilizing Samsung Health Sensor SDK to trigger and obtain blood oxygen (SpO2) measurement results.

Overview

Samsung Health Sensor SDK provides means of accessing and tracking health information contained in the health data storage. Its tracking service gives raw and processed sensor data such as accelerometer and body composition data sent by the Samsung BioActive sensor. The latest BioActive sensor of Galaxy Watch runs powerful health sensors such as photoplethysmogram (PPG), electrocardiogram (ECG), bioelectrical impedance analysis (BIA), sweat loss, and SpO2.

See Samsung Health Sensor SDK descriptions for detailed information.

Set up your environment

You will need the following:

  • Galaxy Watch4 or newer
  • Android Studio (latest version recommended)
  • Java SE Development Kit (JDK) 11 or later

Sample Code

Here is a sample code for you to start coding in this Code Lab. Download it and start your learning experience!

Measuring Blood Oxygen Sample Code
(188.1 KB)

Connect your Galaxy Watch to Wi-Fi

  1. Go to Settings > Connection > Wi-Fi and make sure that Wi-Fi is enabled.

  2. From the list of available Wi-Fi networks, choose and connect to the same one as your PC.

Turn on developer mode and adjust its settings

  1. On your watch, go to Settings > About watch > Software and tap on Software version 5 times.

  2. Upon successful activation of developer mode, a toast message displays as on the image below.

  3. Afterwards, Developer options is going to be visible under Settings.

  4. Tap Developer options and enable the following options:

  • ADB debugging

  • In Developer options find Wireless debugging

  • Turn on Wireless debugging

  • Check Always allow on this network and tap Allow

  • Go back to Developer options and click Turn off automatic Wi-Fi

Connect your Galaxy Watch to Android Studio

  1. Go to Settings > Developer options > Wireless debugging and choose Pair new device.

  2. Take note of the Wi-Fi pairing code, IP address & Port.

  3. In Android Studio, go to Terminal and type:

    adb pair <IP address>:<port> <Wi-Fi pairing code>
    
  4. When prompted, tap Always allow from this computer to allow debugging.

  5. After successfully pairing, type:

    adb connect <IP address of your watch>:<port>
    

    Upon successful connection, you can see the following message in Android Studio's terminal:

    connected to <IP address of your watch>
    

Now, you can run the app directly on your watch.

Turn on developer mode for Health Platform

  1. Swipe down from the top of the screen to open the Quick panel, then tap the settings icon.

  2. Scroll down and tap Apps.

  3. Select Health Platform.

  4. Quickly tap Health Platform for about 10 times. Developer mode is enabled when [Dev mode] appears below Health Platform.

Start your project

In Android Studio, click Open to open existing project.

Locate the downloaded Android project from the directory and click Select Folder.

Check capabilities

For the device to track data with the Samsung Health Sensor SDK, it must support a given tracker type – blood oxygen. To check this, get the list of available tracker types and verify that the tracker is on the list.

In the TrackingManager.kt file, navigate to the isSpO2Available() function. Use the provided healthTrackingService object to obtain supported health tracker types using trackingCapability.supportHealthTrackerTypes from HealthTrackingService API. Assign the obtained list into the provided local variable availableTrackers.

  • trackingCapability returns a HealthTrackerCapability instance in the HealthTrackingService object.
  • supportHealthTrackerTypes returns a list of supported tracker types.
HealthTrackingService
HealthTrackingService initiates a connection to Samsung's Health Tracking Service and provides a HealthTracker instance to track a HealthTrackerType.
public HealthTrackerCapability getTrackingCapability()
Provide a HealthTrackerCapability instance to get a supported health tracker type list.

/******************************************************************************************
 * [Practice 1] Check the list of supported health tracker types.
 * ----------------------------------------------------------------------------------------
 *
 * (Hint) Replace TODO 1 with the code as follows:
 * - Set the provided local variable 'availableTrackers' using trackingCapability.supportHealthTrackerTypes
 * from the HealthTrackingService API.
 * - Use the provided healthTrackingService object.
 ******************************************************************************************/
fun isSpO2Available(): Boolean? {
    if (healthTrackingService == null) return false

    var availableTrackers: List<HealthTrackerType>? = null

    //TODO 1

    if (availableTrackers == null) return null

    return availableTrackers.contains(HealthTrackerType.SPO2_ON_DEMAND)
}

Check connection error resolution

Using Samsung Health Sensor SDK API, resolve any error when connecting to Health Tracking Service.

In the TrackingManager.kt file, navigate to the processTrackerException() function, and check if the provided HealthTrackerException object has a resolution. Assign the result to the provided variable hasResolution.

  • hasResolution() function in the HealthTrackerException object checks if the API can fix the error.
HealthTrackerException
HealthTrackerException provides an error code and an error resolution for a failure of HealthTrackingService.connectService().
boolean hasResolution()
Checks whether the given error has a resolution.
/*******************************************************************************************
 * [Practice 2] Check if HealthTrackerException has a resolution.
 * -----------------------------------------------------------------------------------------
 *
 * (Hint) Replace TODO 2 with the code as follows:
 * - Set the provided local variable 'hasResolution' using the hasResolution() method
 * called on the HealthTrackerException object.
 ******************************************************************************************/
fun processTrackerException(exception: HealthTrackerException) {
    var hasResolution: Boolean = false

    //TODO 2

    if (hasResolution) {
        scope.launch {
            _messageState.emit(MessageState.ResolvableError(exception))
        }
    } else {
        exception.printStackTrace()
        val errorMessage = exception.message

        scope.launch {
            _messageState.emit(MessageState.Error(errorMessage))
        }
    }
}
 

Initialize SpO2 tracker

Before the measurement starts, initialize the SpO2 tracker by obtaining the proper health tracker object.

In the TrackingManager.kt file, navigate to the initSpO2Tracker() method and create a blood oxygen HealthTracker instance.

  • Retrieve the HealthTracker object using the HealthTrackingService.getHealthTracker() API.
  • Use the HealthTrackerType.SPO2_ON_DEMAND type as a parameter.
HealthTrackingService
HealthTrackingService initiates a connection to Samsung's Health Tracking Service and provides a HealthTracker instance to track a HealthTrackerType.
HealthTracker getHealthTracker(HealthTrackerType healthTrackerType)
Provides a HealthTracker instance for the given healthTrackerType.

/*******************************************************************************************
 * [Practice 3] Create a SpO2 HealthTracker object:
 * - Retrieve the HealthTracker object.
 * - Use the provided variable 'spO2Tracker'.
 -------------------------------------------------------------------------------------------
 *
 * (Hint) Replace TODO 3 with the code as follows:
 * - Retrieve the HealthTracker object using healthTrackingService.getHealthTracker().
 * - Use the HealthTrackerType.SPO2_ON_DEMAND type as a parameter.
 * - Assign it to the 'spO2Tracker' variable.
 ******************************************************************************************/
fun initSpO2Tracker(): HealthTracker? {
    var spO2Tracker: HealthTracker? = null

    //TODO 3

    return spO2Tracker
}


Perform measurement

For the client app to start obtaining the data through the SDK, it has to set a listener method on the HealthTracker. The application setups the listener when the user taps on the Start button. Each time there is new data, the listener callback receives it. After the measurement is completed, the listener has to be disconnected.

Due to battery drain, on-demand measurement should not last more than 30 seconds. The measurement is cancelled if the final value is not delivered in time. Note that the sensor needs a few seconds to warm up and provide correct values, which adds to the overall measurement time.

The blood oxygen values come in the onDataReceived callback of TrackerEventListener. In TrackingManager.kt file, you can see the code for reading the value:

private val spO2TrackerListener = object : TrackerEventListener {
    override fun onDataReceived(data: MutableList<DataPoint>) {
        data.forEach { dataPoint ->
            val status = dataPoint.getValue(ValueKey.SpO2Set.STATUS)
            val spO2 = dataPoint.getValue(ValueKey.SpO2Set.SPO2)

            _spO2StatusState.value = obtainSpO2Status(status)
            _spO2State.value = DataState.Success(spO2)
        }
    }
}

Run unit tests

For your convenience, you can find an additional Unit Tests package. This lets you verify your code changes even without using a physical watch. See instructions below on how to run unit tests:

  1. Right-click on com.samsung.health.sensorsdksample.spo2measurement (test) and execute Run 'Tests in 'com.samsung.health.sensorsdksample.spo2measurement'' command.

  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 measure blood oxygen.

  1. Right after the app is started, it requests for user permission. Allow the app to receive data from the blood oxygen sensor.

  1. Afterwards, it shows the application's main screen. To get the blood oxygen, tap on the Start button. To stop the measurement, tap on the Stop button.

You're done!

Congratulations! You have successfully achieved the goal of this Code Lab. Now, you can create a health app that measures blood oxygen by yourself! If you're having trouble, you may download this file:

Measuring Blood Oxygen Complete Code
(188.1 KB)

To learn more, explore Samsung Health Sensor SDK.