Sei sulla pagina 1di 59

Programming Guide:

Samsung Digital Health


- Health Data
1.0.0 beta3

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Samsung Digital Health - Health Data

Programming Guide

Table of Contents
1.

OVERVIEW .........................................................................................................................................................4
1.1. DATA FRAMEWORK................................................................................................................................................. 4
1.2. ARCHITECTURE ........................................................................................................................................................ 5
1.2.1.
DATA SOURCE DEVICE ..................................................................................................................................... 5
1.2.2.
DATA FRAMEWORK......................................................................................................................................... 5
1.2.3.
SAMSUNG DIGITAL HEALTH APPLICATION...................................................................................................... 5

2.

DEVELOPMENT ENVIRONMENT......................................................................................................................... 11
2.1. PREREQUISITES ..................................................................................................................................................... 11
2.2. DOWNLOADING HEALTH DATA OF SAMSUNG DIGITAL HEALTH SDK .................................................................. 11
2.3. TESTING YOUR APPLICATION WITH HEALTHDEVAPP ........................................................................................... 12
2.4. PUBLISHING YOUR APPLICATION .......................................................................................................................... 13

3.

SAMSUNG DIGITAL HEALTH FUNDAMENTALS .................................................................................................... 14


3.1. IMPORTING LIBRARY ............................................................................................................................................. 14
3.2. HELLO SAMSUNG DIGITAL HEALTH....................................................................................................................... 14

4.

SAMSUNG DIGITAL HEALTH FEATURES .............................................................................................................. 17


4.1. HEALTH DATA STORE ............................................................................................................................................ 17
4.1.1.
CONNECTION TO HEALTH DATA STORE ........................................................................................................ 17
4.1.2.
SYNCHRONOUS VS ASYNCHRONOUS REQUEST ............................................................................................ 17
4.1.3.
INSERTING HEALTH DATA ............................................................................................................................. 19
4.1.4.
READING HEALTH DATA ................................................................................................................................ 20
4.1.5.
FILTER ............................................................................................................................................................ 20
4.1.6.
UPDATING HEALTH DATA.............................................................................................................................. 21
4.1.7.
DELETING HEALTH DATA ............................................................................................................................... 21
4.1.8.
AGGREGATION .............................................................................................................................................. 22
4.1.9.
DATA NORMALIZATION................................................................................................................................. 22
4.2. HEALTH DATA TYPE ............................................................................................................................................... 23
4.3. PRIVACY................................................................................................................................................................. 28

5.

USE CASES ........................................................................................................................................................ 29


5.1. CONNECTING TO HEALTHDATASTORE .................................................................................................................. 29
5.2. ACQUIRING USER PERMISSION ............................................................................................................................. 30
5.3. INSERTING DATA ................................................................................................................................................... 32
5.4. UPDATING DATA ................................................................................................................................................... 34
5.5. DELETING DATA..................................................................................................................................................... 35
5.6. READING DATA...................................................................................................................................................... 37
5.7. AGGREGATING DATA ............................................................................................................................................ 38
5.8. OBSERVING CHANGE............................................................................................................................................. 40

6.

SAMPLE APPLICATIONS..................................................................................................................................... 41
6.1. SIMPLEHEALTH ...................................................................................................................................................... 41
6.1.1.
MAINACTIVITY ............................................................................................................................................... 42
6.1.2.
STEPCOUNTREPORTER .................................................................................................................................. 44
6.2. FOODNOTE ............................................................................................................................................................ 46
6.2.1.
MAINACTIVITY ............................................................................................................................................... 48
6.2.2.
CHOOSEFOODACTIVITY ................................................................................................................................. 50
6.2.3.
MEALSTOREACTIVITY .................................................................................................................................... 51

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 2

Samsung Digital Health - Health Data

6.2.4.

Programming Guide

FOODDATAHELPER ........................................................................................................................................ 52

APPENDIX A.

HEALTHDEVAPP - IMPORT DATA ..................................................................................................... 57

APPENDIX B.

HEALTHDEVAPP - EXPORT DATA ..................................................................................................... 58

COPYRIGHT .............................................................................................................................................................. 59

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 3

Samsung Digital Health - Health Data

Programming Guide

1. Overview
Health is a main keyword nowadays and related services are increasing continuously with the need for health
improvement. Samsung Digital Health SDK helps developers to make useful health applications that handle health
data safely, and share health data with other applications based on users consent.

Figure 1: Samsung Digital Health service


Refer to Table 1 for Samsung Digital Health SDK glossary.
Term

Description

Data Framework

It provides useful features to handle users health data. As it is included in S Health,


applications for Samsung Digital Health works after installing S Health.

S Health

An application that helps that monitors users activities and helps user makes a healthier life
with pedometer, exercise, heart rate, and etc.
Its written as italic in this document.

Table 1: Glossary

1.1.Data Framework
The Data Framework of Samsung Digital Health SDK provides the following features:
-

Health Data Store

Handling the connection state

Inserting, reading, updating, deleting health data

Unified unit conversion

Health Data Type

Platform-defined data type

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 4

Samsung Digital Health - Health Data

Programming Guide

Privacy

Granting permission based on users consent to read or write the specific data type

1.2.Architecture
The Data Framework of Samsung Digital Health is designed to provide safe access for health data and a seamless
health service to user. Figure 2 is the architecture for the Data Framework of Samsung Digital Health.

Figure 2: Architecture for the Data Framework of Samsung Digital Health


The detailed description is presented below.

1.2.1. Data Source Device


Devices that have various sensors such as the pedometer, accelerator, or heart rate sensor can measure health data
of user. We call the device that provides health data of user as the source device and each health data that handled
in the Data Framework has source device information.

1.2.2. Data Framework


The Data Framework is the nub for the Samsung Digital Health service. It keeps users health data safely with various
data types based on XML schema definition. Health data coming from a specific source device is inserted with the
unified data unit, read, updated, or deleted through the data store connection through the Data Framework. As it is
included in the S Health, applications need to install S Health.

1.2.3. Samsung Digital Health Application


A Samsung Digital Health application indicates an application that uses the Data Framework of Samsung Digital
Health. Samsung Digital Health SDK provides HealthDevApp that enables you to substitute S Health. It helps you to
Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 5

Samsung Digital Health - Health Data

Programming Guide

develop applications even if S Health is not installed in the device. You c and find it in the [samsung-digitalhealth-healthdata]\Tools folder.
Figure 3 shows the relationship between classes and interfaces of the com.samsung.android.sdk.healthdata
package. Detailed descriptions for each class and interface are in the API Reference under the [samsung-digitalhealth-healthdata]\Docs\API Reference folder.
HealthDataService initializes the Health data service. APIs of the com.samsung.android.sdk.healthdata
works properly after initialize() is called without an exception.
HealthDataStore handles the connection to the data storage of the device. It receives its connection result with
HealthDataStore.ConnectionLsitener. Most requests require the connection to the health data store.
The Data Framework provides classes and interface to insert, read, update, or delete health data.
HealthDataResolver is a central class to handle health data. It sends a data request with related request
interfaces and gets a result through HealthResultHolder. The result can be received immediately with
HealthDataHolder.BaseResult, HealthDataResolver.ReadResult or
HealthDataResolver.AggregateResult. Or it can be received asynchronously with
HealthResultHolder.ResultListener. See 4.1 for more information.

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 6

Samsung Digital Health - Health Data

Programming Guide

<<interface>>
HealthDataStore.ConnectionListener

HealthDataService

HealthDataStore

HealthDeviceManager

+initialize()

<<interface>>
HealthResultHolder

HealthDataResolver

<<interface>>
HealthResultHolder.ResultListener

HealthDataResolver.Filter

<<interface>>
HealthDataResolver.ReadRequest

HealthDevice

HealthDevice.Builder

HealthDataResolver.ReadRequest.Builder
HealthResultHolder.BaseResult
<<interface>>
HealthDataResolver.InsertRequest

HealthData

HealthDataResolver.ReadResult
HealthDataResolver.InsertRequest.Builder

HealthDataResolver.AggregateResult

<<interface>>
HealthDataResolver.UpdateRequest

HealthDataResolver.UpdateRequest.Builder

<<interface>>
HealthDataResolver.DeleteRequest

HealthDataResolver.DeleteRequest.Builder

<<interface>>
HealthDataResolver.AggregateRequest

HealthDataResolver.AggregateRequest.Builder

Figure 3: Class diagram related to HealthDataStore

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 7

Samsung Digital Health - Health Data

Programming Guide

Application developers can use platform-defined data types that Samsung Digital Health provides. See 4.2 for more
information. Especially HealthConstants.Common contains the following mandatory properties for health data.
-

Unique ID of health data

Created and updated time of health data

Application package name

Device that provides health data

HealthConstants.Common is the base class of predefined data types of Samsung Digital Health as in Figure 4.

Figure 4: Class diagram related to health data type

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 8

Samsung Digital Health - Health Data

Programming Guide

Users health data can be accessed with the users consent. Figure 5 shows relationship between classes and
interface related to HealthPermissionManager. It requests permissions with
HealthPermissionManager.PermissionKey that contains the required permission to read or write for the
specific health data type. The permission result can be received synchronous or asynchronously. See 4.3 for more
information.

<<interface>>
HealthDataStore.ConnectionListener

HealthDataStore

HealthPermissionManager

<<interface>>
HealthResultHolder

HealthPermissionManager.PermissionKey

<<interface>>
HealthResultHolder.ResultListener

HealthResultHolder.BaseResult

HealthPermissionManager.PermissionType

HealthPermissionManager.PermissionResult

Figure 5: Class diagram related to HealthPermissionManager


The Health Data library of Samsung Digital Health provides the following package:
-

com.samsung.android.sdk.healthdata

Main interfaces and classes in the library are described in Table 2. See the API reference on details.
com.samsung.android.sdk.healthdata
Interface / Class

Description

HealthConnectionErrorResult

This class handles errors for connection failure to the health data store.

HealthConstants

This class defines constants of health data and contains interfaces for various kinds of
health data such as the count of steps or exercise.

HealthData

This class is an object for a health data type, e.g., the blood pressure or weight.
Quantitative and qualitative values can be specified for the specific health data type
based on its data structure definition. It is used to manage health data with
HealthDataResolver.

