A native Android client for Pledger.io — a self-hosted, open-source personal finance manager. Connects to your own Pledger REST backend (/v2/api/…).
| Area | Choice |
|---|---|
| Language | Kotlin |
| UI | Jetpack Compose (Material 3) |
| Architecture | MVVM + Repository (+ Use Cases where needed) |
| DI | Hilt (KSP) |
| Networking | Retrofit + OkHttp + Moshi |
| Images | Coil (authenticated via shared OkHttp client) |
| Database | Room (offline cache, v6 schema with explicit migrations) |
| Async | Coroutines + Flow |
| Navigation | Jetpack Navigation Compose |
| Background work | WorkManager |
| Auth | JWT + refresh token in EncryptedSharedPreferences; proactive refresh |
| Build | AGP 8.13, Gradle 8.13, version catalog (gradle/libs.versions.toml) |
| Min SDK | 26 (Android 8.0) |
| Target / compile SDK | 36 (Android 16) |
- Android Studio Meerkat (2024.3.1) or newer (Android 16 SDK support)
- JDK 21 for Gradle builds (JDK 25 is not supported by the Android Gradle Plugin)
- Android SDK Platform 36 and Build-Tools 36.0.0 (install via SDK Manager)
- Open the project in Android Studio.
- Sync Gradle dependencies.
- Run on an emulator or device (API 26+).
- On first launch, enter your Pledger.io server base URL (validated via
GET /health). - Sign in with your credentials (
POST /v2/api/security/authenticate).
HTTP cleartext is allowed in debug via network_security_config.xml for local/dev servers; use HTTPS in production.
app/src/main/java/com/pledgerio/app/
├── data/
│ ├── local/ # Room database, DAOs, entities
│ ├── remote/ # Retrofit API, DTOs, interceptors
│ └── repository/ # Repository implementations
├── domain/
│ ├── model/ # Domain models
│ ├── repository/ # Repository interfaces
│ └── usecase/ # Use cases (e.g. dashboard aggregation)
├── ui/
│ ├── theme/ # Material 3 theme
│ ├── components/ # Shared composables (cards, AccountIcon, …)
│ ├── navigation/ # NavGraph, Screen routes
│ ├── onboarding/ # Server setup & login
│ ├── dashboard/
│ ├── transactions/ # List, detail, create form, filters
│ ├── accounts/ # List, detail, add/edit form
│ ├── budgets/
│ ├── reports/
│ └── settings/
├── di/ # Hilt modules
└── util/ # SessionManager, SyncWorker, CurrencyProvider, …
- Onboarding — Configurable server URL (
DynamicBaseUrlInterceptor), health check, JWT login; server URL kept after auth errors or logout - Dashboard — Accounts overview, income/expense summary, recent transactions; FAB menu to add transaction or account
- Transactions — Paged list with month navigation, infinite scroll, type chips (income/expense), optional filters (category, expense/budget, contract) with inline autocomplete; pull-to-refresh; create transaction form with type-specific account inputs (creditor/debtor search vs owned-account dropdown), Guided/Power experience defaults, and one-tap AI auto-classification suggestions (expense group, category, tags); transaction detail with classification and account logos
- Accounts — Grouped list with All / Owned / Parties filter chips (always visible, including empty states); type-aware add menu, balances from
/v2/api/balance; detail with logo, type explanation, transaction history, and delete; add/edit with catalog-driven fields (see Account types) - Currencies — Fetched from API, cached in Room, used for
formatCurrency()across the app - Budgets — Initial budget setup on 404; monthly overview per expense group; manage groups (add/edit); detail screen (see Budgets)
- Reports — Report type selector UI (chart data integration in progress)
- Settings — Storage, biometric unlock, language (English / Dutch / German / system), theme, display currency, finance experience mode (Guided/Power), in-app bug reports (logs + GitHub issue), logout
- Offline — Room cache with network fallback; periodic sync via WorkManager (accounts, currencies, budget alerts)
- Account logos —
iconFileCodeloaded fromGET /v2/api/files/{fileCode}on account and transaction detail screens
- Edit transaction from detail screen
- Full reports charts (Vico dependency is present)
- Deep links from budget notifications
| Route | Screen |
|---|---|
server_setup |
Server URL entry |
login |
Authentication |
dashboard |
Main overview (bottom tab) |
transactions |
Transaction list (bottom tab) |
transaction/add |
Create transaction |
transaction/{id} |
Transaction detail |
accounts |
Account list (bottom tab) |
account/add?type={type} |
Create account (optional type preselect) |
account/{id} |
Account detail |
account/{id}/edit |
Edit account |
budgets |
Budget overview (current month); add expense groups via FAB |
budget/{id} |
Expense group detail; edit monthly budget |
reports |
Reports (bottom tab) |
settings |
Settings |
- Architecture Overview — Layers, data flow, API integration, UI patterns
- Account types — Owned vs counterparty accounts, type codes, transaction mapping
- Budgets — Initial setup, expense groups, API mapping
- Transaction form redesign — Planned UX for creating transactions (type-first flow, amount hero, contextual account labels)
- Invoice scan to transaction plan — Proposed OCR + text extraction pipeline to prefill new transactions
- Usability modes — Guided mode for novices and Power mode for advanced users
- Localization — English, Dutch, and German (extensible)
- Architecture Decision Records — Rationale for major technical choices
Backend API reference: pledger-io/rest-application (/v2/api/… contract).
| Script | Output |
|---|---|
scripts/build-debug.sh / build-debug.ps1 |
Debug APK |
scripts/build-release.sh / build-release.ps1 |
Release APK (minified) |
Or use Gradle directly:
./gradlew assembleDebugOn Windows (PowerShell):
.\gradlew.bat assembleDebugRequires JDK 21.
| Workflow | Trigger | Result |
|---|---|---|
| CI | Push / PR to main or master |
Unit tests + lint + instrumented smoke test + debug APK artifact |
| Release | Publish a GitHub Release, or manual run | Release APK attached to the release |
Distributing an APK on GitHub Release
- Push a tag (e.g.
v1.0.0) and create a release from that tag, or create a release in the GitHub UI. - Click Publish release (draft releases do not run the workflow).
- The Release workflow builds
assembleReleaseand uploadspledger-io-<tag>-<version>.apkto the release assets.
To test the release build without publishing: Actions → Release → Run workflow. The APK is saved as a workflow artifact.
Users can report problems from Settings → About → Report a problem. The app collects sanitized recent logs, prefills the org bug report form in the browser (summary, description, environment, logs), and the user taps Submit on GitHub — no app credentials required. Sign in to GitHub only if the repository requires it to open issues.
Production signing is required for release builds — configure these repository secrets:
| Secret | Description |
|---|---|
ANDROID_KEYSTORE_BASE64 |
Base64-encoded .jks / .keystore file |
ANDROID_KEYSTORE_PASSWORD |
Keystore password |
ANDROID_KEY_ALIAS |
Key alias |
ANDROID_KEY_PASSWORD |
Key password |
Encode a keystore (example):
base64 -w 0 release.keystore > keystore.b64This app is designed to work with the Pledger.io backend. See the backend repository for server licensing.