A complete Android test project for the LightAnalytics SDK. Jetpack Compose dashboard that lets you fire every SDK API call and see results live.
LightAnalyticsTestApp/
├── app/ ← Test app (Jetpack Compose)
│ └── src/
│ ├── main/
│ │ ├── TestApplication.kt SDK initialisation
│ │ ├── MainActivity.kt
│ │ └── ui/
│ │ ├── AnalyticsTestApp.kt Full Compose dashboard UI
│ │ └── AnalyticsViewModel.kt All SDK test actions
│ └── androidTest/
│ └── AnalyticsIntegrationTest.kt 10 instrumented tests
└── light-analytics/ ← SDK module (source included)
└── src/main/kotlin/… 16 production Kotlin files
Android Studio → File → Open → select the LightAnalyticsTestApp folder
The gradle-wrapper.jar binary is not included (binary files don't ship well in zips).
Android Studio will show a banner: "Gradle files have changed since last project sync" or prompt to fix the wrapper.
If it doesn't auto-fix, open the Terminal tab inside Android Studio and run:
gradle wrapper --gradle-version=8.9Or go to File → Project Structure → Project and click "OK" — this triggers a full sync.
Click "Sync Now" in the yellow banner. Gradle downloads all dependencies (~200 MB first time).
Press ▶ Run or Shift+F10. Minimum API 24.
The app is a two-panel dashboard:
Left panel — Controls: every SDK API grouped by category
Right panel — Live log: timestamped result of every action you tap
| Section | What it tests |
|---|---|
| Identity | identify(userId), anonymous ID |
| Core Tracking | track() simple, with properties, trackScreen(), burst ×10 |
| Custom Event | Enter event name + key/value and fire it |
| Super Properties | Register (String/Int/Bool/Double), unregister, clear, override |
| Queue Control | flush() — send immediately; reset() — clear everything |
| Edge Cases | Blank event name (SDK drops it), large payload (SDK truncates), override test |
| Almatar OTA | Real domain events: flight search, Umrah package, booking completed |
The test app points to https://httpbin.org/post by default — it echoes back whatever you POST to it, so you can see the full JSON payload in Logcat.
To point at your real endpoint, edit app/build.gradle.kts:
buildConfigField("String", "ANALYTICS_API_KEY", "\"your-real-key\"")
buildConfigField("String", "ANALYTICS_BASE_URL", "\"https://your-endpoint.com/v1/batch\"")With debug = true, filter Logcat by tag LightAnalytics:
adb logcat -s LightAnalytics
You'll see:
D/LightAnalytics: Queued: button_clicked (depth: 1)
D/LightAnalytics: Queued: burst_event_0 (depth: 2)
...
D/LightAnalytics: Flush: start (depth: 5)
D/LightAnalytics: Flush: sending 5 events (attempt 1)
D/LightAnalytics: Flush: sent 5 events
D/LightAnalytics: Flush: complete — queue empty
./gradlew :light-analytics:testTests use Robolectric — runs entirely on JVM, no emulator required.
./gradlew :app:connectedAndroidTest10 tests covering: init, identify+track, super prop merge, burst, reset, blank name, large payload, and the full OTA booking flow.
The SDK POSTs to your baseUrl:
POST https://your-endpoint.com/v1/batch
Authorization: Bearer <apiKey>
Content-Type: application/json
{
"batch": [
{
"eventId": "uuid",
"name": "flight_search_started",
"timestamp": "2026-03-15T10:30:00Z",
"userId": "almatar-user-123",
"anonymousId":"anon-abc-xyz",
"sessionId": "sess-def-uvw",
"context": {
"platform": "android",
"appVersion": "1.0.0",
"deviceModel": "Google Pixel 8",
"osVersion": "15",
"locale": "ar-SA",
"timezone": "Asia/Riyadh"
},
"properties": {
"origin": "RUH",
"destination": "LHR",
"passengers": 2
}
}
]
}2xx → events removed from queue
429 / 5xx → exponential backoff retry (2s → 4s → 8s → 16s → 32s, max 5 attempts)
Other 4xx → batch dropped immediately