HealthDataObserver

This class defines an observer to handle health data changes.

HealthDataResolver

This class accesses health data to insert, read, update, and delete with the filter and
aggregate functions.

HealthDataService

This class initializes the Health data service.

HealthDataStore

This class handles the connection to the data store in the device.

HealthDataUnit

This class provides unified units for the health data store.

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 9

Samsung Digital Health - Health Data

Programming Guide

HealthDevice

This class contains detailed device information that provides health data.

HeatlthDeviceManager

This class manages devices related health data.

HealthPermissionManager

This class requests permission to read or write health data for the specific health data
type.

HealthResultHolder

This interface represents the result of invoking method.

HealthUserProfile

This class provides user information.

Table 2: Interfaces and classes of com.samsung.android.sdk.healthdata

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 10

Samsung Digital Health - Health Data

Programming Guide

2. Development Environment
To develop applications with Samsung Digital Health features, check prerequisites for the SDK first.

2.1.Prerequisites
Before downloading Samsung Digital Health SDK, refer to the following information.

Android Version
Android 4.4 KitKat (API level 19) or above

Available Devices
Samsung Android devices (KitKat or above)

2.2.Downloading Health Data of Samsung Digital Health SDK


Samsung Digital Health SDK can be downloaded in the Samsung developer site. If the downloaded SDK is unzipped,
you can check the following content in Table 3 for the application development.
Folder in SDK
Docs

Description
API Reference
Describes Samsung Digital Health APIs
Programming Guide
Contains development information to create Samsung Digital Health applications

Libs

samsung-digital-health-healthdata-v1.0.0.jar
Client library of Samsung Digital Health SDK
sdk-v1.0.0.jar
Basic library for the Samsung SDK

Samples

SimpleHealth
Sample application that demonstrates how to use Samsung Digital Health SDK
FoodNote
Sample application to check daily calorie intake

Tools

HealthDevApp.apk
An application to substitute S Health. It provides the Samsung Digital Health service on the
development phase.
DataImportSample-Weight.csv/txt
Example files to import health data with HealthDevApp

Table 3: Samsung Digital Health SDK content

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 11

Samsung Digital Health - Health Data

Programming Guide

2.3.Testing Your Application with HealthDevApp


Samsung Digital Health SDK provides HealthDevApp as a tool for its application development. HealthDevApp enables
applications to use the Samsung Digital Health service as a substitution for S Health in the development phase.
Because the available S Health version for the Samsung Digital Health service is not yet released, install
HealthDevApp in the device and start to make your application.

Figure 6: HealthDevApp
It includes the following features.
-

Samsung Digital Health

Dashboard

HealthDevApp provides a test environment for user profile such as the name, gender, birthday, or
height.

Pedometer

It shows health data in the health data store with its detailed values by each data type.

User profile

HealthDevApp provides the Samsung Digital Health service for your application.

It provides a simple way to collect health data for steps. If you check it and walk with the device,
pedometer data is inserted to the health data store. Accumulated pedometer data can be checked in
Step Count on Dashboard.

Permission setting

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 12

Samsung Digital Health - Health Data

Importing health data with csv or txt is provided for your convenience. Health data of the file can
be inserted to the health data store. Refer to Appendix A for more information.

Export Data

Permissions can be managed and checked for each application of permission related.

Import Data

Programming Guide

Health data in the health data store can be exported to the text or csv file. Refer to Appendix B for
more information. Refer to Appendix B for more information.

Password

It provides the test environment if user sets a password for health data. If the password is set, the
health data store is not connected until the password in entered.

Platform Type
If you use HealthDevApp in the debugging mode, you need to add the following metadata to the
AndroidManifest.xml file of your application project.
<meta-data
android:name="com.samsung.android.health.platform_type"
android:value="dev" />

2.4.Publishing Your Application


Refer to the following guidelines to publish your application.

Packaging Application
If your application is ready to publish, change the value of metadata information for the health platform type to
"rel" as shown below and package your application.
<meta-data
android:name="com.samsung.android.health.platform_type"
android:value="rel" />

If you dont change the value above, your application doesnt run with S Health.

Request for Partner Apps


Applications works with S Health run properly after the partner application registration. Because health data is
closely connected to the privacy and medical issues, Samsung checks violations in your application and registers your
application as the partner application after. You can request for the partner application on the developer site.

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 13

Samsung Digital Health - Health Data

Programming Guide

3. Samsung Digital Health Fundamentals


If you checked prerequisites for the application development and the downloaded SDK content, its ready to start
creating an application. The following sections give you fundamentals for developing a Samsung Digital Health
application.

3.1.Importing Library
Add samsung-digital-health-healthdata-v1.0.0.jar and sdk-v1.0.0.jar to the libs folder in your created application
project.

3.2.Hello Samsung Digital Health


The example below shows essential code for a Samsung Digital Health application.
-

Initializes the Health data service with HealthDataService.

Connects to the health data store with HealthDataStore.


The other operations are available after checking the connection state in the connection callback.

Acquires the required permission to read or write users health data with HealthPermissionManager.

import com.samsung.android.sdk.healthdata.*;

public class MainActivity extends Activity {


private HealthDataStore mStore;
private HealthPermissionManager.PermissionKey mPermissionKey;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPermissionKey = new PermissionKey(HealthConstants.StepCount.HEALTH_DATA_TYPE,
PermissionType.READ);
HealthDataService healthDataService = new HealthDataService();
try {
// Initializes the Health data service
healthDataService.initialize(this);
} catch (Exception e) {
// Handles exception
}
mStore = new HealthDataStore(this, mConnectionListener);
// Connects to the health data store
mStore.connectService();
}
@Override
public void onDestroy() {
mStore.disconnectService();
super.onDestroy();
}
Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 14

Samsung Digital Health - Health Data

Programming Guide

private final HealthDataStore.ConnectionListener mConnectionListener


= new HealthDataStore.ConnectionListener() {
@Override
public void onConnected() {
// The connection is successful.
// Acquires the required permission
HealthPermissionManager pmsManager = new HealthPermissionManager(mStore);
try {
// Check whether the required permission is acquired
Set<PermissionKey> keySet = new HashSet<PermissionKey>();
keySet.add(mPermissionKey);
Map<PermissionKey, Boolean> resultMap = pmsManager.isPermissionAcquired(keySet);
if (resultMap.get(mPermissionKey) == Boolean.TRUE) {
// The permission has been acquired already
} else {
// Requests permission to read the count of steps
pmsManager.requestPermissions(keySet)
.setResultListener(mPermissionListener);
}
} catch (Exception e) {
// Error handling
}
}
@Override
public void onConnectionFailed(HealthConnectionErrorResult error) {
// Resolve error if the connection fails
error.resolve(this);
}
@Override
public void onDisconnected() {
// The connection is disconnected
}
};
private final HealthResultHolder.ResultListener<PermissionResult> mPermissionListener =
new HealthResultHolder.ResultListener<PermissionResult>() {
@Override
public void onResult(PermissionResult result) {
Map<PermissionKey, Boolean> resultMap = result.getResultMap();
if (resultMap.get(mPermissionKey) == Boolean.FALSE) {
// The requested permission is not acquired
} else {
// The requested permission is acquired.
}
}
};
}

Figure 7 show an activity for resolve() if the connection to the health data store fails. If it is caused by
OLD_VERSION_PLATFORM, the activity needs to download the latest S Health. If it is caused by OLD_VERSION_SDK,
its required to download the latest version of your application.

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 15

Samsung Digital Health - Health Data

Programming Guide

Figure 7: Activity for resolve()

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 16

Samsung Digital Health - Health Data

Programming Guide

4. Samsung Digital Health Features


Key features of Samsung Digital Health SDK are:
-

Health data store

Health data types

Privacy

4.1.Health Data Store


Samsung Digital Health SDK provides the health data store to access health data with users consent. The data access
includes inserting, reading, updating, and deleting health data. Data in the health data store can be shared among
applications.

4.1.1. Connection to Health Data Store


The connection to the health data store is required to access health data in the health data store.
HealthDataStore provides connectService() and disconnectService() and its events can be checked with
HealthDataStore.ConnectionListener. See 5.1 for its use case.

4.1.2. Synchronous vs Asynchronous Request


Data can be accessed with the following APIs of HealthDataResolver. It enables an application to request the
following operations.
-

HealthResultHolder<BaseResult> insert(InsertRequest request)

HealthResultHolder<BaseResult> update(UpdateRequest request)

HealthResultHolder<BaseResult> delete(DeleteRequest request)

HealthResultHolder<ReadResult> read(ReadRequest request)

HealthResultHolder<AggregateResult> aggregate(AggregateRequest request)

Its result is received through HealthResultHolder as a container for the corresponding result. The result of
HealthDataResolver.ReadResult and HealthDataResolver.AggregateResult are returned as the
Cursor interface. You can check the data value by moving the cursor.
The result of the health data request can be received either synchronously or asynchronously. You can choose one of
them for your application design.
If you want to get the result immediately for the health data request, use HealthResultHolder.await() as
shown below. It throws an exception if it is called in the main thread.
import com.samsung.android.sdk.healthdata.*;
// The state of connection
private HealthDataStore mStore;
private void readGlucoseSynchronously(long start, long end) {
Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 17

Samsung Digital Health - Health Data

Programming Guide

HealthDataResolver resolver = new HealthDataResolver(mStore, null);


Filter filter = Filter.greaterThan(HealthConstants.BloodGlucose.GLUCOSE, 125);
ReadRequest request = new ReadRequest.Builder()
.setDataType(HealthConstants.BloodGlucose.HEALTH_DATA_TYPE)
.setFilter(filter)
.build();
try {
// Checks the result immediately
// It has to be called in another thread from the main thread
ReadResult c = resolver.read(request).await()
if (c != null) {
List dataList = new ArrayList();
while (c.moveToNext()) {
float data = c.getFloat(c.getColumnIndex(HealthConstants.BloodGlucose.GLUCOSE));
dataList.add(data);
}
c.close();
}
else {
Log.d(APP_TAG, "There is no result.");
}
} catch (Exception e) {
Log.d(APP_TAG, "Reading health data fails.");
}
}

