Terra Docs
Dashboard
  • Docs
  • API Reference
  • Changelog
  • Get started ⚡️ Choose your integration
  • Health & Fitness API
    • Overview
    • Set up your Integrations
    • Connect a User
    • Receive data updates
    • Request Historical data
    • Write data
    • Debugging FAQ
    • Mobile-Only Sources: Apple, Samsung, Google Fit
      • iOS (Swift)
      • Android (Kotlin)
      • React Native
      • Flutter
  • Streaming API
    • Getting Started
    • Wearable -> Your app
      • iOS (Swift)
      • Android
    • Your app -> Terra
      • iOS (Swift)
      • Android
    • Terra -> Your Backend
  • Teams API
  • Biomarkers API - Upcoming
Powered by GitBook
On this page
  • Overview
  • 1. Install the SDK
  • 2. Initialize the SDK
  • 3. Connect to a User
  • 4. Validate the Connection
  • 📱 App Example
  • Disconnecting a user
  • Historical Data retrieval

Was this helpful?

  1. Health & Fitness API
  2. Mobile-Only Sources: Apple, Samsung, Google Fit

Android (Kotlin)

PreviousiOS (Swift)NextReact Native

Last updated 24 days ago

Was this helpful?

Overview

This guide will walk you through the necessary steps to use the Terra SDK with Android-based integrations in your Android app. It covers everything from SDK initialization, user connection, permission handling, and background data updates.

The TerraAndroid SDK supports the following integrations:

  • Samsung Health

  • Health Connect

1. Install the SDK

1. Install Terra in build.gradle

  • Inside the dependencies section of your build.gradle file, add the following line of code.

build.gradle
implementation 'co.tryterra:terra-android:{VERSION_NUMBER}'
  • You can find the latest version number on .

2. Sync your project with build.gradle

Sync your project with Gradle by clicking on the "Sync Project with Gradle Files" button in the toolbar. This will download the TerraAndroid SDK and make it available to your project.

Requirements

  • Your app build config must be for Android 28 (minSDK 28) and above.

  • The device must have the required app installed, e.g. Health Connect or Samsung Health

3. Configure Health Permissions

Terra API provides direct access to the Samsung Health SDK via our privileged partnership with Samsung.

If you'd like to apply for Samsung Health access, please reach out to us by submitting a ticket on the Terra Support page. You can find this in your Terra Dashboard!

1. In the Health Connect app

Give all permissions between the apps you wish to read from (e.g. Samsung Health, Google Fit, etc) & Health Connect.

2. Add Health Connect capability to your app

Include the permission tags under the Activity you wish to link the user to when they click the privacy policy link in the Health Connect permission screen. Here are the steps:

  1. Go to your Android App's AndroidManifest.xml

  2. Go to your Privacy Policy <activity> and include the following tags under this <activity> tag.

"Your Android manifest needs to have an Activity that displays your app's privacy policy, which is your app's rationale of the requested permissions, describing how the user's data is used and handled." — Health Connect.

AndroidManifest.xml
<intent-filter>
  <action android:name="androidx.health.ACTION_SHOW_PERMISSIONS_RATIONALE" />
 </intent-filter>
  
<intent-filter>
   <action android:name="android.intent.action.VIEW_PERMISSION_USAGE"/>
  <category android:name="android.intent.category.HEALTH_PERMISSIONS"/>
</intent-filter>

Apply for Health Connect access

Before going live (release), you will need to apply for permissions to access the Health Connect API with Google.

  1. For each permission which you are not using, please add the following lines to your AndroidManifest.xml

<uses-permission android:name="android.permission.health.READ_HEART_RATE" tools:node="remove"/>

with android.permission.health.XXX for each permission you aren't using


2. Initialize the SDK

The initialization only needs to be done once on app start, (e.g. in your MainActivity file or equivalent), and every time the app is brought into the foreground. This ensures that the SDK is properly set up and ready to be used.

The SDK should be initialized every time your app is started.

This is a necessary prerequisite for other SDK functions to run as expected

