Skip to main content

Integration Guide

This document describes how to integrate the WarrantyLife Mobile SDK into your application.

Requirements

  • Min SDK: Android 8.0 (API level 26) or higher.
  • Target SDK: API level 35.
  • Kotlin: 1.8 or higher (Current project uses 2.1.0).
  • Jetpack Compose: Required for interactive diagnostic components.
  • Java: JDK 17 or higher.
  • Dependencies:
    • Firebase Cloud Messaging (for silent wake-up and rewards).
    • Kotlin Coroutines for asynchronous handling.

Installation

Dependencies

Add the SDK as a dependency in your app-level build.gradle file:

plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'com.google.dagger.hilt.android'
id 'kotlin-kapt'
id 'org.jetbrains.kotlin.plugin.compose'
}

dependencies {
implementation project(':sdk')
implementation project(':sdk-diagnostic') // required for diagnostic tests

// Hilt
implementation "com.google.dagger:hilt-android:2.54"
kapt "com.google.dagger:hilt-android-compiler:2.54"
implementation 'androidx.hilt:hilt-work:1.3.0'
kapt 'androidx.hilt:hilt-compiler:1.3.0' // required for @HiltWorker
implementation 'androidx.hilt:hilt-navigation-compose:1.3.0'

// Compose + Navigation
implementation "androidx.activity:activity-compose:$compose_version"
implementation "androidx.navigation:navigation-compose:$nav_version"
implementation 'androidx.compose.material3:material3:1.3.2'

// Coroutines
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.11.0'

// WorkManager (required by SDK internals)
// Already pulled transitively — no explicit entry needed unless you target WorkManager directly
}

Both com.google.dagger:hilt-android-compiler and androidx.hilt:hilt-compiler are required. The former processes @HiltAndroidApp / @HiltViewModel; the latter processes @HiltWorker used by the SDK's background workers.

Manifest Configuration

Permission ownership

PermissionDeclared inReason
FOREGROUND_SERVICESDK moduleOwned by the SDK; merged automatically into host app
FOREGROUND_SERVICE_SPECIAL_USESDK moduleSame — DropDetectionService declares foregroundServiceType="specialUse"
FOREGROUND_SERVICE_LOCATIONSDK moduleSame — SystemForegroundService (WorkManager) uses foregroundServiceType="location|dataSync"
FOREGROUND_SERVICE_DATA_SYNCSDK moduleSame
ACCESS_FINE_LOCATIONHost appRuntime permission — must be requested by the app; Play Store reviews it per-app
ACCESS_COARSE_LOCATIONHost appSame
ACCESS_BACKGROUND_LOCATIONHost appSensitive runtime permission — cannot be bundled inside an SDK
POST_NOTIFICATIONSHost appRuntime permission — user-facing, app must request it
CAMERAHost appRuntime permission

You do not need to redeclare FOREGROUND_SERVICE_* in your app manifest. Android's manifest merger pulls them in from the SDK automatically.

Host app manifest

<manifest>

<!-- Runtime permissions the host app must declare and request -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

<!-- Optional: declare camera as not required if you want to ship on devices without one -->
<uses-feature android:name="android.hardware.camera" android:required="false" />

<application
android:name=".YourApplication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:enableOnBackInvokedCallback="true"
android:fullBackupContent="@xml/backup_rules"
...>

<!-- Disable Sentry auto-init (SDK initialises it manually) -->
<meta-data
android:name="io.sentry.auto-init"
android:value="false" />

<!-- FileProvider — used by the SDK to share image URIs with the camera -->
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>

<!-- Disable WorkManager auto-init so the SDK can supply its own WorkerFactory -->
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<meta-data
android:name="androidx.work.WorkManagerInitializer"
android:value="androidx.startup"
tools:node="remove" />
</provider>

</application>
</manifest>

Backup rules

Why these rules must live in the host app: Android backup rules (fullBackupContent / dataExtractionRules) are application-level. Library modules cannot inject their own — there is no manifest-merger equivalent for XML rule files. The host app must own them.

The SDK uses three SharedPreferences files that must be excluded from backup:

FileReason to exclude
com.warrantylife.sdk_pref.xmlContains auth token and device ID. Token is session-specific and invalid after restore; device ID restoration silently suppresses device-change detection
sensor_readings.xmlRaw accelerometer/gyroscope samples — large, transient, device-specific
drop_history.xmlLocal drop-event log — device-specific sensor history

Create res/xml/backup_rules.xml (used on API 30 and below):

<?xml version="1.0" encoding="utf-8"?>
<full-backup-content>
<include domain="sharedpref" path="."/>
<exclude domain="sharedpref" path="com.warrantylife.sdk_pref.xml"/>
<exclude domain="sharedpref" path="sensor_readings.xml"/>
<exclude domain="sharedpref" path="drop_history.xml"/>
</full-backup-content>

Create res/xml/data_extraction_rules.xml (used on API 31+):

<?xml version="1.0" encoding="utf-8"?>
<data-extraction-rules>
<cloud-backup>
<include domain="sharedpref" path="."/>
<exclude domain="sharedpref" path="com.warrantylife.sdk_pref.xml"/>
<exclude domain="sharedpref" path="sensor_readings.xml"/>
<exclude domain="sharedpref" path="drop_history.xml"/>
</cloud-backup>
<device-transfer>
<include domain="sharedpref" path="."/>
<exclude domain="sharedpref" path="com.warrantylife.sdk_pref.xml"/>
<exclude domain="sharedpref" path="sensor_readings.xml"/>
<exclude domain="sharedpref" path="drop_history.xml"/>
</device-transfer>
</data-extraction-rules>

Create res/xml/file_paths.xml:

<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-cache-path name="external_cache" path="." />
<cache-path name="cache" path="." />
</paths>

Hilt Setup

Application class

@HiltAndroidApp
class MyApplication : Application()

Hilt module — provide SDK singletons

@Module
@InstallIn(SingletonComponent::class)
object DataModules {

@Singleton
@Provides
fun provideApiRepository(@ApplicationContext context: Context): ApiRepository {
return WarrantyLifeSDK.build(
context = context,
clientCode = "YOUR_CLIENT_CODE",
sentryClientKey = "YOUR_SENTRY_KEY", // pass "" to skip Sentry
appVersionCode = BuildConfig.VERSION_CODE
)
}

@Singleton
@Provides
fun provideSDKAppDataManager(@ApplicationContext context: Context): AppDataManager {
return WarrantyLifeSDK.getAppDataManager(context)
}
}

WarrantyLifeSDK.build() must be called before the first Activity reaches onStart. Providing it as a Hilt singleton ensures this.

Firebase Configuration

The SDK requires Firebase Cloud Messaging. Ensure you have added your google-services.json and applied the Google Services plugin.

Next Steps

Once the SDK is installed, proceed to the Usage Guide to initialize the SDK and start registering devices.