If you need to request asynchronously, set the result listener with


HealthResultHolder.setResultListener().
An example below shows the asynchronous request.
import com.samsung.android.sdk.healthdata.*;
// The state of connection
private HealthDataStore mStore;
private void readGlucoseAsynchronously(long start, long end) {
HealthDataResolver resolver = new HealthDataResolver(mStore, null);
Filter filter = Filter.greaterThan(HealthConstants.BloodGlucose.GLUCOSE, 125);
ReadRequest request = new ReadRequest.Builder()
.setDataType(HealthConstants.BloodGlucose.HEALTH_DATA_TYPE)
.setFilter(filter)
.build();
try {
resolver.read(request).setResultListener(new HealthResultHolder.ResultListener<ReadResult>() {
@Override
public void onResult(ReadResult result) {
// Checks the result
Cursor c = result.getResultCursor();
if (c != null) {
List dataList = new ArrayList();
while (c.moveToNext()) {
float data = c.getFloat(c.getColumnIndex(HealthConstants.BloodGlucose.GLUCOSE));
dataList.add(data);
Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 18

Samsung Digital Health - Health Data

Programming Guide

}
c.close();
}
else {
Log.d(APP_TAG, "There is no result.");
}
}
};
} catch (Exception e) {
Log.d(APP_TAG, "Reading health data fails.");
}
}

4.1.3. Inserting Health Data


The Data Framework enables your application to add created health data for the specific data type. Each data to be
added needs to specify the following information.
-

Data type

Source device ID that provides health data

Health data including mandatory properties that are defined in the data type.
See 4.2 on details for health data properties of the health data type.

The Data Framework registers the current device where your application is installed. If the source device is the
current device, its ID can be checked as shown below.
import com.samsung.android.sdk.healthdata.*;
// The state of connection
private HealthDataStore mStore;
private void getCurrentDeviceInfo() {
HealthDeviceManager deviceManager = new HealthDeviceManager(mStore);
HealthDevice device = deviceManager.getLocalDevice();
String devicdId = device.getUuid();
}

You can register more source devices with HealthDevice.Builder.build() and


HealthDeviceManager.regsiterDevice().
import com.samsung.android.sdk.healthdata.*;
// The state of connection
private HealthDataStore mStore;
private void registerDevice(String seed, String manufacturer, String model) {
// Specifies device information
HealthDevice.Builder builder = new HealthDevice.Builder();
HealthDevice device = builder.setModel(model)
.setManufacturer("Samsung")
.setDeviceSeed("400E85A7ED28")
.setGroup(HealthDevice.GROUP_MOBILE)
.build();
// Registers the device
HealthDeviceManager deviceManager = new HealthDeviceManager(mStore);
try {
Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 19

Samsung Digital Health - Health Data

Programming Guide

deviceManager.registerDevice(device);
} catch {
// Error handling
}
}

When you insert health data to the health data store, check units of data values are correct. Get more information
from 4.1.9.
The health data store accepts only validated health data. If any mandatory property is missing,
HealthDataResolver.insert() throws an exception. If property values dont satisfy the validation range, it succeeds but
inserted values are ignored.
You can check the number of data with BaseResult.getCount() in the result of HealthDataResolver.insert(). The size
limitation for blob type insertion is 1 megabyte.

4.1.4. Reading Health Data


An application can read health data for the specific data type through the health data store. More conditions can be
added to HealthResolve.ReadRequest to get required data.
-

Filter if a condition for the property of the data type is required

Properties and property alias of the result

Sort order of the result

Source device if a condition for source devices that provides health data is required

Package name if a condition for the package name that provides health data is required

4.1.5. Filter
HealthDataResolver.Filter is very useful to clear the data range for reading, updating, and aggregating health
data. Each filter contains one comparison below.
-

eq()

greaterThan()

greaterThanEquals()

in()

lessThan()

lessThanEquals()

not()

Multiple filters can be combined with and() and or() as Figure 8 and example below.

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 20

Samsung Digital Health - Health Data

Programming Guide

Figure 8: Using filter


import com.samsung.android.sdk.healthdata.*;
Filter filter1 = Filter.eq("property1", "AAA");
Filter filter2 = Filter.eq("property2", "BBB");
Filter filter3 = Filter.greaterThanEquals("property3",100);
Filter filter = Filter.and(Filter.or(filter1, filter2), filter3);

If all three filters above need to be combined with and(), refer to the following example.
Filter badFilterEx = Filter.and(Filter.and(filter1, filter2), filter3); // Bad example for Filter
Filter goodFilterEx = Filter.and(filter1, filter2, filter3);

// Good example for Filter

If you want to make a filter for the specific property, refer to the following example.
Filter badFilterEx = Filter.or(
Filter.eq("Property1", "AAA"),
Filter.eq("Property1", "BBB"),
Filter.eq("Property1", "CCC"));
Filter goodFilterEx = Filter.in("Property1", {"AAA", "BBB", "CCC"});

// Bad example for Filter

// Good example for Filter

4.1.6. Updating Health Data


HealthResolve.UpdateRequest enables you to update specific health data of the specific data type. Only health
data that is inserted by your application can be updated. See required information below to update health data.
-

Data type

Health data that includes values for the specific properties to be updated

Filter to set the specific range to update

4.1.7. Deleting Health Data


Health data deletion is available with HealthResolve.DeleteRequest. Only health data that is inserted by your
application can be deleted. It requires following information.
Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 21

Samsung Digital Health - Health Data

Programming Guide

Data type

Unique IDs for health data to be deleted

If you want to specify the data range more, set a filter to DeleteRequest. Data IDs of the result can be used to
delete data.

4.1.8. Aggregation
The Data Framework provides useful aggregate functions to get statistical information. Available aggregate functions
are:
-

SUM

COUNT

AVG

MIN

MAX

You can add a group for the specific property of the data type with alias that make easy to figure the result value out.
Especially a time group with the specific time unit can be specified with
HealthDataResolver.Aggregate.TimeGroupUnit. Available time units and the value formation for each time
unit in the result are described in Table 4.
Unit

Value format in the result

Minutely

yyyy-mm-dd hh:mm
(e.g. 2014-10-09 18:17)

Hourly

yyyy-mm-dd hh
(e.g. 2014-10-09 18)

Daily

yyyy-mm-dd
(e.g. 2014-10-09)

Weekly

yyyy-ww
(e.g. 2014-41)

Monthly

yyyy-mm
(e.g. 2014-10)

Table 4: Time unit and the value format in the result


If you add a time unit group with Hourly as "hour" alias, the result for the aggregate request contains an "hour"
property with "yyyy-mm-dd hh" formatted values if the request is successful.

4.1.9. Data Normalization


The health data is stored based on the normalized unit as defined in International System of Unit (SI) in Table 6.
Item

Unit

Item

Unit

Height

cm

Calorie

Kcal

Weight

Kg

Sp3ed

m/h

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 22

Samsung Digital Health - Health Data

Programming Guide

Temperature

Celsius

Fat, visceral fat

Kg

Distance

Meter

Muscle mass

Kg

Blood glucose

mmol

Bone mass

Kg

HbA1c

Time

Millisecond

Blood Pressure

mmHg

Body water

Liter

Table 5: International System of Unit


It enables your application to read health data without the specific unit. It means that you need to be careful to unify
the data units when you insert health data to the health data store. HealthDataUnit helps to convert data value
between units.
If there is no required unit in HealthDataUnit, you can define and register a new unit as shown below.
import com.samsung.android.sdk.healthdata.*;
public class HealthDataUnitExample {
public static final CustomUnit CUSTOM = new CustomUnit();
void convertToCustom() {
CustomUnit unit = new CustomUnit();
HealthDataUnit.registerDataUnit(unit);
double custom = CUSTOM.convertTo(1.0d, HealthDataUnit.METER);
}
public static class CustomUnit extends HealthDataUnit {
CustomUnit() {
mUnit = "custom";
}
@Override
public double convertTo(double source, HealthDataUnit unit) {
final String unitString = unit.getUnitName();
if (unitString.equalsIgnoreCase("m")) {
return source * 2;
}
throw new UnknownFormatConversionException("No conversion is defined");
}
}
}

4.2.Health Data Type


Samsung Digital Health SDK provides useful predefined data types. Predefined data types of Samsung Digital Health
SDK are in Table 6.
Name

Description

HealthConstants.Weight

Historical records of user's weight

HealthConstants.BloodGlucose

The amount of glucose (sugar) present in blood

HealthConstants.HbA1c

Glycated hemoglobin data

HealthConstants.BloodPressure

The pressure exerted by circulating blood upon walls of blood


vessels

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 23

Samsung Digital Health - Health Data

Programming Guide

HealthConstants.BodyTemperature

Body temperature of user, known as normothermia or


euthermia

HealthConstants.HeartRate

Measured heart rate values represented in beats per minute

HealthConstants.Electrocardiogram

Electrical activity of the heart over a period of time

HealthConstants.OxygenSaturation

The oxygen saturation value of user

HealthConstants.StepCount

Accumulative count of steps over a short period of time


(binning)

HealthConstants.Sleep

Information about user sleep

HealthConstants.AmbientTemperature

Ambient temperature and humidity data around device

HealthConstants.UvExposure

Degree of exposure to ultraviolet(UV) radiated from the sun

HealthConstants.Exercise

Whole workout that user does for enhancing fitness and health

HealthConstants.WaterIntake

Records about how much and many times user takes water

HealthConstants.CaffeinIntake

Amount of caffeine intake

HealthConstants.FoodInfo

Set of particular food information such as nutrition and calorie

HealthConstants.FoodIntake

Records about how much user takes food and calories

Table 6: Predefined data types


All data types have the following mandatory properties in Table 7.
Property

Description
ID of health data.

UUID

Assigned by the system.


UTC time when data is created.

CREATED_TIME

Assigned by the system.


UTC time when data is updated.

UPDATED_TIME

Assigned by the system.


Application package name which provides data.

PACKAGE_NAME

Assigned by the system.

DEVICE_UUID

Device ID which provides health data

Table 7: Mandatory properties of health data


The manifest for the data type is composed of meta-data to present characteristics of the health data type. It is
defined as the XML schema. Table 8 shows each element description for the manifest.
Element
<manifest>

Description
Base element for the data type. Its attributes are shown below.
-

"id"

Data type ID
"import"

Indicates another "id" of another manifest to extend

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 24

Samsung Digital Health - Health Data

Programming Guide

"version"

<publisher>

Publisher name. Its attribute is shown below.


-

<documentation>

<title>

Indicates the version of the manifest. Its numeric. If there are manifests with different
version values, the higher version works.

"name": Name of publisher

Documentation section defines informational text. It has the following sub elements.
-

<title>

<description>

Title of the data type with the specific language code for localization. Its attribute is shown below.
-

"lang": It is composed of the following values. E.g. lang="en_US"

The language code with two-letter lowercase as defined by ISO 639-1.

The country code with two-letter uppercase as defined by ISO 3166-1.

The value of this element without the "lang" language attribute becomes the default title.
<description>

Description for the data type. Its attribute is as follows.


-

"lang": It is composed of the following values. E.g. lang="en_US"

The language code with two-letter lowercase as defined by ISO 639-1.

The country code with two-letter uppercase as defined by ISO 3166-1.

The value of this element without the "lang" language attribute becomes the default title.
<visibility>

Sharing scope of the data type. Its attribute is shown below.


-

<owner-app-list>
<package>
<policy>

"public"

"yes"(default) if the data type is shared to any application, or "no"

Specify <owner-app-list> as a sub element if its not public.

If the visibility is not public, you can list the allowed applications to access or extend this data type.
It has a <package> sub element.
Package name of the allowed application.
Data policy. Its attributes are shown below.
-

"lifetime": Datas lifetime in months. E.g. lifetime="72" (it means 6 years.)

"measurement": Measurement type which is one of the following values.

"discrete" for discretely measured data without the end time.

"session" for measured data with the end time which has a session.

"no": Not measured data

<medical-country>

"privacy": The privacy level which is one of the following values.

"insensitive": Data encryption is not required.

"sensitive": Data encryption is required. Its the default value.

"medical": Data encryption and listing allowed countries with <medical-country> are
required.

Need to write all allowed countries if the "privacy" attribute is "medical". It has the following
attribute and allowed country code values.

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 25

Samsung Digital Health - Health Data

Programming Guide

"allowed"

"yes": If all allowed counties are written.

"no": If all prohibited countries are written.

<property>

Allowed or prohibited country codes with two-letter uppercase as defined by ISO 3166-1.

Use comma "," as the delimiter between country codes.

E.g. <policy lifetime="72" measurement="discrete" privacy="medical">


<medical-country allowed="no"> AO, GB, IE</medical-country>
</policy>

Defines detailed information for each property of this data type including the default value,
validation range, title and description. Its attributes are shown below.
-

"name"

"type"

One of "int", "long", "float", "double", "text", and "blob"


"mandatory"

The default value is "no".

"yes" if the property is a mandatory property for the data type. Be careful not to make the
property as "yes" if you add a new property to update your application.

If the property is defined as mandatory, the value for the property has to be specified when
new data is inserted.

"unique"

The default value is "no".

"yes" if the data value needs to be unique

<default-value>

Default value of the property to be filled when a new health data is inserted without value
specification

<validation>

Validation range
-

"min"

"max"

The maximum value if the type is numeric


"minLength"

The minimum length if the type is text


"maxLength"

<documentation>

The minimum value if the type is numeric

The maximum length if the type is text

Description for the property of the data type.

Table 8: Manifest definition


An example below shows the manifest definition for the health data type.

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 26

Samsung Digital Health - Health Data


0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

Programming Guide

<?xml version="1.0" encoding="UTF-8"?>


<manifest xmlns="http://schemas.samsung.com/2014/10/iot"
id="com.samsung.health.blood_glucose"
version="1">
<publisher name="Samsung Electronics Co., Ltd."/>
<documentation>
<title>Blood Glucose</title>
<title lang="es_US">Glucosa en la sangre</title>
</documentation>
<visibility public="yes" />
<policy lifetime="72" measurement="discrete" privacy="medical">
<!-- AO (Angola), GB (United Kingdom), IE (Ireland), FR (France), NL (Netherland),
BE (Belgium), LU (Luxembourg), AT (Austria), SK (Slovak), GR (Greece), CY (Cyprus),
SI (Slovenia), DZ (Algeria), IR (Iran), CA (Canada), KR (Korea) -->
<medical-country allowed="no">AO, GB, IE, FR, NL, BE, LU, AT, SK, GR, CY, SI, DZ, IR, CA,
KR</medical-country>
</policy>
<property name="datauuid" mandatory="yes" type="text" unique="yes">
<validation minLength="10" maxLength="36"/>
<documentation>
<title>Unique ID</title>
<description>Unique ID</description>
</documentation>
</property>
...
<property name="start_time" mandatory="yes" type="long">
<documentation>
<title>Start time</title>
<description>When the measurement was taken</description>
</documentation>
</property>
<property name="time_offset" mandatory="yes" type="long">
<documentation>
<title>Time offset</title>
<description>Time zone in which data is entered</description>
</documentation>
</property>
...
</manifest>

Its detailed description is as follows.


-

Line 1: manifest schema version

Line 2: data type ID

Line 5-8: documentation for this data type

Line 6: data type name with the default language attribute

Line 7: data type name with the specific language attribute

Line 9: visibility of this data type

Line 10-16: data policy with its lifetime, measurement type, privacy level

Line 14: Prohibited country codes

Line 18-39: property definition

Line 18: Name, mandatory option, data type, and unique option for the property

Line 18: validation range of value

Line 19: Property description

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 27

Samsung Digital Health - Health Data

Programming Guide

4.3.Privacy
Privacy is a key for handling health data. Samsung Digital Health enables your application to access health data based
on users consent. An application needs to declare proper permissions for handling required health data types and to
handle SecureException when the application cannot gain user consent because user can withdraw consent at
any time. See 5.2 on details for permission declaration.
Declared permissions in manifest can be checked in the user permission menu of Settings of S Health or applications
as in Figure 9. The permission menu shows declared all the data types and user may change permission for each data
type at any time. When a permission API is called in an application, the Data Framework shows permissions related
to the requested permission API only. The flow can be preceded after user approves or denies the data type usage.
User consent is limited to the device. Even if multiple devices use the same Samsung account, the application has to
acquire user consent on each device independently.

Figure 9: Privacy and user permission

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 28

Samsung Digital Health - Health Data

Programming Guide

5. Use Cases
Useful examples to develop an application are as follows.
-

Connecting to HealthDataStore

Acquiring user permission

Inserting data

Updating data

Deleting data

Reading data

Aggregating data

Observing change

5.1.Connecting to HealthDataStore
An application has to connect to HealthDataStore to handle health data. Other APIs work after the health data
store is connected successfully. Its sequence is shown below.
1) Implement the HealthDataStore.ConnectionListener interface.
2) Create a HealthDataStore instance.
3) Call connectService() to connect to health service.
4) After receiving the onConnected() callback, other APIs work properly.
: ConnectionListener

