HealthDataStore

interface HealthDataStore

HealthDataStore is a proxy that provides a way to access the data stored in the Samsung Health app.

An app can access the data through the operations provided by HealthDataStore, such as reading, aggregating, inserting, updating and deleting data.

Use the HealthDataService.getStore method to retrieve an instance from HealthDataStore.

The below examples show how apps can retrieve appropriate permissions and read data in two styles of programming. All requests are processed immediately after moving to a dedicated thread pool, so the caller can invoke the method on any thread. However, of the various manners of waiting for the result of AsyncCompletableFuture or AsyncSingleFuture, do not use the sync manner on the main thread.

Synchronous request

The below sample code uses suspend functions, showing how to retrieve a step count for a defined time period. Be careful not to use the synchronous request on the main thread.
@Throws(InterruptedException::class)
suspend fun showSteps(date: LocalDate, context: Context) {
    val store = HealthDataService.getStore(context)
    val requiredPermissions: MutableSet<Permission> = HashSet(
        listOf(Permission.of(DataTypes.STEPS, AccessType.READ))
    )

    // This checks if the app has the user's permission for the target data types.
    if (areAllPermissionsObtained(store, requiredPermissions)) {
        val stepsResponse = getAggregateResult(store, date)
         stepsResponse.dataList.forEach {
             val steps = it.value
             // This processes the value.
         }
    }
}

@Throws(InterruptedException::class)
private suspend fun areAllPermissionsObtained(
    store: HealthDataStore,
    permissions: Set<Permission>
): Boolean {
    try {
        // An API call to check the granted permissions.
        val initialResult: Set<Permission> = store.getGrantedPermissions(permissions)
        if (!initialResult.containsAll(permissions)) {
            val requiredPermissions =
                permissions.toMutableSet().apply { removeAll(initialResult) }
            //  An API call for a permission request.
            val obtainedResult = store.requestPermissions(requiredPermissions, this.context)
            if (obtainedResult.containsAll(requiredPermissions)) {
                return true
            }
        } else {
            return true
        }
    } catch (error: HealthDataException) {
        if (error is ResolvablePlatformException && error.hasResolution) {
            Log.i(TAG, error.toString())
            error.resolve(this.context)
            // An exception to indicate that the Samsung Health app is not ready to serve the specified operation.
        } else if (error is AuthorizationException) {
            Log.i(TAG, error.toString())
            //  An exception to indicate that the app is not authorized to perform the specified operation.
        } else if (error is InvalidRequestException) {
            Log.i(TAG, error.toString())
            // An exception to indicate that the app requests the specified operation with invalid conditions.
        } else if (error is PlatformInternalException) {
            Log.i(TAG, error.toString())
            // An exception to indicate that the Samsung Health app experienced an internal error
            // that cannot be resolved by the app.
        }
    }
    return false
}

private suspend fun getAggregateResult(
    store: HealthDataStore,
    date: LocalDate
): DataResponse<AggregatedData<Long>> {
    val stepsRequest: AggregateRequest<Long> =
        DataType.StepsType.TOTAL.requestBuilder.setLocalTimeFilterWithGroup(
            LocalTimeFilter.of(date.atStartOfDay(), date.plusDays(1).atStartOfDay()),
            LocalTimeGroup.of(LocalTimeGroupUnit.MINUTELY, 30)
        ).build()

    // An API call for an aggregate request.
    return store.aggregateData(stepsRequest)
}

Asynchronous request

This manner returns `AsyncCompletableFuture` or `AsyncSingleFuture`. The actual requests are processed immediately after moving to a dedicated thread pool, so the method can be invoked on any thread. To get a query result, processing `Futures` using sync manner on the main thread is not recommended.
@Throws(InterruptedException::class)
fun showSteps(date: LocalDate, context: Activity) {
    Log.i(TAG, "showSteps Async")
    this.context = context
    val store = HealthDataService.getStore(context)
    val requiredPermissions: MutableSet<Permission> = HashSet(
        listOf(Permission.of(DataTypes.STEPS, AccessType.READ))
    )

    // This checks the user's permissions for the target data types.
    runOnAllPermissionsObtained(store, requiredPermissions) {
        val stepsResponse = getAggregateResult(store, date)
        stepsResponse.dataList.forEach {
            val steps = it.value
            // This processes the value.
            Log.i(TAG, "step count: $steps")
        }
    }
}

private fun runOnAllPermissionsObtained(
    store: HealthDataStore,
    permissions: Set<Permission>,
    runnable: Runnable
) {
    // An asynchronous API call to check if the correct permissions are granted.
    store.getGrantedPermissionsAsync(permissions)
        .setCallback(
            Looper.getMainLooper(),
            Consumer { initialResult: Set<Permission> ->
                if (!initialResult.containsAll(permissions)) {
                    val requiredPermissions =
                        permissions.toMutableSet().apply { removeAll(initialResult) }
                    // An asynchronous API call for a permission request.
                    store.requestPermissionsAsync(permissions, context)
                        .setCallback(Looper.getMainLooper(),
                            Consumer { obtainedResult ->
                                if (!obtainedResult.containsAll(requiredPermissions)) {
                                    return@Consumer
                                }
                                runnable.run()
                            }
                        ) { error ->
                            if (error is ResolvablePlatformException && error.hasResolution) {
                                error.resolve(context)
                            }
                        }
                } else {
                    runnable.run();
                }
            }
        ) { error ->
            if (error is ResolvablePlatformException && error.hasResolution) {
                error.resolve(context)
                // An exception to indicate that the Samsung Health app is not ready to serve the specified operation.
            } else if (error is AuthorizationException) {
                // An exception to indicate that the app is not authorized to perform given operation.
            } else if (error is InvalidRequestException) {
                // An exception to indicate that the app requests the given operation with invalid conditions.
            } else if (error is PlatformInternalException) {
                // An exception to indicate that the Samsung Health app experienced an internal error
                // that cannot be resolved by the app.
            }
        }
}