Step 1: Import Terra and TerraManager

In your Android Studio project, you should now be able to import classes from the Terra SDK.

MainActivity.kt
import co.tryterra.terra.Terra
import co.tryterra.terra.TerraManager

Step 2: Get a TerraManager Instance

MainActivity.kt
import co.tryterra.terra.Terra
import co.tryterra.terra.TerraManager

import java.lang.IllegalStateException

class MainActivity : Activity() {
    private lateinit var terra: TerraManager

    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        Terra.instance("YOUR DEV ID", "REFERENCE ID", this) { manager, error ->
            error?.let{it ->  
                throw IllegalStateException("🤯: Error initialising terra ${it.message}")
            }
            terra = manager
        }
    }
}

(N.B This call is asynchronous, please ensure this is complete before using the manager).


3. Connect to a User

Once Terra is initialized, you can create a connection (e.g. Samsung Health or Health Connect).

This method triggers the a permission popup and establishes the connection.

  • type: Specify the connection type (e.g. Connections.SAMSUNG or Connections.HEALTH_CONNECT)

  • token: A one-time authentication token generated from your backend server using Terra API. This ensures secure communication between your app and the Terra servers.

  • customPermissions: A set of permissions that define what data you want to request from the Android SDKs (e.g., heart rate, steps). If empty, it defaults to all available permissions.

  • schedulerOn: To allow Terra to make scheduled requests whenever the app is in the foreground.

MainActivity.kt
import android.app.Activity
import android.os.Bundle
import android.util.Log

import co.tryterra.terra.Terra
import co.tryterra.terra.TerraManager
import co.tryterra.terra.enums.Connections

import java.lang.IllegalStateException

class MainActivity : Activity() {
    private lateinit var terra: TerraManager
        
    override fun onCreate(savedInstanceState: Bundle?) {
        // Creation of Terra Manager as in Step 2!
    }

    fun initialiseUserConnection() {
        if (!this::terra.isInitialized){
            throw IllegalStateException("🤯: Terra Manager not initialised yet")
        }
        // Example token received from your backend
        val token = "your_generated_token_from_backend"
        
        // Initialize the connection to Samsung Health
        terra.initConnection(
            connection = Connections.SAMSUNG,   // Connecting to Samsung Health
            token = token,                      // Token passed from backend
            context = this,                  // The activity context
            customPermissions = setOf(),  // Custom permissions set (empty set defaults to all permissions)
            schedulerOn = true,                 // Background scheduler on
            startIntent = null                  // Deprecated - always set to null
        ) { success, error ->
            error?.let {
                throw IllegalStateException("🤯: ${it.message}")
            }
            // Connection successful!
            Log.i("MainActivity", "Auth Success status: $success")
        }
    }
}

initConnection only needs to be called a single time.

Health Connect prohibits the permission popup to appear more than once for any given permission, so calling initConnection more than once will result in no action at all

The only case where it would re-appear is if:

a. you call initConnection with an expanded set of customPermissions

b. the app is deleted & reinstalled.

c. a permission that was not granted to use on release by Google has been requested by the app


4. Validate the Connection


Now you'll start receiving health data events automatically to your Data Destination (e.g. webhook)!

You can also request historical data to backfill, to verify that data exists, or as a fallback.


📱 App Example

MainActivity.kt
import android.app.Activity
import android.os.Bundle
import android.util.Log

import co.tryterra.terra.Terra
import co.tryterra.terra.TerraManager
import co.tryterra.terra.enums.Connections

import java.lang.IllegalStateException