: Application

: HealthDataStore

<<implement>>
1
<<create>>
2

3 : connectService()

4 : onConnected()

Figure 10: Sequence diagram for connecting to health data store


Its example code is shown below.
Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 29

Samsung Digital Health - Health Data

Programming Guide

import com.samsung.android.sdk.healthdata.*;
public class MainActivity extends Activity {
private HealthDataStore mStore;
@Override
public void onCreate(Bundle savedInstanceState) {
HealthDataService healthDataService = new HealthDataService();
try {
healthDataService.initialize(this);
} catch (Exception e) {
// Handles exceptions
}
mStore = new HealthDataStore(this, mConnectionListener);
mStore.connectService();
}
@Override
public void onDestroy() {
mStore.disconnectService();
}
private final HealthDataStore.ConnectionListener mConnectionListener = new
HealthDataStore.ConnectionListener() {
@Override
public void onConnected() {
// The connection is successful.
}
@Override
public void onConnectionFailed(HealthConnectionErrorResult error) {
// The connection fails.
error.resolve(mInstance);
}
@Override
public void onDisconnected() {
// The connection is disconnected.
}
};
}

5.2.Acquiring user permission


Users health data is private information of user and it needs be handled carefully. An application needs to acquire
user permission before accessing health data. Its sequence is shown below.
1) Implement the HealthResultHolder.ResultListener<PermissionResult> interface.
2) Create a HealthPermissionManager instance.
3) Add required permission set and call isPermissionAcquired().
4) If user permission is not acquired yet, call requestPermissions().

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 30

Samsung Digital Health - Health Data

Programming Guide

5) The Data Framework makes the user to select the allowance for the requested permission. If the user consents,
the application can access data.

Figure 11: Sequence diagram for acquiring user permission


Its example code is shown below.
import com.samsung.android.sdk.healthdata.*;
public class MainActivity extends Activity {
private HealthDataStore mStore;
private PermissionKey mPermissionKey;
private void requestUserPermission() {
HealthPermissionManager pmsManager = new HealthPermissionManager(mStore);
try {
// Check whether the permissions that this application needs are acquired
mPermissionKey = new PermissionKey(HealthConstants.StepCount.HEALTH_DATA_TYPE,
PermissionType.READ);
Set<PermissionKey> keySet = new HashSet<PermissionKey>();
keySet.add(mPermissionKey);
Map<PermissionKey, Boolean> resultMap = pmsManager.isPermissionAcquired(keySet);
if (resultMap.get(mPermissionKey) == Boolean.TRUE) {
// User permission is already acquired.
} else {
// Request the permission for reading the count of steps if it is not acquired
pmsManager.requestPermissions(keySet).setResultListener(mPermissionListener);
}
} catch (Exception e) {
// Error handling
}
}
Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 31

Samsung Digital Health - Health Data

Programming Guide

private final HealthResultHolder.ResultListener<PermissionResult> mPermissionListener =


new HealthResultHolder.ResultListener<PermissionResult>() {
@Override
public void onResult(PermissionResult result) {
Map<PermissionKey, Boolean> resultMap = result.getResultMap();
if (resultMap.get(mPermissionKey) == Boolean.FALSE) {
// Requested permission is not acquired.
} else {
// Requested permission is acquired, so the application can access data.
}
}
};
}

