The time is here! We are letting you test out our Real Time Streaming Features!

A Worthy Note

This packages uses Bluetooth Low Energy (BLE) and Bluetooth services. These will be requested as permissions upon initialisation of the package.

The package streams real time data through Websockets and is hosted by us! You can learn more about it here on our docs.

The data streamed to your websocket connection (as a developer) will follow the following format:

      "ts": <String> (In ISOFormat Date Form)
       "val": <Double>
       "d" <Array<Double>>
    "uid": <String> (user ID)
    "seq": <Int>,
    "t": <String> (Datatype name: Exactly the same as the name of `DataTypes` enum)

ts is the timestamp of the record.

For each datatype, either val or d is populated.


  • HEART_RATE: val the BPM of each reading
  • STEPS: val the amount of accumulated steps
  • DISTANCE: val the accumulated distance in meters
  • FLOORS_CLIMBED: val the accumulated floors climbed
  • STEPS_CADENCE: val the amount of steps per second taken by the user
  • SPEED: val the speed in meter per second of the user
  • ACCELERATION: d the acceleration data of the device.
    • d[0] -> acceleration in x direction
    • d[1] -> acceleration in y direction
    • d[2] -> acceleration in z direction
  • GYROSCOPE: d the rotation rate of the device.
    • d[0] -> the rotation rate in x axis
    • d[1] -> the rotation rate in y axis
    • d[2] -> the rotation rate in z axis


The library is part of mavenCentral!

You may import it in your app gradle file as: implementation co.tryterra:terra-rtandroid:0.1.1


The package revolves mainly around a single class: TerraRT.

You will need to initialise one as follows:

terraRT = TerraRT(
    devId: String,
    context: Context,
    referenceId: String?,
    completion: (Boolean) -> Unit,


  • devId: String => Your developer ID from terra
  • referenceId: String? => A user ID associated to your yours
  • context: Context => The app context for which you call this function from (usually from a class that extends from Activity types)
  • completion: (Boolean) -> Unit => A completion function that is called when the initialisation is complete

Initialising Connections

After initialisation of this class, you can initialise different connections.

You can do this as follows:

terraRT.initConnection(token: String, callback: (Boolean) -> Unit)


  • token: String => An authentication token generated from Generate Authentication Token .
  • completion: (Boolean) -> Unit => A completion function that is called when the initialisation is complete.

Currently supported Connections:

  • BLE (includes Garmin HR Broadcasts, Polar, Wahoo, XIAOMI Bands and more!!!)
  • Wear OS (Bluetooth) (Please check out our WearOS SDK for this!)
  • ANT (Includes Garmin HR Broadcasts, and ANT+ Supported fitness equipments!)
  • Sensors (Android device sensors like acceleration, location, gyroscope, etc...)
  • ANDROID (Sensors data from the device)
  • ALL_DEVICES (Includes all BLE and ANT+ devices (v0.3.1 onwards only)

Upon running this initConnection function, any necessary permission request will be requested.

You may now connect to devices to start the streaming process!

terraRT.startDeviceScan(type: Connections,  useCache: Boolean = false, callback: (Boolean) -> Unit)

This will pull a widget up to allow the user to scan and connect to a device.

useCache parameter can be used if you wish to let the user simply connect the previous connected device.

N.B You will have to download 2 plugins from ANT+ services to use this function, otherwise the connections will return false in the callback (Error logs will be printed). You can find the 2 plugins here: Ant+ Plugins Service and Ant Radio Service

You may also choose to design your own widget! We provide a method that returns all the devices scanned through a callback function:

fun startDeviceScan(type: Connections, deviceCallback: (Device) -> Unit)

Where Device is:

data class Device(
    val deviceId: String,
    val deviceName: String?

You may then connect to the device through the method:

fun connectDevice(device: Device, connectionCallback: (Boolean) -> Unit)


For 0.2.x versions and below you can start scans using the following:

  • For Bluetooth/BLE related connections, you will also be required to run
terraRT.startBluetoothScan(type: Connections, callback: (Boolean) -> Unit)

type: Connections => The same Connections enum as before! However this function will only take connections that uses Bluetooth: Connections.BLE and Connections.WEAR_OS

This will cause Bluetooth connection widget will pop up asking you to select the Bluetooth device you wish to connect to. Connecting to any other devices will simply fail if not supported!

The callback is to check whether the connection is successful or not. Please wait for the callback before proceeding!

  • For ANT+ related connections, you can do something similar to BLE connections by running
terraRT.startAntPlusScan(callback: (Boolean) -> Unit)

Streaming Data (WOOOO)

Here comes the fun part. You can now simply start streaming data by running

terraRT.startRealtime(type: Connections, token: String, dataTypes: DataTypes)


  • connection: Connections => This argument takes a Connections enum, indicating the connection you wish to start realtime for
  • token: String => This argument is a token for verification of the user to connect to Terra's websocket API. You may generate one from the docs as shown here
  • dataTypes: DataTypes => This argument takes a DataTypes enum indicating the datatype you wish to stream for.

Similarly now, you may stop real time streaming:

terraRT.stopRealtime(type: Connections)

N.B Streaming from WEAR OS is handled on the Watch itself!!


Finally, disconnecting a device is done as:

terraRT.disconnect(type: Connections)