Skip to main content

Introduction

The Open Wearables Android SDK (open-wearables-android-sdk) is a native Kotlin SDK for secure background synchronization of health data from Samsung Health and Health Connect to the Open Wearables platform. This is the core native implementation that powers health data sync on Android. The Flutter SDK uses this SDK under the hood as a wrapper.

GitHub Repository

View source code, report issues, and contribute to the Android SDK.

Features

  • Dual Provider Support - Samsung Health and Health Connect in a single SDK
  • Background Sync - Health data syncs via WorkManager with foreground service for reliability
  • Resumable Sessions - Sync sessions survive app restarts
  • Dual Authentication - Token-based auth with auto-refresh on 401, or API key authentication
  • Secure Storage - Credentials stored in Android EncryptedSharedPreferences
  • Incremental Updates - Only syncs new data using anchored queries
  • Unified Payload - Consistent data format regardless of provider
  • Wide Data Support - Steps, heart rate, workouts, sleep, and more

Requirements

RequirementDetails
Min SDKAndroid 10 (API 29+)
Compile SDK36
Java17
Kotlin2.1.0+
Samsung Health SDKFor Samsung Health provider
Health ConnectFor Health Connect provider

Installation

Add the SDK via JitPack. In your root build.gradle.kts (or settings.gradle.kts):
dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
        maven { url = uri("https://jitpack.io") }
    }
}
Then add the dependency in your app’s build.gradle.kts:
dependencies {
    implementation("com.github.the-momentum:open-wearables-android-sdk:0.5.0")
}

Android Configuration

The SDK’s AndroidManifest.xml automatically merges the required permissions and services. However, ensure your app’s build.gradle.kts has the correct SDK versions:
android {
    compileSdk = 36
    defaultConfig {
        minSdk = 29
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }
}

Permissions

The SDK declares these permissions automatically (merged via manifest):
PermissionPurpose
FOREGROUND_SERVICEForeground service during sync
FOREGROUND_SERVICE_DATA_SYNCData sync foreground service type
POST_NOTIFICATIONSSync notification (Android 13+)
INTERNETNetwork access
ACCESS_NETWORK_STATENetwork monitoring
health.READ_HEALTH_DATA_IN_BACKGROUNDBackground health data access
health.READ_STEPSStep count
health.READ_HEART_RATEHeart rate
health.READ_RESTING_HEART_RATEResting heart rate
health.READ_HEART_RATE_VARIABILITYHRV
health.READ_OXYGEN_SATURATIONBlood oxygen
health.READ_BLOOD_PRESSUREBlood pressure
health.READ_BLOOD_GLUCOSEBlood glucose
health.READ_ACTIVE_CALORIES_BURNEDActive energy
health.READ_BASAL_METABOLIC_RATEBasal energy
health.READ_BODY_TEMPERATUREBody temperature
health.READ_WEIGHTBody mass
health.READ_HEIGHTHeight
health.READ_BODY_FATBody fat percentage
health.READ_LEAN_BODY_MASSLean body mass
health.READ_FLOORS_CLIMBEDFlights climbed
health.READ_DISTANCEWalking/running distance
health.READ_HYDRATIONWater intake
health.READ_VO2_MAXVO2 max
health.READ_RESPIRATORY_RATERespiratory rate
health.READ_EXERCISEWorkouts
health.READ_SLEEPSleep data

Quick Start

Here’s the minimal code to get health sync working:
import com.openwearables.health.sdk.OpenWearablesHealthSDK

class HealthService(private val context: Context) {

    private lateinit var sdk: OpenWearablesHealthSDK

    fun initialize() {
        // 1. Initialize the SDK
        sdk = OpenWearablesHealthSDK.initialize(context)

        // 2. Set up logging (optional)
        sdk.logListener = { message ->
            Log.d("HealthSDK", message)
        }

        // 3. Set log level (optional — default is OWLogLevel.DEBUG)
        sdk.logLevel = OWLogLevel.ALWAYS

        // 4. Handle auth errors (optional)
        sdk.authErrorListener = { error ->
            Log.e("HealthSDK", "Auth error: $error")
        }

        // 5. Configure with your backend host
        sdk.configure(host = "https://api.openwearables.io")

        // 6. Check if already signed in
        if (sdk.isSessionValid()) {
            Log.d("HealthSDK", "Session restored")
            return
        }
    }

    suspend fun connect(userId: String, accessToken: String, refreshToken: String?) {
        // 7. Sign in
        sdk.signIn(
            userId = userId,
            accessToken = accessToken,
            refreshToken = refreshToken,
            apiKey = null
        )

        // 8. Set provider
        sdk.setProvider("google") // or "samsung"

        // 9. Request permissions
        val authorized = sdk.requestAuthorization(
            types = listOf("steps", "heartRate", "sleep", "workout")
        )

        if (!authorized) {
            Log.w("HealthSDK", "Health permissions were denied")
            return
        }

        // 10. Start background sync (sync last 90 days of data)
        sdk.startBackgroundSync(syncDaysBack = 90)
    }
}

Activity Setup

The SDK needs a reference to the current Activity for permission dialogs (especially Health Connect):
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val sdk = OpenWearablesHealthSDK.getInstance()
        sdk.setActivity(this)
    }

    override fun onDestroy() {
        super.onDestroy()
        OpenWearablesHealthSDK.getInstance().setActivity(null)
    }
}

Documentation

Integration Guide

Complete guide to integrating the SDK including authentication flow, backend setup, and best practices.

Troubleshooting

Common issues and their solutions for Android.

Provider Selection

The SDK supports two health data providers on Android:
ProviderIDDescription
Health Connect"google"Google’s Health Connect API. Works on all Android 10+ devices.
Samsung Health"samsung"Samsung Health SDK. Works on Samsung devices with Samsung Health installed.
val sdk = OpenWearablesHealthSDK.getInstance()

// Check which providers are available
val providers = sdk.getAvailableProviders()
for (p in providers) {
    println("${p["displayName"]} (${p["id"]}) - available: ${p["isAvailable"]}")
}

// Set the active provider
val selected = sdk.setProvider("google") // or "samsung"
if (!selected) {
    Log.e("HealthSDK", "Selected provider is unavailable on this device")
}

Supported Health Data Types

Type IDDescription
stepsStep count
heartRateHeart rate
restingHeartRateResting heart rate
heartRateVariabilitySDNNHRV (SDNN)
oxygenSaturationBlood oxygen
vo2MaxVO2 max
respiratoryRateRespiratory rate
bloodPressureBlood pressure (systolic + diastolic)
bloodGlucoseBlood glucose
activeEnergyActive calories burned
basalEnergyBasal metabolic rate
bodyTemperatureBody temperature
bodyMassWeight
heightHeight
bodyFatPercentageBody fat %
leanBodyMassLean body mass
flightsClimbedFloors climbed
distanceWalkingRunningWalking/running distance
distanceCyclingCycling distance
water / dietaryWaterWater intake
workoutAll workout types with segments, laps, route, samples
sleepSleep sessions with stages (awake, light, deep, REM)
Health Connect generally supports more data types than Samsung Health. If both are available, Health Connect is recommended for the widest data coverage.

Next Steps

Integration Guide

Complete step-by-step integration guide.

Flutter SDK

Using Flutter? The Flutter SDK wraps this native SDK for cross-platform apps.