To access health data, the application needs to get user permission. You need to call the permission request API, and
the application needs to specify data types on its manifest file. If the required data type is missing on its manifest file,
the user permission API fails.
Permissions to read and write are different entities. If the application needs to declare permission for multiple data
types, use semicolon (;). The following example shows manifest to declare permissions for reading and writing.
<meta-data
android:name="com.samsung.android.health.permission.read"
android:value="com.samsung.health.blood_pressure;com.samsung.health.heart_rate" />
<meta-data
android:name="com.samsung.android.health.permission.write"
android:value="com.samsung.health.heart_rate" />

5.3.Inserting data
An application can insert created data into the health data storage. The data request works either synchronously or
asynchronously. See 4.1.2 for additional information. Make sure not to make the synchronous request on the UI
thread. The sequence for the asynchronous request is shown below.
1) Implement the HealthResultHolder.ResultListener<BaseResult> interface.
2) Create a HealthDataResolver.InsertRequest instance.
3) Add a HealthData instances to InsertRequest.
4) Create a HealthDataResolver instance.
5) Call insert() to insert data.
6) The application can check the result asynchronously on the onResult() callback.

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 32

Samsung Digital Health - Health Data

Programming Guide

: ResultListener <BaseResult>

: InsertRequest

: HealthDataResolver

: Application
<<implement>>
1

<<create>>
2

3 : addHealthData()
<<create>>
4

5 : insert()

6 : onResult()

Figure 12: Sequence diagram for inserting data


Its example code is shown below.
import com.samsung.android.sdk.healthdata.*;
private void insertGlucose(long start, long offset, int value) {
HealthDataResolver resolver = new HealthDataResolver(mStore, null);
HealthData data = new HealthData();
// all mandatory properties should be filled out
data.putLong(HealthConstants.BloodGlucose.START_TIME, start);
data.putLong(HealthConstants.BloodGlucose.TIME_OFFSET, offset);
data.putInt(HealthConstants.BloodGlucose.GLUCOSE, value);
data.putInt(HealthConstants.BloodGlucose.MEASUREMENT_TYPE,
HealthConstants.BloodGlucose.MEASUREMENT_TYPE_WHOLE_BLOOD);
HealthDataResolver.InsertRequest request = new HealthDataResolver.InsertRequest.Builder()
.setDataType(HealthConstants.BloodGlucose.HEALTH_DATA_TYPE)
.build();
try {
// register the local device with the data if it is not registered
data.setSourceDevice(new HealthDeviceManager(mStore).getLocalDevice().getUuId());
request.addHealthData(data);
resolver.insert(request).setResultListener(mResultListener);
} catch (Exception e) {
// Error handling
}
}
Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 33

Samsung Digital Health - Health Data

Programming Guide

private final HealthResultHolder.ResultListener<BaseResult> mResultListener = new


HealthResultHolder.ResultListener<BaseResult>() {
@Override
public void onResult(BaseResult result) {
// Check the result
}
};

5.4.Updating data
An application can update data on the health data storage. The data request works either synchronously or
asynchronously. See 4.1.2 for additional information. Make sure not to make the synchronous request on the UI
thread. Only health data that is inserted by your application can be updated. The following example shows how to
update the food amount of existing health data. Its sequence for the asynchronous request is shown below.
1) Implement the HealthResultHolder.ResultListener<BaseResult> interface.
2) Create a HealthDataResolver.UpdateRequest instance and set a filter.
3) Create a HealthDataResolver instance.
4) Call update().
5) The application can check the result asynchronously on the onResult() callback.

: ResultListener <BaseResult>

: UpdateRequest

: HealthDataResolver

: Application
<<implement>>
1

<<new>>
2

<<create>>
3

4 : update()

5 : onResult()

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 34

Samsung Digital Health - Health Data

Programming Guide

Figure 13: Sequence diagram for updating data


Its example code is shown below.
import com.samsung.android.sdk.healthdata.*;

private void updateFood(float origAmount, float updatedAmount) {


HealthDataResolver resolver = new HealthDataResolver(mStore, null);
try {
HealthData data = new HealthData();
data.setSourceDevice(new HealthDeviceManager(mStore).getLocalDevice().getUuId());
data.putFloat(HealthConstants.FoodIntake.AMOUNT, updatedAmount);
Filter filter = Filter.eq(HealthConstants.FoodIntake.AMOUNT, origAmount);
UpdateRequest request = new UpdateRequest.Builder()
.setDataType(HealthConstants.FoodIntake.HEALTH_DATA_TYPE)
.setFilter(filter)
.setHealthData(data)
.build();
resolver.update(request).setResultListener(mResultListener);
} catch (Exception e) {
// Error handling
}
}
private final HealthResultHolder.ResultListener<BaseResult> mResultListener = new
HealthResultHolder.ResultListener<BaseResult>() {
@Override
public void onResult(BaseResult result) {
// Check the result
}
};

5.5.Deleting data
An application can delete data on the health data storage. The data request works either synchronously or
asynchronously. See 4.1.2 for additional information. Make sure not to make the synchronous request on the UI
thread. Only health data that is inserted by your application can be deleted. Its sequence for the asynchronous
request is shown below.
1) Implement the HealthResultHolder.ResultListener<BaseResult> interface.
2) Create a HealthDataResolver.DeleteRequest instance.
3) Set "datauuids" to be deleted.
4) Create a HealthDataResolver instance.
5) Call delete().
6) The application can check the result asynchronously on the onResult() callback.
Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 35

Samsung Digital Health - Health Data

Programming Guide

: ResultListener <BaseResult>

: Application

: DeleteRequest

: HealthDataResolver

<<implement>>
1

<<new>>
2

3 : deleteHealthData()

<<new>>
4
5 : delete()

6 : onResult()

Figure 14: Sequence diagram for deleting data


Its example code is shown below.
import com.samsung.android.sdk.healthdata.*;

private void deleteWeight(List<String> datauuidList) {


HealthDataResolver resolver = new HealthDataResolver(mStore, null);
try {
Filter filter = Filter.in(HealthConstants.Weight.UUID, datauuidList.toArray(new String[0]));
DeleteRequest request = new DeleteRequest.Builder()
.setDataType(HealthConstants.Weight.HEALTH_DATA_TYPE)
.setFilter(filter)
.build();
resolver.delete(request).setResultListener(mResultListener);
} catch (Exception e) {
// Error handling
}
}
private final HealthResultHolder.ResultListener<BaseResult> mResultListener = new
HealthResultHolder.ResultListener<BaseResult>() {
@Override
public void onResult(BaseResult result) {
// Check the result
}
Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 36

Samsung Digital Health - Health Data

Programming Guide

};

5.6.Reading data
An application can read data on the health data storage. The data request works either synchronously or
asynchronously. See 4.1.2 for additional information. Make sure not to make the synchronous request on the UI
thread. The sequence for the asynchronous request is shown below.
1) Implement the HealthResultHolder.ResultListener<ReadResult> interface.
2) Create a HealthDataResolver.ReadRequest instance.
3) Create a HealthDataResolver instance.
4) Call read().
5) The application can check the result asynchronously on the onResult() callback. If the request is successful,
the application gets Cursor that contains the result.

: ResultListener <ReadResult>

: Application

: ReadRequest

: HealthDataResolver

<<implement>>
1

<<new>>
2

<<new>>
3

4 : read()

5 : onResult()

Figure 15: Sequence diagram for querying data


Its example code is shown below.
import com.samsung.android.sdk.healthdata.*;
Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 37

Samsung Digital Health - Health Data

Programming Guide

private void readStepCount(long from, long to) {


HealthDataResolver resolver = new HealthDataResolver(mStore, null);
Filter filter = Filter.lessThan(HealthConstants.StepCount.DIATNACE, 100);
try {
ReadRequest request = new ReadRequest.Builder()
.setDataType(HealthConstants.StepCount.HEALTH_DATA_TYPE)
.setFilter(filter)
.build();
resolver.read(request).setResultListener(mReadResultListener);
} catch (Exception e) {
// Error handling
}
}
private final HealthResultHolder.ResultListener<ReadResult> mReadResultListener = new
HealthResultHolder.ResultListener<ReadResult>() {
@Override
public void onResult(ReadResult result) {
// Check and get result
if (BaseResult.STATUS_SUCCESSFUL == result.getStatus()) {
Cursor cursor = result.getResultCursor();
}
}
};

5.7.Aggregating data
An application can aggregate health data with frequently used aggregate functions like average or sum. The data
request works either synchronously or asynchronously. See 4.1.2 for additional information. Make sure not to make
the synchronous request on the UI thread. The sequence for the asynchronous request is shown below.
1) Implement the HealthResultHolder.ResultListener<AggregateResult> interface.
2) Create a HealthDataResolver.AggregateRequest instance.
3) Create a HealthDataResolver instance.
4) Call aggregate().
5) The application can check the result asynchronously on the onResult() callback. If the request is successful,
the application gets Cursor that contains the result.

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 38

Samsung Digital Health - Health Data

Programming Guide

: ResultListener <AggregateResult>

: Application

: AggregateRequest

: HealthDataResolver

<<implement>>
1

<<new>>
2

<<new>>
3

4 : aggregate()

5 : onResult()

Figure 16: Sequence diagram for aggregating data


Its example code is shown below.
import com.samsung.android.sdk.healthdata.*;

private void readDailyGlucoseAverage(long from, long to) {


HealthDataResolver resolver = new HealthDataResolver(mStore, null);
AggregateRequest request = new AggregateRequest.Builder()
.setDataType(HealthConstants.BloodGlucose.HEALTH_DATA_TYPE)
.addFunction(AggregateFunction.AVG, HealthConstants.BloodGlucose.GLUCOSE, "average")
.setTimeGroup(TimeGroupUnit.DAILY, 1, HealthConstants.BloodGlucose.START_TIME,
HealthConstants.BloodGlucose.TIME_OFFSET, "days")
.setSort("days", SortOrder.DESC)
.build();
try {
resolver.aggregate(request).setResultListener(mAggregateResultListener);
} catch (Exception e) {
// Error handling
}
}
private final HealthResultHolder.ResultListener<AggregateResult> mAggregateResultListener = new
HealthResultHolder.ResultListener<AggregateResult>() {
@Override
public void onResult(AggregateResult result) {
// Check and get result
if (BaseResult.STATUS_SUCCESSFUL == result.getStatus()) {
Cursor cursor = result.getResultCursor();
}
}
};
Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 39

