Simple Data Entry is a native Android client for DHIS2 focused on fast, reliable data capture in low-connectivity environments. It supports dataset reporting, standalone event capture, and tracker workflows with consistent card-based screens, offline caching, and deliberate, user-controlled sync. Developed by HISP Uganda.
- Dataset reporting with sectioned entry, validation, and clear status feedback
- Event programs with card and line-list views, creation, and editing
- Tracker programs with enrollments, stage events, and profile details
- Offline-first behavior with cached metadata and locally stored drafts
- Manual and login-time sync flows to avoid surprise bandwidth usage
- Kotlin + Jetpack Compose (UI)
- DHIS2 Android SDK + Rules Engine
- MVVM + StateFlow + repositories
- Hilt (DI), Room (offline persistence), WorkManager (background sync)
app/- Android application source (Compose UI, ViewModels, repositories)
- Presentation layer: Compose screens + ViewModels, navigation in
app/src/main/java/com/ash/simpledataentry/navigation - Domain layer: use cases and models under
app/src/main/java/com/ash/simpledataentry/domain - Data layer: repositories + Room + sync services under
app/src/main/java/com/ash/simpledataentry/data - Sync: WorkManager-backed background sync plus a foreground sync service for explicit user actions
flowchart LR
User[User] --> UI[Compose Screens]
UI --> VM[ViewModels]
VM --> UC[Use Cases]
UC --> Repo[Repositories]
Repo --> DB[(Room)]
Repo --> SDK[DHIS2 SDK]
SDK --> API[(DHIS2 Server)]
Repo --> Sync[WorkManager / Sync Service]
Sync --> API
Prerequisites:
- Android Studio (Giraffe or newer) with Android SDK
- JDK 17+ (Android Studio bundled JDK 21 works)
Build debug APK:
./gradlew assembleDebugRun on a device or emulator:
- Open the project in Android Studio and press Run
| Login | Sync Progress |
|---|---|
![]() |
![]() |
| Home - All Programs | Datasets Tab |
|---|---|
![]() |
![]() |
| Dataset Instances | Data Entry Form |
|---|---|
![]() |
![]() |
| Nested Accordions | Radio Options |
|---|---|
![]() |
![]() |
| Validation | Unsaved Changes |
|---|---|
![]() |
![]() |
| Enrollment List | Tracker Dashboard |
|---|---|
| Events Summary | Events Table |
|---|---|
| Tracked Entity Profile |
|---|
Release builds are automated via .github/workflows/release.yml and attach APK + AAB artifacts to a GitHub Release on tag push.
Set GitHub Secrets:
ANDROID_KEYSTORE_BASE64- base64 of your*.jksfileANDROID_KEYSTORE_PASSWORDANDROID_KEY_ALIASANDROID_KEY_PASSWORD
Example to create the base64 payload:
base64 < /path/to/keystore.jksCreate a release:
git tag v1.0.0
git push origin v1.0.0Artifacts:
- APK:
app/build/outputs/apk/release/app-release.apk - AAB:
app/build/outputs/bundle/release/app-release.aab
local.properties(ignored) holds your Android SDK path; keep it out of version control.- Server credentials are entered at runtime via the login flow; no
.envis required.
Unit tests:
./gradlew testInstrumentation tests:
./gradlew connectedAndroidTest- Sync is intentionally user-driven after login; datasets and metadata use cached values by default.
- Event line lists and tracker stage tables may load data values in the background.
Issues and PRs are welcome. Please describe the use case, expected behavior, and test coverage.
MIT. See LICENSE.









