> For the complete documentation index, see [llms.txt](https://docs.tryterra.co/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.tryterra.co/streaming-api/connect-wearable-to-sdk/android.md).

# Android

## Prerequisites

Ensure you have the following before you begin:

1. **Android Studio**: The latest stable version.
2. **Terra Account**: Access to your Terra Developer account and API key.
3. **Gradle Dependency**: Ensure you include the TerraRT SDK in your project by adding the necessary dependencies.

   ```gradle
   implementation 'co.tryterra:terra-rtandroid:X.X.X'
   ```

   based on [the latest version on maven central](https://central.sonatype.com/artifact/co.tryterra/terra-rtandroid)

## SDK Initialization

{% hint style="info" %}
Always initialize the `TerraRT` class to begin using the SDK.

Do so every time the app is opened or brought into the foreground.
{% endhint %}

To do this, run the [TerraRT manager initialization function](/reference/streaming-api/reference/android-kotlin.md#terrart) as below:

```kotlin
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import co.tryterra.terrartandroid.TerraRT

class MainActivity : AppCompatActivity() {
    private lateinit var terraRT: TerraRT

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val developerId = "yourDeveloperId"
        val referenceId: String? = "yourReferenceId"

        terraRT = TerraRT(
            devId = developerId,
            context = this,
            referenceId = referenceId
        ) { success ->
            if (success) {
                println("TerraRT initialized successfully")
            } else {
                println("Failed to initialize TerraRT")
            }
        }
    }
}
```

## **Initializing a Connection**

Register the [phone](/reference/streaming-api/core-concepts.md#phone) by calling [`initConnection`](/reference/streaming-api/reference/android-kotlin.md#initconnection).

This connects the [phone](/reference/streaming-api/core-concepts.md#phone) to Terra, allows you to use other SDK functions, and allows it to be a [producer](/reference/streaming-api/core-concepts.md#producer) once a [device](/reference/streaming-api/core-concepts.md#device) is connected later on.

Use the [terraRT instance created above](#sdk-initialization) and call initConnection as below using an **authentication token**.

```kotlin
val token = "yourAuthToken"  // Generated from your backend

terraRT.initConnection(token) { success ->
    if (success) {
        println("Connection initialized successfully!")
    } else {
        println("Failed to initialize connection.")
    }
}
```

To generate the **token**, make the below call **from your backend**

{% openapi src="<https://raw.githubusercontent.com/tryterra/openapi/refs/heads/master/dist/core/v2-bundled.yaml>" path="/auth/generateAuthToken" method="post" %}
<https://raw.githubusercontent.com/tryterra/openapi/refs/heads/master/dist/core/v2-bundled.yaml>
{% endopenapi %}

## Device Connection Management

Once initialized, you can scan for devices and connect to them using the TerraRT SDK.

You can scan for devices using

* BLE
* ANT+ (if supported by the Android phone used)

#### Start Device Scan

You can start scanning for devices and allow the user to connect to a wearable device using [startDeviceScan](/reference/streaming-api/reference/android-kotlin.md#startdevicescan).

You can choose whether to use cached devices (ones you've connected to before) or show a connection widget if no cached device is found.

```kotlin
import co.tryterra.terrartandroid.enums.Connections

// Option 1: Widget-based scan with auto-connection
terraRT.startDeviceScan(
    type = Connections.BLE,
    useCache = false,
    showWidgetIfCacheNotFound = true
) { success ->
    if (success) {
        println("Device connected successfully!")
    } else {
        println("Failed to connect to the device.")
    }
}

// Option 2: Programmatic scan with device callback
terraRT.startDeviceScan(type = Connections.BLE) { device ->
    println("Found device: ${device.deviceName}")
    // Connect to the chosen device
    terraRT.connectDevice(device) { connected ->
        println("Device connected: $connected")
    }
}
```

### Real-Time Data Streaming

Once the device is connected, you can start streaming real-time data such as heart rate, steps, and more.

{% hint style="info" %}
Receiving a real time data stream depends on the [device](/reference/streaming-api/core-concepts.md#device) being configured to broadcast the data it is collecting through BLE or ANT+
{% endhint %}

#### Start Real-Time Streaming

```kotlin
import co.tryterra.terrartandroid.enums.DataTypes

val dataTypes: Set<DataTypes> = setOf(DataTypes.HEART_RATE, DataTypes.STEPS)

// Stream data locally (no server)
terraRT.startRealtime(type = Connections.BLE, dataTypes = dataTypes) { update ->
    println("${update.type}: ${update.`val`}")
}
```

#### Stop Real-Time Streaming

```kotlin
terraRT.stopRealtime(type = Connections.BLE)
```

#### Disconnect Device

```kotlin
terraRT.disconnect(type = Connections.BLE)
```

### Example Usage

#### Full Example: Managing a BLE Connection and Streaming Data

```kotlin
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import co.tryterra.terrartandroid.TerraRT
import co.tryterra.terrartandroid.enums.Connections
import co.tryterra.terrartandroid.enums.DataTypes
import co.tryterra.terrartandroid.models.Update

class MainActivity : AppCompatActivity() {
    private lateinit var terraRT: TerraRT

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        terraRT = TerraRT(
            devId = "yourDeveloperId",
            context = this,
            referenceId = "yourReferenceId"
        ) { success ->
            if (success) {
                println("TerraRT initialized")
                connectAndStream()
            }
        }
    }

    private fun connectAndStream() {
        val token = "yourAuthToken"

        terraRT.initConnection(token) { success ->
            if (success) {
                // Scan and connect to a BLE device
                terraRT.startDeviceScan(
                    type = Connections.BLE,
                    useCache = false
                ) { scanSuccess ->
                    if (scanSuccess) {
                        // Start streaming heart rate data
                        val dataTypes = setOf(DataTypes.HEART_RATE, DataTypes.STEPS)
                        terraRT.startRealtime(
                            type = Connections.BLE,
                            dataTypes = dataTypes
                        ) { update ->
                            handleUpdate(update)
                        }
                    }
                }
            }
        }
    }

    private fun handleUpdate(update: Update) {
        println("${update.type}: ${update.`val`} at ${update.ts}")
    }

    override fun onDestroy() {
        super.onDestroy()
        terraRT.stopRealtime(type = Connections.BLE)
        terraRT.disconnect(type = Connections.BLE)
    }
}
```