Samsung Digital Health - Health Data

Programming Guide

5.8.Observing change
An application can observe changes in the health data storage. If observed data type is changed, notification is
received in its callback. The sequence is shown below.
1) Implement the HealthDataObserver listener.
2) Call addObserver() to add an observer for the specific health data type.
3) If the observed data type is changed, the application receives notification in the onChange() callback.

: HealthDataObserver

: Application

: Platform
<<implement>>
1

2 : addObserver()

3 : onChange()

Figure 17 Sequence diagram for observing change


Its example code is shown below.
import com.samsung.android.sdk.healthdata.*;
private void addStepCountObserver() {
HealthDataObserver.addObserver(mStore, HealthConstants.StepCount.HEALTH_DATA_TYPE, mObserver);
}
private final HealthDataObserver mObserver = new HealthDataObserver(null) {
@Override
public void onChange(String dataTypeName) {
// Changed callback
}
};

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 40

Samsung Digital Health - Health Data

Programming Guide

6. Sample Applications
6.1.SimpleHealth
Samsung Digital Health SDK provides SimpleHealth as a sample application. SimpleHealth demonstrates how to use
the APIs for Samsung Digital Health to retrieve and show the count of steps in today including a process to get
permission to read HealthConstants.StepCount health data.
Prerequisites to run SimpleHealth are shown below.
-

Prepare a device that supports Android 4.4KitKat (API level 19) or above.

Install HealthDevApp in the device.

Figure 18 shows its screenshots.

Figure 18: Screenshots of SimpleHealth


Descriptions for each source file are shown below.
File

Description
It contains following operations.

MainActivity.java

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Connects to the health data store.

Checks permission to read


HealthConstants.StepCount and requests
permission if required.

Page | 41

Samsung Digital Health - Health Data

Programming Guide

Provides an option menu for the permission setting.

It contains following operations.

StepCountReporter.java

Gets todays the total count of steps and show it.

Adds an observer to get notification for the count of steps


change.

Applies changed the count of steps to the text box of


MainActivity.

6.1.1. MainActivity
MainActivity is derived from Android Activity. It connects to the health data store and requests permission to read
the HealthConstants.StepCount data type from the data store. It also provides an option menu for the
permission setting to check the status for step count data.

Connecting to Health Data Store


The code below shows how to connect to the health data store.
public class MainActivity extends Activity {
public static final String APP_TAG = "SimpleHealth";
private final int MENU_ITEM_PERMISSION_SETTING = 1;
private
private
private
private

static MainActivity mInstance = null;


HealthDataStore mStore;
Set<PermissionKey> mKeySet;
StepCountReporter mReporter;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mInstance = this;
mKeySet = new HashSet<PermissionKey>();
mKeySet.add(new PermissionKey(HealthConstants.StepCount.HEALTH_DATA_TYPE, PermissionType.READ));
HealthDataService healthDataService = new HealthDataService();
try {
healthDataService.initialize(this);
} catch (Exception e) {
// Handles exceptions
}
// Create a HealthDataStore instance and set its listener
mStore = new HealthDataStore(this, mConnectionListener);
// Request the connection to the health data store
mStore.connectService();
}
@Override
public void onDestroy() {
mStore.disconnectService();
super.onDestroy();
}

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 42

Samsung Digital Health - Health Data

Programming Guide

Checking Permission and Requesting Permission


The code below shows how to check and request permission for HealthConstants.StepCount.
private final HealthDataStore.ConnectionListener mConnectionListener =
new HealthDataStore.ConnectionListener() {
@Override
public void onConnected() {
Log.d(APP_TAG, "Health data service is connected.");
HealthPermissionManager pmsManager = new HealthPermissionManager(mStore);
mReporter = new StepCountReporter(mStore);
try {
// Check whether the permissions that this application needs are acquired
Map<PermissionKey, Boolean> resultMap = pmsManager.isPermissionAcquired(mKeySet);
if (resultMap.containsValue(Boolean.FALSE)) {
// Request the permission for reading the count of steps if it is not acquired
pmsManager.requestPermissions(keySet).setResultListener(mPermissionListener);
} else {
// Get the count of current steps and display it
mReporter.start();
}
} catch (Exception e) {
Log.e(APP_TAG, e.getClass().getName() + " - " + e.getMessage());
Log.e(APP_TAG, "Permission setting fails.");
}
}
// ...
};
private final HealthResultHolder.ResultListener<PermissionResult> mPermissionListener =
new HealthResultHolder.ResultListener<PermissionResult>() {
@Override
public void onResult(PermissionResult result) {
Log.e(APP_TAG, "Permission callback is received.");
Map<PermissionKey, Boolean> resultMap = result.getResultMap();
if (resultMap.containsValue(Boolean.FALSE)) {
drawStepCount("");
showPermissionAlarmDialog();
} else {
// Get the count of current steps and display it
mReporter.start();
}
}
};

Permission Setting Menu


The code below shows the permission setting menu.
private void showPermissionAlarmDialog() {
if (isFinishing()) {
return;
}
AlertDialog.Builder alert = new AlertDialog.Builder(MainActivity.this);
alert.setTitle("Notice");
alert.setMessage("All permission should be acquired");
Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 43

Samsung Digital Health - Health Data

Programming Guide

alert.setPositiveButton("OK", null);
alert.show();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(1, MENU_ITEM_PERMISSION_SETTING, 0, "Permission Setting");
return true;
}
@Override
public boolean onOptionsItemSelected(android.view.MenuItem item) {
if (item.getItemId() == (MENU_ITEM_PERMISSION_SETTING)) {
HealthPermissionManager pmsManager = new HealthPermissionManager(mStore);
try {
// Show user permission UI for allowing user to change options
pmsManager.requestPermissions(mKeySet).setResultListener(mPermissionListener);
} catch (Exception e) {
Log.e(APP_TAG, e.getClass().getName() + " - " + e.getMessage());
Log.e(APP_TAG, "Permission setting fails.");
}
}
return true;
}

6.1.2. StepCountReporter
StepCountReporter interacts with HealthDataResolver and HealthContentObserver objects to get today's
total step count and updates the step count change to MainActivity. HealthDataResolver is used to read the step
count data for today. HealthContentObserver is used to observe a change for steps.

Reading the Count of Steps in Today


The code below shows how to read todays step count.
public class StepCountReporter {
private final HealthDataStore mStore;
public StepCountReporter(HealthDataStore store) {
mStore = store;
}
public void start() {
// Register an observer to listen changes of step count and get today step count
HealthDataObserver.addObserver(mStore, HealthConstants.StepCount.HEALTH_DATA_TYPE, mObserver);
readTodayStepCount();
}
// Read the today's step count on demand
private void readTodayStepCount() {
HealthDataResolver resolver = new HealthDataResolver(mStore, null);
// Set time range from start time of today to the current time
long startTime = getStartTimeOfToday();
long endTime = System.currentTimeMillis();
Filter filter = Filter.and(Filter.greaterThanEquals(HealthConstants.StepCount.START_TIME,
startTime),
Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 44

Samsung Digital Health - Health Data

Programming Guide
Filter.lessThanEquals(HealthConstants.StepCount.START_TIME,
endTime));

HealthDataResolver.ReadRequest request = new ReadRequest.Builder()


.setDataType(HealthConstants.StepCount.HEALTH_DATA_TYPE)
.setFilter(filter)
.build();
try {
resolver.read(request).setResultListener(mListener);
} catch (Exception e) {
Log.e(MainActivity.APP_TAG, e.getClass().getName() + " - " + e.getMessage());
Log.e(MainActivity.APP_TAG, "Getting step count fails.");
}
}
private long getStartTimeOfToday() {
Calendar today = Calendar.getInstance();
today.set(Calendar.HOUR_OF_DAY, 0);
today.set(Calendar.MINUTE, 0);
today.set(Calendar.SECOND, 0);
today.set(Calendar.MILLISECOND, 0);
return today.getTimeInMillis();
}
private final HealthResultHolder.ResultListener<ReadResult> mListener =
new HealthResultHolder.ResultListener<ReadResult>() {
@Override
public void onResult(ReadResult result) {
int count = 0;
Cursor c = null;
try {
c = result.getResultCursor();
if (c != null) {
while (c.moveToNext()) {
count += c.getInt(c.getColumnIndex(HealthConstants.StepCount.COUNT));
}
}
} finally {
if (c != null) {
c.close();
}
}
MainActivity.getInstance().drawStepCount(String.valueof(count));
}
};
// ...
}

Observation for Step Count Change


The code below shows how to add an observer for step count change.
public class StepCountReporter {
private final HealthDataStore mStore;
public StepCountReporter(HealthDataStore store) {
mStore = store;
}
Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 45

Samsung Digital Health - Health Data

Programming Guide

public void start() {


// Register the observer to listen changes of step count and get today step count
HealthDataObserver.addObserver(mStore, HealthConstants.StepCount.HEALTH_DATA_TYPE, mObserver);
readTodayStepCount();
}
//...
private final HealthDataObserver mObserver = new HealthDataObserver(null) {
// Update the step count when a change event is received
@Override
public void onChange(String dataTypeName) {
Log.d(MainActivity.APP_TAG, "Observer receives a data changed event");
readTodayStepCount();
}
};
}

6.2.FoodNote
Samsung Digital Health SDK provides FoodNote as a sample application. FoodNote demonstrates how to use the APIs
for Samsung Digital Health to check the selected days calorie intake including getting permission to read and write
health data for HealthConstants.FoodIntake and HealthConstants.FoodInfo.
Prerequisites to run FoodNote are shown below.
-

Prepare a device that supports Android 4.4 KitKat (API level 19) or above.

Install HealthDevApp in the device.

Figure 19 shows its screenshots.

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 46

Samsung Digital Health - Health Data

Programming Guide

Figure 19: Screenshots of FoodNote


Descriptions for each source file are shown below.
File

MainActivity.java