class MainActivity : Activity() {
    private lateinit var terra: TerraManager

    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        Terra.instance("YOUR DEV ID", "REFERENCE ID", this) { manager, error ->
            error?.let{it -> 
                throw IllegalStateException("🤯: Error initialising terra ${it.message}")
            }
            terra = manager
            this.initialiseUserConnection()
        }
    }

    fun initialiseUserConnection() {
        if (!this::terra.isInitialized){
            throw IllegalStateException("🤯: Terra Manager not initialised yet")
        }
        
        if (terra.getUserId(Connections.SAMSUNG) != null){
            // User already connected
            return
        }
        
        // Initialize the connection to Samsung Health
        terra.initConnection(
            connection = Connections.SAMSUNG,   // Connecting to Samsung Health
            token = "AUTH TOKEN",                      // Token passed from backend
            context = this,                  // The activity context
            customPermissions = setOf(),  // Custom permissions set (empty set defaults to all permissions)
            schedulerOn = true,                 // Background scheduler on
            startIntent = null                  // Deprecated - always set to null
        ) { success, error ->
            error?.let {
                throw IllegalStateException("🤯: ${it.message}")
            }
            // Connection successful!
            Log.i("MainActivity", "Auth Success status: $success")
        }
    }
}

Disconnecting a user


Historical Data retrieval

You may set toWebhook to false if you wish for the callback function to return the data payload on the client side.

MainActivity.kt
import co.tryterra.terra.enums.Connections
import java.time.Instant
import java.time.temporal.ChronoUnit
import java.util.*

fun requestData() {
    val startDate = Date.from(Instant.now().minus(1, ChronoUnit.DAYS))
    val endDate = Date()
    
    // Request for yesterday and today's data
    terra.getDaily(
        type = Connections.SAMUNG,
        startDate = startDate,
        endDate = endDate,
        toWebhook = false 
    ) { success, payload, error ->
        error?.let{
            throw IllegalStateException("🤯: Error requesting data ${it.message}")    
        }
        // Process payload here
    }
}

Use this .

To do this, run the as below:

Call from the TerraManager instance you've created above to have the corresponding permission screen pop up.

1. Call

From the TerraManager instance, call with the following arguments:

To learn more about these parameters and their different options, check the

To ensure a connection is still valid on the client side, use the method. This function is synchronous and returns the user_id right away or null if none exists.

Check out the for details about all the functions in the SDK.

In order to disconnect an SDK user, you may use , called from your backend.

You can request for historical data using one of the .

Maven Central
application form
Android SDK reference
Terra manager initialization function
terra.initConnection
initConnection()
initConnection()
Android SDK Reference.
terra.getUserId()
the same endpoint as for Web API-based integrations
data retrieval functions

2. Generate an Auth Token

To be able to call the initConnection() method, you need to pass a token as an argument.

This token is a single-use token created to ensure the authentication endpoint for creating a connection (and connecting the SDK to Terra's servers) does not get abused.

Generate the token with this endpoint POSThttps://api.tryterra.co/v2/auth/generateAuthToken . Make sure to call it with your Terra x-api-key and dev-id in the headers from your backend server. After you generate the token, provide the response to your client side using your own logic.

Go to the SDK Reference to find more details on the .

  • During the development phase, it it acceptable to place this call on the client side, exposing your API key in your mobile app.

  • For a production implementation, DO NOT expose your API key this way, and make sure to only make this call from your backend.

Data Sources requiring the Terra Mobile-SDK

The Mobile SDK is ONLY used to connect to the following integrations:

Apple Health - iOS

Samsung Health - Android

Google Fit - Android. Note: the is the preferred way to connect to Google Fit until its sunsetting on June 30, 2025 due to better reliability

For ALL other integrations, please refer to the

Health & Fitness API
Health & Fitness API

Always validate the connection before using the SDK

Check if a user_id exists right after initializing the Terra SDK to see if the connection still exists.

  1. Check if the User is Connected

    1. If the function returns a user ID, the user is still connected, 🎉 keep vibing along!

    2. If the function returns nil, the user needs to reconnect.

  2. Re-connect if Needed If the connection is lost, you can call terra.initConnection() again to re-establish the connection.

Calling terra.initConnection() when the user is already connected or just needs a reconnection will not trigger any permission screens from Apple Health, and the user flow will remain uninterrupted. The connection will be re-established if necessary.

Generate the Mobile SDK Auth Token API Endpoint