Files
android-webview-kiosk/CLAUDE.md
T
arnie dd04fba9af
build / build (push) Has been cancelled
feat: add tv-connect / tv-install devshell helpers
tv-connect: adb connect $TV_IP:5555
tv-install <flavor>: installs flavor release APK

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 20:14:47 +02:00

3.0 KiB

android-webview-kiosk

Android TV app: fullscreen WebView kiosk. Multiple APK flavors built from webviews.yaml (repo root) — one APK per entry. Runs on the living-room Sony Bravia KD-65XE9305 (Android 8.0, API 26; Android System WebView updates independently via Play Store — currently v138). Launched remotely through the Bravia REST IP-control API by Control4 (driver lives in a separate project). See README.md for the API sequence. Build toolchain: AGP 9.2.1, Gradle 9 (nixpkgs 26.05), build-tools 36, compileSdk 35, JDK 21.

Lab project — with deviations

This is a lab project (lab skill conventions apply) EXCEPT:

  • No container image, no helm chart, no /livez//readyz — artifact is an APK.
  • No nix build: gradle needs network for Maven deps. The flake is a dev shell only. All builds run as nix develop --command gradle ....
  • Agents cannot run nix/gradle/adb here — ask the user to run commands and report output.

NixOS aapt2 workaround

AGP cannot run the Maven-downloaded aapt2 on NixOS (dynamically linked generic Linux binary). The dev shell sets GRADLE_OPTS to pass -Dorg.gradle.project.android.aapt2FromMavenOverride=<sdk aapt2>; Gradle turns org.gradle.project.* system props into project properties, which is what AGP reads. Works since nixpkgs 26.05 (PR #449037 merged post-25.11). No file rewriting; gradle.properties stays untouched.

Commands (user-run, from repo root, direnv activates devshell)

  • Tests: gradle --no-daemon :app:test
  • All APKs: gradle --no-daemon :app:assembleReleaseapp/build/outputs/apk/<flavor>/release/<flavor>-release.apk
  • Single APK: gradle --no-daemon :app:assembleWeatherRelease
  • Connect ADB: tv-connect (uses $TV_IP from .envrc)
  • Sideload: tv-install <flavor> e.g. tv-install weather (bump versionCode in app/build.gradle.kts first for upgrades)
  • Fresh install: adb uninstall cz.c3c.webviewkiosk.<flavor> && tv-install <flavor>

Key facts

  • Package/applicationId: cz.c3c.webviewkiosk; repo name keeps the android- prefix, the package can't (hyphens illegal).
  • Webview URL + label configured in webviews.yaml (repo root). Each entry becomes a product flavor with applicationIdSuffix = ".<name>"; BuildConfig.WEBVIEW_URL is injected at build time. Changing a URL means editing the YAML, rebuilding, resideloading. Intentional: keeps Control4 integration to a single parameterless launch call.
  • signing/release.keystore is committed on purpose (private repo, LAN-only kiosk) so every build is upgrade-compatible. Don't reuse the key.
  • minSdk 26 is a hard floor — the TV never gets newer Android.
  • LEANBACK_LAUNCHER category + android:banner are what make the app visible to the Bravia API's getApplicationList/setActiveApp. Don't remove either.
  • App URIs (from getApplicationList) are per-flavor, e.g. weather: com.sony.dtv.cz.c3c.webviewkiosk.weather.cz.c3c.webviewkiosk.weather.MainActivity
  • setActiveApp alone wakes the TV from standby — no separate setPowerStatus call needed. Control4 driver can skip the wake step.