ChooseFoodActivity.java

MealStoreActivity.java

FoodDataHelper.java

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Description
-

Connects to the health data store.

Checks permission for HealthConstants.FoodInfo


and HealthConstants.FoodIntake, and requests
permission if required.

Provides an option menu for the permission setting.

Shows the selected days calorie intake.

Adds an observer to get notification for the calories


change.

Loads the food list with FoodInfoTable class.

Choose the food from the food list.

Shows the selected days calories based on meal types.

Deletes food intake data after choosing the food item in


the food list.

Inserts food intake data

Deletes food intake data

Reads and shows food intake data of the selected day and
the meal type

Page | 47

Samsung Digital Health - Health Data

Programming Guide

6.2.1. MainActivity
MainActivity is derived from Android Activity. It connects to the health data store and requests permission to read,
write the HealthConstants.FoodIntake data type from the data store. And it provides an option menu for the
permission setting to access food intake and food info data.

Connecting to Health Data Store


The code below shows how to connect to the health data store.
public class MainActivity extends Activity implements FoodDataHelper.DailyCaloriesCallback {
// ...
private static final SimpleDateFormat INDEXTIME_FORMAT = new SimpleDateFormat("yyyy/MM/dd (E)",
Locale.US);
private static final int MENU_ITEM_PERMISSION_SETTING = 1;
private static MainActivity mInstance = null;
private HealthDataStore mStore;
private FoodDataHelper mDataHelper;
private long mDayStartTime;
private TextView mDayTv;
Set<PermissionKey> mPermissionkeySet = new HashSet<PermissionKey>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ...
HealthDataService healthDataService = new HealthDataService();
try {
healthDataService.initialize(this);
} catch (Exception e) {
// Handles exceptions
}
// Create a HealthDataStore instance and set its listener
mStore = new HealthDataStore(this, mConnectionListener);
mDataHelper = new FoodDataHelper(mStore, getBaseContext());
// Add the read and write
mPermissionkeySet.add(new
mPermissionkeySet.add(new
mPermissionkeySet.add(new
mPermissionkeySet.add(new

permissions to mPermissionKeySet
PermissionKey(FoodIntake.HEALTH_DATA_TYPE, PermissionType.READ));
PermissionKey(FoodIntake.HEALTH_DATA_TYPE, PermissionType.WRITE));
PermissionKey(FoodInfo.HEALTH_DATA_TYPE, PermissionType.READ));
PermissionKey(FoodInfo.HEALTH_DATA_TYPE, PermissionType.WRITE));

// Request the connection to the health data store


mStore.connectService();
}
@Override
public void onDestroy() {
HealthDataObserver.removeObserver(mStore, mObserver);
mStore.disconnectService();
super.onDestroy();
}
@Override
public void onResume() {
super.onResume();
try {
mDataHelper.readDailyIntakeCalories(MainActivity.this, mDayStartTime);
} catch (Exception e) {
Log.e(TAG, e.getClass().getName() + " - " + e.getMessage());
Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 48

Samsung Digital Health - Health Data

Programming Guide

}
}
public static MainActivity getInstance() {
return mInstance;
}
public FoodDataHelper getFoodDataHelper() {
return mDataHelper;
}
private final HealthDataStore.ConnectionListener mConnectionListener =
new HealthDataStore.ConnectionListener() {
@Override
public void onConnected() {
Log.d(TAG, "onConnected");
HealthPermissionManager pmsManager = new HealthPermissionManager(mStore);
Map<PermissionKey, Boolean> permissionMap =
pmsManager.isPermissionAcquired(mPermissionkeySet);
// Check the permissions acquired or not
if (permissionMap.containsValue(Boolean.FALSE)) {
requestPermissions();
}
// Show the intake calories of the given day
mDataHelper.readDailyIntakeCalories(MainActivity.this, mDayStartTime);
}
@Override
public void onConnectionFailed(HealthConnectionErrorResult error) {
Log.d(TAG, "onConnectionFailed");
// Set an activity to resolve the error
error.resolve(MainActivity.this);
}
@Override
public void onDisconnected() {
Log.d(TAG, "onDisconnected");
}
};

Checking Permission and Requesting Permission


The code below shows how to check and request permission for HealthConstants.FoodIntake and
HealthConstants.FoodInfo.
private void requestPermissions() {
HealthPermissionManager pmsManager = new HealthPermissionManager(mStore);
try {
// Show user permission UI for allowing user to change options
pmsManager.requestPermissions(mPermissionkeySet).setResultListener(mPermissionListener);
} catch (Exception e) {
Log.e(TAG, e.getClass().getName() + " - " + e.getMessage());
Log.e(TAG, "Permission setting fails.");
}
}
private final HealthResultHolder.ResultListener<PermissionResult> mPermissionListener =
new HealthResultHolder.ResultListener<PermissionResult>() {
@Override
public void onResult(PermissionResult result) {
Map<PermissionKey, Boolean> resultMap = result.getResultMap();
Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 49

Samsung Digital Health - Health Data

Programming Guide

// Show a permission alarm and initializes the calories if permissions are not acquired
if (resultMap.values().contains(Boolean.FALSE)) {
showPermissionAlarmDialog();
} else {
// Get the calories of Indexed time and display it
mDataHelper.readDailyIntakeCalories(MainActivity.this, mDayStartTime);
// Register an observer to listen changes of the calories
HealthDataObserver.addObserver(mStore, FoodIntake.HEALTH_DATA_TYPE, mObserver);
}
}
};
private void showPermissionAlarmDialog() {
if (isFinishing()) {
return;
}
AlertDialog.Builder alert = new AlertDialog.Builder(MainActivity.this);
alert.setTitle("Notice");
alert.setMessage("All permissions must be acquired");
alert.setPositiveButton("OK", null);
alert.show();
}

Permission Setting Menu


The code below shows the permission setting menu.
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(1, MENU_ITEM_PERMISSION_SETTING, 0, "Permission Setting");
return true;
}
@Override
public boolean onOptionsItemSelected(android.view.MenuItem item) {
if (item.getItemId() == (MENU_ITEM_PERMISSION_SETTING)) {
requestPermissions();
}
return true;
}

6.2.2. ChooseFoodActivity
ChooseFood interacts with the HealthDataResolver object in FoodDataHelper to insert the selected food
calories with the number of intake and apply the changed calories to MealStore.
The code below shows how to choose the food from FoodInfo class and Input the number of intake.
public class ChooseFoodActivity extends Activity {
// ...
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get the intake day and meal type from Android Intent
Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 50

Samsung Digital Health - Health Data

Programming Guide

mIntakeDay = getIntent().getExtras().getLong(AppConstants.BUNDLE_KEY_INTAKE_DAY);
mMealType = getIntent().getExtras().getInt(AppConstants.BUNDLE_KEY_MEAL_TYPE);
// ...
// Load the FoodList from FoodInfoTable class
List<String> foodNameArray = new ArrayList<String>();
foodNameArray.addAll(FoodInfoTable.keySet());
Collections.sort(foodNameArray);
// ...
// Show a Dialog to set intake times, after tap the food from food list
nameListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mSelectedFoodType = ((TextView) view).getText().toString();
AlertDialog.Builder intakeDialogBuiler = createDialogBuilder();
intakeDialogBuiler.show();
}
});
}
private AlertDialog.Builder createDialogBuilder() {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
// Set EditText of the dialog
final EditText input = new EditText(this);
dialogBuilder.setTitle(R.string.editTextTitle);
dialogBuilder.setMessage(mSelectedFoodType + " : "
+ FoodInfoTable.get(mSelectedFoodType).calorie + " kcals/time");
dialogBuilder.setView(input);
input.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
dialogBuilder.setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// Take the String value (intake count) from EditText
String takeCount = input.getText().toString();
// Check for null or "0" value
if (!takeCount.isEmpty() && !("0".equals(takeCount))) {
FoodDataHelper dataHelper = MainActivity.getInstance().getFoodDataHelper();
dataHelper.insertFoodInfo(mSelectedFoodType, Float.valueOf(takeCount), mMealType,
mIntakeDay);
}
}
});
return dialogBuilder;
}
}

6.2.3. MealStoreActivity
MealStoreActivity interacts with the HealthDataResolver object in the FoodDataHelper class to get and delete the
calories and updates the calories.
The code below shows how to delete selected food from food intake data.
public class MealStoreActivity extends Activity implements FoodDataHelper.MealDetailsCallback {
// ...
Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 51

Samsung Digital Health - Health Data

Programming Guide

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get the intake day and meal type from Android Intent
mIntakeDay = getIntent().getExtras().getLong(AppConstants.BUNDLE_KEY_INTAKE_DAY);
mMealType = getIntent().getExtras().getInt(AppConstants.BUNDLE_KEY_MEAL_TYPE);
// ...
mDataHelper = MainActivity.getInstance().getFoodDataHelper();
// Get the cached food intake data
mDataHelper.readDailyIntakeDetails(MealStoreActivity.this, mIntakeDay, mMealType);
// ...
findViewById(R.id.delete).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.delete:
int id = mCachedFoodListView.getCheckedItemPosition();
if (id != ListView.INVALID_POSITION) {
// Get the food intake UUID from mFoodNameArray
String selectedUuid = mIntakeUuidArray.get(id);
// Delete the selected food by the foodintake UUID
mDataHelper.deleteFoodIntake(selectedUuid);
if (!mFoodNameArray.get(id).trim().contains("(Not Deletable)")) {
mFoodNameArray.remove(id);
}
mFoodNameArray.remove(id);
// Read the food intake data after deletion
mDataHelper.readDailyIntakeDetails(MealStoreActivity.this,
mIntakeDay, mMealType);
// Change the UI, after deletion
mCachedFoodListView.clearChoices();
mNameArrayAdapter.notifyDataSetChanged();
}
break;
}
}
});
}
}

