Integration Guide
This document describes how to integrate the WarrantyLife Mobile SDK into your application.
Requirements
- Android
- 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
- Android
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-compilerandandroidx.hilt:hilt-compilerare required. The former processes@HiltAndroidApp/@HiltViewModel; the latter processes@HiltWorkerused by the SDK's background workers.
Manifest Configuration
Permission ownership
| Permission | Declared in | Reason |
|---|---|---|
FOREGROUND_SERVICE | SDK module | Owned by the SDK; merged automatically into host app |
FOREGROUND_SERVICE_SPECIAL_USE | SDK module | Same — DropDetectionService declares foregroundServiceType="specialUse" |
FOREGROUND_SERVICE_LOCATION | SDK module | Same — SystemForegroundService (WorkManager) uses foregroundServiceType="location|dataSync" |
FOREGROUND_SERVICE_DATA_SYNC | SDK module | Same |
ACCESS_FINE_LOCATION | Host app | Runtime permission — must be requested by the app; Play Store reviews it per-app |
ACCESS_COARSE_LOCATION | Host app | Same |
ACCESS_BACKGROUND_LOCATION | Host app | Sensitive runtime permission — cannot be bundled inside an SDK |
POST_NOTIFICATIONS | Host app | Runtime permission — user-facing, app must request it |
CAMERA | Host app | Runtime 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:
| File | Reason to exclude |
|---|---|
com.warrantylife.sdk_pref.xml | Contains auth token and device ID. Token is session-specific and invalid after restore; device ID restoration silently suppresses device-change detection |
sensor_readings.xml | Raw accelerometer/gyroscope samples — large, transient, device-specific |
drop_history.xml | Local 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.