Android SDK
The Tessol Android SDK exposes TessolCommandController for controlling compatible devices over Bluetooth Low Energy (BLE), synchronizing time, reading temperature data, and uploading records. This guide targets the current stable SDK, 1.0.8.
Requirements
Section titled “Requirements”- Android API level 24 or newer
- A BLE-capable Android device
- A provisioned AWS IoT device certificate and matching PKCS#8 private key
- Runtime Bluetooth permissions; location permission is also required for BLE scanning on some Android versions before Android 12
- Internet access when uploading records
Request certificates and compatible device details from TAMsys support.
Install the SDK
Section titled “Install the SDK”Add Maven Central and the SDK dependency to your Android project:
repositories { google() mavenCentral()}
dependencies { implementation("in.tessol.tamsys:tamsys-sdk:1.0.8")}For a Groovy build file:
dependencies { implementation "in.tessol.tamsys:tamsys-sdk:1.0.8"}The release is published as in.tessol.tamsys:tamsys-sdk:1.0.8 on Maven Central.
Declare BLE permissions
Section titled “Declare BLE permissions”The host app is responsible for declaring and requesting BLE permissions. Use the permissions that apply to your target SDK and scanning behavior; this is a minimal baseline for scanning and connecting:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />
<!-- Android 12 (API 31) and newer --> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" tools:targetApi="s" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!-- Android 11 (API 30) and older --> <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30" /></manifest>Manifest declarations do not grant dangerous permissions. Request the applicable permissions at runtime before scanning or issuing device commands, and explain the request in your UI.
Initialize the SDK
Section titled “Initialize the SDK”-
Import the public API
import `in`.tessol.tamsys.v2.sdk.TessolCommandControllerimport `in`.tessol.tamsys.v2.sdk.TessolSdkimport `in`.tessol.tamsys.v2.sdk.data.model.AwsConfigs -
Initialize once at application startup
Provide the device certificate and PKCS#8 private key as streams before calling any other SDK functionality:
TessolSdk.initialize(AwsConfigs(deviceCertInputStream = context.assets.open("device-certificate.pem"),privateKeyInputStream = context.assets.open("private_key_pkcs8.pem"))) -
Create and retain a controller for the device workflow
val controller = TessolCommandController.getInstance(context)
Handle results
Section titled “Handle results”Controller operations are suspending functions that return Kotlin Result<T>. Call them from a coroutine and handle both branches:
lifecycleScope.launch { controller.getSystemInfo(deviceId) .onSuccess { systemInfo -> // Update the UI with systemInfo. } .onFailure { error -> // Show a recoverable error state. }}Most one-shot BLE commands retry up to three times within a default total timeout of 30 seconds. Record synchronization has the separate timeout constraint described below.
Device operations
Section titled “Device operations”Every device operation requires the exact deviceId: String assigned to the compatible Tessol device.
Start and stop an operation
Section titled “Start and stop an operation”val startResult = controller.startOperation(deviceId)val stopResult = controller.stopOperation(deviceId)Read and synchronize device time
Section titled “Read and synchronize device time”val timeResult = controller.getTime(deviceId)val setTimeResult = controller.setTime( deviceId = deviceId, time = System.currentTimeMillis())Set the data logging interval
Section titled “Set the data logging interval”val intervalResult = controller.setInterval( deviceId = deviceId, intervalSeconds = 60)Use a positive interval in multiples of 5 seconds.
Read system information
Section titled “Read system information”val systemInfoResult = controller.getSystemInfo(deviceId)System information can include firmware version, stored data point count, and other device metadata.
Factory reset
Section titled “Factory reset”val resetResult = controller.factoryReset(deviceId)Temperature and stored records
Section titled “Temperature and stored records”Get the current temperature
Section titled “Get the current temperature”val temperatureResult = controller.getCurrentTemp(deviceId)The controller can return its most recently fetched current-temperature value for up to one minute. When one app works with multiple devices, retain a separate controller for each device workflow rather than alternating device IDs on one controller.
Retrieve stored temperature records
Section titled “Retrieve stored temperature records”Use the V2 record retrieval API and allow at least 90 seconds for the complete operation:
val syncResult = controller.saveRecordsFromDeviceV2( deviceId = deviceId, timeoutMs = 120_000L)On success, the result contains the number of records saved in the SDK’s local database. Successfully processed sectors are then erased from the device. Do not terminate the operation midway, and surface failures so the user can retry safely.
Upload records
Section titled “Upload records”Upload all records currently stored in the SDK’s local database:
val uploadResult = controller.uploadRecordsFromDevice()Attach application-specific data to every uploaded record when needed:
val extraData = mapOf( "batteryVoltage" to "1", "longitude" to "76.6897041", "latitude" to "30.7075106")
val uploadResult = controller.uploadRecordsFromDevice( extraData = extraData)The result contains the uploaded record count. The SDK removes local records only after a successful upload. SDK 1.0.8 publishes uploads to TAMsys through the AWS IoT Core HTTPS device API.
To read and immediately upload one current temperature record:
val uploadResult = controller.uploadCurrentTemperature( deviceId = deviceId, extraData = extraData)Reference application
Section titled “Reference application”The sample app’s CommandsActivityPublicSDK demonstrates command buttons, interval prompts, loading states, and success or failure dialogs.
| Command | Action |
|---|---|
SystemInfo |
Fetch system data |
SetInterval |
Set the logging interval |
GetTime |
Fetch device time |
SetTime |
Set device time to the Android system time |
StartOperation |
Start device operation |
StopOperation |
Stop device operation |
GetCurrentTemperature |
Fetch the latest temperature |
GetStoredSensorData |
Retrieve stored temperature data |
UploadData |
Upload stored data |
FactoryReset |
Reset the device |
Implementation checklist
Section titled “Implementation checklist”- Use SDK
1.0.8or explicitly validate the API differences before pinning another version. - Initialize the SDK once before creating a controller.
- Declare and request the platform-appropriate BLE permissions.
- Run controller operations in a lifecycle-aware coroutine scope.
- Handle both success and failure from every
Result<T>. - Use
saveRecordsFromDeviceV2()with a timeout of at least 90 seconds. - Treat device certificates and private keys as sensitive credentials.
Reference UI and usage flow: Tessol Android sample app README, updated for SDK 1.0.8. Dependency version, public signatures, timeout constraints, and lifecycle behavior on this page were cross-checked against the published SDK 1.0.8 artifact and its source JAR.