6.2.4. FoodDataHelper
Inserting Food Intake Data
The code below shows how to insert food intake data.
public void insertFoodInfo(String foodName) {
HealthData data = new HealthData();
// Get the FoodInfoTable's key from the selected food name to use nutrition information
FoodInfoTable.FoodInfo foodInfo = FoodInfoTable.get(foodName);
// Fill out the mandatory properties to insert data
data.putString(FoodInfo.PROVIDER_FOOD_ID, foodInfo.providerFoodId);
data.putString(FoodInfo.INFO_PROVIDER, foodInfo.infoProvider);
data.putString(FoodInfo.NAME, foodInfo.name);
// ...
Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 52

Samsung Digital Health - Health Data

Programming Guide

data.putFloat(FoodInfo.CALCIUM, foodInfo.calcium);
data.putFloat(FoodInfo.IRON, foodInfo.iron);
// Register the local device if it is not registered
data.setSourceDevice(new HealthDeviceManager(mStore).getLocalDevice().getUuid());
HealthDataResolver resolver = new HealthDataResolver(mStore, null);
InsertRequest request = new
InsertRequest.Builder().setDataType(FoodIntake.HEALTH_DATA_TYPE).build();
request.addHealthData(data);
mSavedUuid = data.getUuid();
resolver.insert(request);
}

Deleting Food Intake Data


The code below shows how to delete food intake data.
public void deleteFoodIntake(String intakeUuid) {
HealthDataResolver resolver = new HealthDataResolver(mStore, null);
Filter filter = Filter.eq(FoodIntake.UUID, intakeUuid);
HealthDataResolver.DeleteRequest deleteRequest = new DeleteRequest.Builder()
.setDataType(FoodIntake.HEALTH_DATA_TYPE).setFilter(filter).build();
try {
resolver.delete(deleteRequest);
} catch (Exception e) {
e.printStackTrace();
}
}

Reading Food Intake Calories of Selected day


The code below shows how to read food intake calories of selected day.
public void readDailyIntakeCalories(DailyCaloriesCallback callback, long startTime) {
mDailyCalorieCallback = callback;
HealthDataResolver resolver = new HealthDataResolver(mStore, null);
HealthDataResolver.Filter filter = Filter.and(
Filter.greaterThanEquals(FoodIntake.START_TIME, startTime),
Filter.lessThanEquals(FoodIntake.START_TIME, startTime + DAY_END_TIME));
// Read the foodIntake data of specified day(startTime to end)
HealthDataResolver.ReadRequest request = new ReadRequest.Builder()
.setDataType(FoodIntake.HEALTH_DATA_TYPE)
.setProperties(new String[]{FoodIntake.CALORIE,FoodIntake.MEAL_TYPE})
.setFilter(filter)
.build();
try {
resolver.read(request).setResultListener(mIntakeCaloriesListener);
} catch (Exception e) {
Log.e(MainActivity.TAG, e.getClass().getName() + " - " + e.getMessage());
Log.e(MainActivity.TAG, "Getting daily calories fails.");
mDailyCalorieCallback.onDailyCaloriesRetrieved("", "", "", "", "");
}
}
private final HealthResultHolder.ResultListener<ReadResult> mIntakeCaloriesListener =
Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 53

Samsung Digital Health - Health Data

Programming Guide

new HealthResultHolder.ResultListener<ReadResult>() {
@Override
public void onResult(ReadResult result) {
Cursor c = null;
try {
c = result.getResultCursor();
if (c == null) {
Log.e(MainActivity.TAG, "null cursor!");
return;
}
float
float
float
float
float

breakfast = 0.f;
lunch = 0.f;
dinner = 0.f;
snacks = 0.f;
total = 0.f;

// Read the food intake calories of each meal type


while (c.moveToNext()) {
String calorie = c.getString(c.getColumnIndex(FoodIntake.CALORIE));
int mealType = c.getInt(c.getColumnIndex(FoodIntake.MEAL_TYPE));
switch (mealType) {
case FoodIntake.MEAL_TYPE_BREAKFAST:
breakfast += Float.valueOf(calorie);
break;
case FoodIntake.MEAL_TYPE_LUNCH:
lunch += Float.valueOf(calorie);
break;
case FoodIntake.MEAL_TYPE_DINNER:
dinner += Float.valueOf(calorie);
break;
case FoodIntake.MEAL_TYPE_OTHER:
snacks += Float.valueOf(calorie);
break;
default:
break;
}
}
// Show the food intake calories
total = breakfast + lunch + dinner + snacks;
mDailyCalorieCallback.onDailyCaloriesRetrieved(String.valueof(breakfast),
String.valueof(lunch), String.valueof(dinner), String.valueof(snacks), String.valueof(total));
} finally {
if (c != null) {
c.close();
}
}
}
};

Reading Food Intake Data of selected day and meal type


The code below shows how to read desire food intake data
public void readDailyIntakeDetails(MealDetailsCallback callback, long startTime, int mealType) {
mMealDetailsCallback = callback;
HealthDataResolver resolver = new HealthDataResolver(mStore, null);
// Set the filter to read the desire data type
Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 54

Samsung Digital Health - Health Data

Programming Guide

HealthDataResolver.Filter filter =
Filter.and(Filter.greaterThanEquals(FoodIntake.START_TIME, startTime),
Filter.lessThanEquals(FoodIntake.START_TIME, startTime + DAY_END_TIME),
Filter.eq(FoodIntake.MEAL_TYPE, mealType));
// Read the foodIntake data of specified day and meal type(startTime to end)
HealthDataResolver.ReadRequest request = new ReadRequest.Builder()
.setDataType(FoodIntake.HEALTH_DATA_TYPE)
.setProperties(new String[] { FoodIntake.UUID, FoodIntake.NAME, FoodIntake.CALORIE,
FoodIntake.AMOUNT, FoodIntake.PACKAGE_NAME })
.setFilter(filter)
.build();
try {
resolver.read(request).setResultListener(mIntakeDetailListener);
} catch (Exception e) {
Log.e(MainActivity.TAG, "read error!");
Log.e(MainActivity.TAG, e.getClass().getName() + " - " + e.getMessage());
}
}
private final HealthResultHolder.ResultListener<ReadResult> mIntakeDetailListener =
new HealthResultHolder.ResultListener<ReadResult>() {
@Override
public void onResult(ReadResult result) {
Cursor c = null;
float intakeTimes;
float intakeCalories;
String foodName;
float totalCalories = 0.f;
String packageName;
try {
c = result.getResultCursor();
if (c == null) {
Log.e(MainActivity.TAG, "null cursor!");
return;
}
ArrayList<String> savedUuidList = new ArrayList<String>();
List<String> foodNameList = new ArrayList<String>();
while (c.moveToNext()) {
savedUuidList.add(c.getString(c.getColumnIndex(FoodIntake.UUID)));
// Set the variables to get the food intake details
foodName = c.getString(c.getColumnIndex(FoodIntake.NAME));
intakeTimes = c.getFloat(c.getColumnIndex(FoodIntake.AMOUNT)));
intakeCalories = c.getFloat(c.getColumnIndex(FoodIntake.CALORIE)));
packageName = c.getString(c.getColumnIndex(FoodIntake.PACKAGE_NAME));
// Add the food intake information to List(for UI)
foodNameList.add(foodName + " : " + (intakeCalories / unitCalories) + " times"
+ " (" + intakeCalories + "kcals)");
// Calculate the total calories from food intake data
totalCalories += intakeCalories;
}
mMealDetailsCallback.onMealDetailsRetrieved(totalCalories, savedUuidList, foodNameList);
} finally {
if (c != null) {
c.close();
}
}
}
Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 55

Samsung Digital Health - Health Data

Programming Guide

};

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 56

Samsung Digital Health - Health Data

Programming Guide

Appendix A. HealthDevApp - Import Data


One of the easy ways to get health data is turning on "Pedometer" on HealthDevApp. In another way, HealthDevApp
provides a menu Import Data to import health data with csv or txt. You can create health data files for each
health data type and import them on HealthDevApp.
Follow the data format below. You can refer to example files in the SDK.

File Extension
Only ".csv" and ".txt" file extension are acceptable.

Delimiter
Each property of a specific health data type is delimited with the following characters.
File type

Delimiter

csv

comma (",")

txt

tab ("\t")

If you edit txt, use double quotations for the comma in a string value. In case of csv, you dont need to add double
quotations for the comma in a string value.

Time Format
The following formats are allowed for time related data such as created_time, updated_time, start_time,
end_time, and time_offset.
-

YYYY-MM-DD HH:mm:ss.SSS

YYYY-MM-DD HH:mm:ss AM/PM


(millisecond is stored as '000'.)

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 57

Samsung Digital Health - Health Data

Programming Guide

Appendix B. HealthDevApp - Export Data


HealthDevApp can export saved health data in the health data store to csv or txt with the 'Export data' menu. You
can select the file type as csv or txt with the following steps and Figure 20.
-

Select the 'Export data' menu on HealthDevApp.

Select data types to export data. If you dont select the file type separately, data is exported as csv. To select
the data type:

Tab 'FILE TYPE' on the top.

Select the file type and 'OK'.

The exported data file is saved under the 'SHealth' folder of the device storage.

Figure 20: File type selection to export data

Note
If any data is not saved, the health data type is not exported. The health data type which contains a property with the
BLOB type is not exported. E.g. electrocardiography.

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 58

Samsung Digital Health - Health Data

Programming Guide

Copyright
Copyright 2015 Samsung Electronics Co. Ltd. All Rights Reserved.
Though every care has been taken to ensure the accuracy of this document, Samsung Electronics Co., Ltd. cannot
accept responsibility for any errors or omissions or for any loss occurred to any person, whether legal or natural,
from acting, or refraining from action, as a result of the information contained herein. Information in this document
is subject to change at any time without obligation to notify any person of such changes.
Samsung Electronics Co. Ltd. may have patents or patent pending applications, trademarks copyrights or other
intellectual property rights covering subject matter in this document. The furnishing of this document does not give
the recipient or reader any license to these patents, trademarks copyrights or other intellectual property rights.
No part of this document may be communicated, distributed, reproduced or transmitted in any form or by any
means, electronic or mechanical or otherwise, for any purpose, without the prior written permission of Samsung
Electronics Co. Ltd.
The document is subject to revision without further notice.
All brand names and product names mentioned in this document are trademarks or registered trademarks of their
respective owners.
For more information, please visit http://developer.samsung.com/

Copyright Samsung Electronics, Co., Ltd. All rights reserved.

Page | 59

Potrebbero piacerti anche