# Encore A minimal, modern Android app: **Kotlin** + **Jetpack Compose** (Material 3), built and tested with **Nix**. Jetpack Compose *is* the modern Android UI framework — declarative Kotlin UI that has replaced the old XML layouts. Material 3 is Google's current design system, wired up here with dynamic (wallpaper-based) color on Android 12+. ## Layout ``` flake.nix Nix entrypoint: dev shells, SDK, package, emulator package.nix Reproducible APK build (nixpkgs-style derivation) deps.json Lockfile of Gradle/Maven deps (generated — see below) settings.gradle.kts Gradle project + repositories build.gradle.kts Root build script (declares plugin versions) gradle/libs.versions.toml Version catalog: all dependency/plugin versions app/ build.gradle.kts The :app module (Android + Compose config) src/main/ AndroidManifest.xml App/activity declaration kotlin/ca/ksamad/encore/ MainActivity.kt Entry activity; sets the Compose content Theme.kt Material 3 theme (dynamic color) res/values/ strings.xml, themes.xml src/test/kotlin/... A plain JVM unit test ``` ## Everyday Development (Recommended) Use the dev shell — it puts a JDK, Gradle, and the Android SDK on your PATH with the right environment variables set: ```sh nix develop gradle assembleDebug # build the debug APK -> app/build/outputs/apk/debug/ gradle testDebugUnitTest # run unit tests gradle tasks # see everything available ``` The debug APK is unsigned but installable on a device/emulator: ```sh adb install app/build/outputs/apk/debug/app-debug.apk ``` ### Android Studio For the GUI editor, Compose previews, and device manager: ```sh nix develop .#studio android-studio ``` Open this folder as an existing project. (Android Studio manages its own SDK; the command-line flow above is fully independent of it.) ### Emulator ```sh nix run .#emulate ``` ## Reproducible Build with Nix ```sh nix build # -> ./result/encore.apk ``` Unlike `gradle assembleDebug`, this build runs **fully offline**: every Gradle/Maven dependency is pinned by hash in `deps.json`, and Nix supplies the Android SDK. It also runs the unit tests (`testDebugUnitTest`) as its check phase, so a green `nix build` means both "it assembles" and "tests pass". This is what you'd use in CI for a reproducible artifact. > Note: `package.nix` and `app/build.gradle.kts` contain a few small workarounds, active > **only** during dependency capture (gated on the `IN_GRADLE_UPDATE_DEPS` env var), that > stop Nix's "resolve every configuration" sweep from tripping over internal AGP/Kotlin > configurations. They don't affect the dev shell or the actual build. See the comments in > `app/build.gradle.kts` for the details. ### Regenerating `deps.json` Any time you change a dependency or plugin version (i.e. edit `gradle/libs.versions.toml` or a `build.gradle.kts`), regenerate the lockfile: ```sh nix build .#default.mitmCache.updateScript ./result # runs the build under a proxy, rewrites ./deps.json ``` Then commit the updated `deps.json`. (It works by recording Gradle's dependency downloads through a man-in-the-middle proxy and storing their hashes — see `package.nix`.) ## Docs - [`docs/device-testing.md`](docs/device-testing.md) — build & install onto a real Android device/DAP over USB (and the NixOS `adb` notes). - [`docs/TODO.md`](docs/TODO.md) — near-term roadmap / known bugs. ## Version notes Pinned in `gradle/libs.versions.toml`: AGP 8.7.3, Kotlin 2.0.21, Compose BOM 2024.10.01, compiled against `compileSdk` 35, `minSdk` 24. Nix supplies Gradle 8.14. If you bump these, keep AGP/Kotlin/Gradle mutually compatible and regenerate `deps.json`.