private fun getAggregateResult(
    store: HealthDataStore,
    date: LocalDate
): DataResponse<AggregatedData<Long>> {

    val stepsRequest =
        DataType.StepsType.TOTAL.requestBuilder.setLocalTimeFilterWithGroup(
            LocalTimeFilter.of(date.atStartOfDay(), date.plusDays(1).atStartOfDay()),
            LocalTimeGroup.of(LocalTimeGroupUnit.MINUTELY, 30)
        ).build()

    // An asynchronous API call for an aggregate request.
    return store.aggregateDataAsync(stepsRequest).get()
}

Since

1.0.0

Functions

Link copied to clipboard
suspend fun <T : Any, S : AggregateRequest.Builder<T>> HealthDataStore.aggregate(aggregateOperation: AggregateOperation<T, S>, builder: suspend S.() -> S? = null): DataResponse<AggregatedData<T>>

Aggregates a set of data in the Samsung Health app with simplified code. It enables you to request an aggregate operation for a specific data type with building an AggregateRequest easily. To aggregate data asynchronously, use HealthDataStore.aggregateDataAsync.

Link copied to clipboard
abstract suspend fun <T : Any> aggregateData(request: AggregateRequest<T>): DataResponse<AggregatedData<T>>

Aggregates a set of the Samsung Health app's data according to the specified request.

Link copied to clipboard

Aggregates a set of Samsung Health data according to the specified request.

Link copied to clipboard

Deletes a set of data from the Samsung Health app with simplified code. It enables you to delete health data with a specific data type and building a DeleteDataRequest easily. To delete data asynchronously, use HealthDataStore.deleteDataAsync.

Link copied to clipboard
abstract suspend fun deleteData(request: DeleteDataRequest)

Delete a set of data in the request into the Samsung Health app.

Link copied to clipboard

Delete a set of data in the request into the Samsung Health.

Link copied to clipboard

Retrieves the DeviceManager object for information about the devices that provide the health data stored in the Samsung Health

Link copied to clipboard
abstract suspend fun getGrantedPermissions(permissions: Set<Permission>): Set<Permission>

Returns the specified set of granted Permissions.

Link copied to clipboard

Returns the specified set of granted Permissions.

Link copied to clipboard

Inserts a set of data into the Samsung Health app with simplified code. It enables you to insert health data with a specific data type and building an InsertDataRequest easily. To insert data asynchronously, use HealthDataStore.insertDataAsync.

Link copied to clipboard
abstract suspend fun <T : DataPoint> insertData(request: InsertDataRequest<T>)

Inserts a set of data in the request into the Samsung Health app.

Link copied to clipboard

Inserts a set of data in the request into the Samsung Health.

Link copied to clipboard
suspend fun <T : DataPoint, S : ReadDataRequest.Builder<T>> HealthDataStore.read(type: DataType.Readable<T, S>, builder: suspend S.() -> S? = null): DataResponse<T>

Reads a set of data in the Samsung Health app with simplified code. It enables you to read health data with a specific data type and building a ReadDataRequest for that data type easily. To read data asynchronously, use HealthDataStore.readDataAsync.

Link copied to clipboard

Reads a set of associated data for a certain target data according to the given request.

Link copied to clipboard

Reads asynchronously a set of associated data for a certain target data according to the given request.

Link copied to clipboard

Reads a set of changed data in the Samsung Health app with simplified code. It enables you to read changed health data with a specific data type and building a ChangedDataRequest for that data type easily. To read changed data asynchronously, use HealthDataStore.readChangesAsync.

Link copied to clipboard
abstract suspend fun <T : DataPoint> readChanges(request: ChangedDataRequest<T>): DataResponse<Change<T>>

Reads a set of changes made in the Samsung Health app's data according to the specified request.

Link copied to clipboard

Reads a set of changes made in the Samsung Health data according to the specified request.

Link copied to clipboard
abstract suspend fun <T : DataPoint> readData(request: ReadDataRequest<T>): DataResponse<T>

Reads a set of the Samsung Health app's data according to the specified request.

Link copied to clipboard

Reads a set of the Samsung Health app's data according to the specified request.

Link copied to clipboard
abstract suspend fun requestPermissions(permissions: Set<Permission>, activity: Activity): Set<Permission>

Requests a data permission popup to be displayed for the user to grant a specified set of Permissions.

Link copied to clipboard

Requests a data permission popup to be displayed for the user to grant a specified set of Permissions.

Link copied to clipboard

Updates a set of data in the Samsung Health app with simplified code. It enables you to update health data with a specific data type and building a UpdateDataRequest easily. To update data asynchronously, use HealthDataStore.updateDataAsync.

Link copied to clipboard
abstract suspend fun <T : DataPoint> updateData(request: UpdateDataRequest<T>)

Updates a set of data, represented by the request into the Samsung Health app's database.

Link copied to clipboard

Updates a set of data in the request into the Samsung Health.

Preferences Submitted

You have successfully updated your cookie preferences.