Skip to main content

Setup and Maven Repository

Project requires Java 17. If necessary, adjust your Java version in your IDE, typically in IDE's File -> Project structure -> SDK Location. Update your project-level settings.gradle file and dependencyResolutionManagement section:
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.PREFER_PROJECT)
    repositories {
        // other repositories
        maven {
            name = 'truemetrics SDK'
            url = "https://github.com/TRUE-Metrics-io/truemetrics_android_SDK_p_maven/raw/main"
        }
    }
}

Declare Dependency

Inside your build.gradle add the following dependency:
implementation 'io.truemetrics:truemetricssdk:1.4.0'

Initialize SDK

SDK behaves like a singleton object that manages its own internal state. Initialize it in your Application class:
class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()

        val config = SdkConfiguration.Builder("YOUR_API_KEY").build()
        TruemetricsSdk.init(this, config)
    }
}

Custom Foreground Notification

The SDK runs as a foreground service and shows a notification while recording. You can customize this notification using the SDK’s notification channel:
class CustomNotificationFactory : ForegroundNotificationFactory {
    override fun createNotification(context: Context): Notification {
        // Use SDK's notification channel ID
        return NotificationCompat.Builder(context, "FOREGROUND_SERVICE")
            .setContentTitle("Truemetrics SDK Running")
            .setContentText("Collecting sensor data...")
            .setSmallIcon(R.drawable.ic_notification)
            .setOngoing(true)
            .build()
    }
}

val config = SdkConfiguration.Builder("YOUR_API_KEY")
    .foregroundNotificationFactory(CustomNotificationFactory())
    .build()
Make sure to ask user for notification permission if device runs Android 13 or later.

Observing SDK Status

Use the observeSdkStatus() Flow to monitor SDK state changes:
val sdk = TruemetricsSdk.getInstance()

sdk.observeSdkStatus().collect { status ->
    when (status) {
        is Status.Uninitialized -> {
            // SDK not yet initialized
        }
        is Status.Initialized -> {
            // SDK initialized, deviceId available
            val deviceId = status.deviceId
        }
        is Status.RecordingInProgress -> {
            // Recording is active
            val deviceId = status.deviceId
        }
        is Status.RecordingStopped -> {
            // Recording has stopped
        }
        is Status.DelayedStart -> {
            // Waiting for auto-start delay
            val deviceId = status.deviceId
            val delayMs = status.delayMs
        }
        is Status.TrafficLimitReached -> {
            // Traffic limit reached
        }
        is Status.ReadingsDatabaseFull -> {
            // Device storage full
        }
        is Status.Error -> {
            // SDK encountered an error
            val errorCode = status.errorCode
            val message = status.message
        }
        is Status.AskForPermissions -> {
            // SDK requesting permissions
            val permissions = status.permissions
        }
    }
}

Error Codes

When Status.Error is received, the errorCode indicates what went wrong:
Error CodeDescription
AUTHENTICATION_ERRORAPI key is not valid, expired or revoked
UPLOAD_ERRORRecordings couldn’t be uploaded after exhausting all attempts
STORAGE_FULLDevice storage is full which prevents saving sensor readings
MISSING_NOTIFICATION_PERMISSIONNotification permission not granted, foreground service cannot start
CONFIG_ERRORConfiguration error
TRAFFIC_USED_UPAll allotted traffic has been used
SENSORS_NOT_WORKINGSome sensors are not working. Check if permissions are missing

Start Recording

val sdk = TruemetricsSdk.getInstance()
sdk.startRecording()
Starting the recording also starts the Foreground service and shows the notification. Recording continues even when the app exits.

Stop Recording

sdk.stopRecording()
Stopping recording also stops the Foreground service and removes the notification.

Check Recording Status

val isRecording = sdk.isRecordingInProgress()
val isStopped = sdk.isRecordingStopped()
val startTime = sdk.getRecordingStartTime() // milliseconds since epoch

Device ID

Get the unique device identifier (available after initialization):
val deviceId = sdk.getDeviceId()

Log Metadata

sdk.logMetadata(mapOf(
    "userId" to "user123",
    "sessionId" to "session_abc"
))
For advanced metadata management with templates and tags, see the metadata chapter.

Statistics API

Monitor upload and sensor health:
// Upload statistics
val uploadStats = sdk.getUploadStatistics()
uploadStats?.let {
    println("Successful uploads: ${it.successfulUploadsCount}")
    println("Last upload: ${it.lastSuccessfulUploadTimestamp}")
}

// Sensor statistics with quality assessment
val sensorStats = sdk.getSensorStatistics()
sensorStats?.forEach { stat ->
    println("Sensor: ${stat.sensorName}")
    println("Quality: ${stat.quality}") // EXCELLENT, GOOD, POOR, BAD, or UNKNOWN
}

Deinitialize SDK

sdk.deinitialize()
De-initialization stops recording if in progress and tears down the SDK. Warning: After calling deinitialize(), the SDK instance becomes unusable. You must call init() again to use the SDK.