> ## Documentation Index
> Fetch the complete documentation index at: https://docu.truemetrics.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# SDK Interface

> Overview of the functionality of the Truemetrics Android SDK 1.5.4

### 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:

```groovy theme={null}
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:

```groovy theme={null}
implementation 'io.truemetrics:truemetricssdk:1.5.4'
```

### Initialize SDK

SDK behaves like a singleton object that manages its own internal state. Initialize it in your Application class:

```kotlin theme={null}
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:

```kotlin theme={null}
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:

```kotlin theme={null}
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 Code                        | Description                                                          |
| --------------------------------- | -------------------------------------------------------------------- |
| AUTHENTICATION\_ERROR             | API key is not valid, expired or revoked                             |
| UPLOAD\_ERROR                     | Recordings couldn't be uploaded after exhausting all attempts        |
| STORAGE\_FULL                     | Device storage is full which prevents saving sensor readings         |
| MISSING\_NOTIFICATION\_PERMISSION | Notification permission not granted, foreground service cannot start |
| CONFIG\_ERROR                     | Configuration error                                                  |
| TRAFFIC\_USED\_UP                 | All allotted traffic has been used                                   |
| SENSORS\_NOT\_WORKING             | Some sensors are not working. Check if permissions are missing       |

### Start Recording

```kotlin theme={null}
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

```kotlin theme={null}
sdk.stopRecording()
```

Stopping recording also stops the Foreground service and removes the notification.

### Check Recording Status

```kotlin theme={null}
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):

```kotlin theme={null}
val deviceId = sdk.getDeviceId()
```

### Log Metadata

Log standardized delivery/pickup event metadata:

```kotlin theme={null}
import io.truemetrics.truemetricssdk.metadata.StandardMetadata

sdk.logMetadata(StandardMetadata(
    eventTime = "2025-01-15T14:30:00Z",
    eventType = "delivery_successful",
    deliveryId = "parcel_123",
    tourId = "tour_456",
    waypointLatitude = "52.5200",
    waypointLongitude = "13.4050",
    referenceLatitude = "52.5201",
    referenceLongitude = "13.4051",
    address = "Pflanzstrasse 5, 10762 Berlin"
))
```

The map-based `logMetadata(Map<String, String>)` overload is deprecated. Use `logMetadata(StandardMetadata)` instead.

For advanced metadata management with templates and tags, see the [metadata chapter](/metadata).

### Statistics API

Monitor upload and sensor health:

```kotlin theme={null}
// 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

```kotlin theme={null}
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.
