Measure Blood Oxygen Level on Galaxy Watch
Objective
Create a health app for Galaxy Watch, operating on Wear OS powered by Samsung, utilizing the new Samsung Privileged Health SDK to trigger and obtain blood oxygen level (SpO2) measurement results.
Partnership Request
In this Code Lab, you will use a specially prepared mock library. It has limited functionality and uses dummy data instead of real-time data. To get real values, you will need the full version of the Samsung Privileged Health SDK library, which is available to registered Samsung partners. Apply as a partner by checking out the Partner App Program to get exclusive access to the Samsung Privileged Health SDK.
Overview
Samsung Privileged Health 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 Privileged Health 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!
Turn on Developer Mode and adjust its settings
-
On your watch, go to Settings > About watch > Software and tap on Software version 5 times.
-
Upon successful activation of Developer mode, a toast message will display as on the image below.
-
Afterwards, Developer options will be visible under Settings.
-
Tap Developer options and enable the following options:
-
ADB debugging
-
Debug over Wi-Fi
-
Turn off automatic Wi-Fi
-
Connect your Galaxy Watch to Wi-Fi
- Go to Settings > Connection > Wi-Fi and make sure that Wi-Fi is enabled.
- From the list of available Wi-Fi networks, choose and connect to the same one as your PC.
- When successfully connected, tap a Wi-Fi network name, swipe down, and note the IP address. You will need this to connect your watch over ADB from your PC.
Connect your Galaxy Watch to Android Studio
In Android Studio, go to Terminal and type:
adb connect <IP address as mentioned in previous step>
When prompted, tap Always allow from this computer to allow debugging.
Upon successful connection, you will 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.
Start your project
After downloading the sample code containing the project files, in Android Studio click Open to open existing project.
Locate the downloaded Android Project (Basic) from the directory and click OK.
Check capabilities
For the device to track data with the Samsung Privileged Health SDK, it must support a given tracker type – blood oxygen level. To check this, get the list of available tracker types and verify that the tracker is on the list.
In the ConnectionManager.java
file, navigate to the isSpO2Available()
function, use a provided HealthTrackingService
object to create a HealthTrackerCapability
instance, send it to the checkAvailableTrackers
function, and assign its result to the availableTrackers
list.
getTrackingCapability()
returns aHealthTrackerCapability
instance in theHealthTrackingService
object
HealthTrackingService
|
|
---|---|
public HealthTrackerCapability
|
getTrackingCapability()
Provide a |
/******************************************************************************************
* [Practice 1] Check capabilities to confirm SpO2 availability
*
* ----------------------------------------------------------------------------------------
*
* (Hint) Replace TODO 1 with java code
* Get HealthTrackerCapability object from HealthTrackingService
* Send the object to checkAvailableTrackers()
******************************************************************************************/
public boolean isSpO2Available(HealthTrackingService healthTrackingService) {
if (healthTrackingService == null)
return false;
List<HealthTrackerType> availableTrackers = null;
//"TODO 1"
if (availableTrackers == null)
return false;
else
return availableTrackers.contains(HealthTrackerType.SPO2);
}
Check connection error resolution
Suppose a connection to the Health Tracking Service attempt ends with an error. In that case, you can try to resolve it using the Samsung Privileged Health SDK API.
In the ConnectionManager.java
file, navigate to the processTrackerException()
function, and check if the provided HealthTrackerException
object has a resolution. Assign the result to hasResolution
variable.
hasResolution()
function in theHealthTrackerException
object checks if the API side can fix the error
HealthTrackerException
|
|
---|---|
boolean | hasResolution()
Checks whether the given error has a resolution. |
/*******************************************************************************************
* [Practice 2] Resolve HealthTrackerException error
*
* -----------------------------------------------------------------------------------------
*
* (Hint) Replace TODO 2 with java code
* Call hasResolution() on HealthTrackerException object
******************************************************************************************/
public void processTrackerException(HealthTrackerException e) {
boolean hasResolution = false;
//"TODO 2"
if (hasResolution)
e.resolve(callingActivity);
if (e.getErrorCode() == HealthTrackerException.OLD_PLATFORM_VERSION || e.getErrorCode() == HealthTrackerException.PACKAGE_NOT_INSTALLED)
ObserverUpdater.getObserverUpdater().notifyConnectionObservers(R.string.NoValidHealthPlatform);
else
ObserverUpdater.getObserverUpdater().notifyConnectionObservers(R.string.ConnectionError);
Log.e(TAG, "Could not connect to Health Tracking Service: " + e.getMessage());
}
Initialize SpO2 tracker
Before the measurement starts, initialize the SpO2 tracker by obtaining the proper health tracker object.
In the SpO2Listener.java
file, navigate to the init()
function. Using the provided HealthTrackingService
object, create an instance of the SpO2 tracker and assign it to the spo2Tracker
object.
getHealthTracker()
withHealthTrackerType.SPO2
as an argument will create aHealthTracker
instance
HealthTrackingService
|
|
---|---|
HealthTracker
|
getHealthTracker(HealthTrackerType healthTrackerType)
Provides a |
/*******************************************************************************************
* [Practice 3] Initialize SpO2 tracker
*
* ----------------------------------------------------------------------------------------
*
* (Hint) Replace TODO 3 with java code
* Initialize spo2Tracker with proper Samsung Privileged Health SDK functionality
* Call getHealthTracker() on HealthTrackingService object
* Use HealthTrackerType.SPO2 as an argument
******************************************************************************************/
void init(HealthTrackingService healthTrackingService) {
//"TODO 3"
}
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 Measure button. Each time there is new data, the listener callback receives it. After the measurement completes, the listener has to be disconnected.
Since, due to battery drain, on-demand measurement should not last more than approximately 30 seconds. The measurement will cancel if the final blood oxygen level value is not delivered in time. It’s also worth noting that the sensor needs a few seconds to warm up and provide correct values, adding to the overall measurement time.
The blood oxygen level values come in the onDataReceived
callback of TrackerEventListener
. See below example of the code, in the SpO2Listener.java
file, reading the value:
private final HealthTracker.TrackerEventListener spo2Listener = new HealthTracker.TrackerEventListener() {
@Override
public void onDataReceived(@NonNull List<DataPoint> list) {
for (DataPoint data : list) {
updateSpo2(data);
}
}
};
private void updateSpo2(DataPoint data) {
int status = data.getValue(ValueKey.SpO2Set.STATUS);
int spo2Value = 0;
if (status == MEASUREMENT_COMPLETED)
spo2Value = data.getValue(ValueKey.SpO2Set.SPO2);
ObserverUpdater.getObserverUpdater().notifyTrackerObservers(status, spo2Value);
}
Run unit tests
For your convenience, you will find an additional Unit Tests package. This will let you verify your code changes even without using a physical watch. See instructions below on how to run the unit tests:
- Right click on com.samsung.sdc22.health.basic (test) and execute Run 'Tests in 'com.samsung.sdc22.health.basic'' command.
- If you completed all the tasks correctly, you will see all the unit tests passed successfully.
Run the app
After building the APK, you can run the application on a connected device to measure your blood oxygen level.
- Right after the app is started, it will request user permission. Allow the app to receive data from the body sensors.
- Afterwards, it will show the application's main screen. To get the blood oxygen level value, tap on the Measure 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 level by yourself! If you're having trouble, you may download this file:
To learn more about Samsung Health, visit:
developer.samsung.com/health