A daily weather-insight app for Android. Each morning, at a time you set, ClothesCast posts a one-sentence comparative summary — “4°C warmer than yesterday, leave the sweater at home” or “Rain likely around 3pm.” — derived on-device from yesterday’s actual weather, today’s forecast, and the clothes thresholds you’ve configured.
It can also speak the insight aloud — through the platform TTS engine, or through an online voice (Gemini) if you’d rather a more natural read.
See PRIVACY.md for what data leaves the device and when.
Working v1: full ClothesCast pipeline (Open-Meteo → on-device rendering → notification, phone TTS, Cast, MQTT, widgets, and cached Today refreshes), Compose Settings UI for location, schedule, delivery toggles, units, clothes rules, voice, API keys, calendar extras, smart-home outputs, privacy, and telemetry, runtime permission UX, boot/timezone/locale alarm re-arm, and debug / manual actions for testing without waiting until the scheduled time.
Distribution: every push to main ships a signed AAB to the Play Store
internal track for testers, and a debug APK is also available from the CI
artifact (see below) for sideload installs.
commonMain later
without a rewrite.USE_EXACT_ALARM) → BroadcastReceiver → WorkManager
for daily scheduling that survives Doze, reboot, timezone and locale
changes.TextToSpeech engine
(default, fully on-device), or an online voice via the Gemini API.
Online engines are BYOK; keys are encrypted on-device via Tink +
Android Keystore + DataStore Preferences.READ_CALENDAR granted, calendar
events can gate event-relevant weather advice without turning event titles
into notification, voice, MQTT, or Cast content.ACCESS_COARSE_LOCATION granted, the
worker uses the phone’s coarse location at notify-time instead of the
city you picked.| Module | Status |
|---|---|
:core:domain |
Pure-Kotlin models, use cases (insight rendering, clothes rules), repository interfaces |
:core:data |
Open-Meteo forecast + geocoding clients, Gemini TTS client, parser tests |
:app |
Compose UI, manifest, receivers, worker, alarm scheduler, DI, platform TTS, calendar reader, encrypted key store, widgets, Cast, MQTT, telemetry |
Three options, in roughly increasing order of friction:
main build automatically. Every push to main ships a
signed AAB to this track.testers group in
the FAD console, you get the debug APK from every push to main with a
one-tap install link.main.
.github/workflows/ci.yml).app-debug-apk artifact.app-debug.apk to the phone (Drive, USB, etc.).POST_NOTIFICATIONS. Without it the daily insight has nowhere
to go.sweater, jacket,
coat, gloves, shorts) are a sensible starting set. Add your own or
tune the thresholds to match how you dress.READ_CALENDAR to let calendar presence
gate event-relevant advice without putting event titles in rendered output.
See docs/calendar-holidays.md for how holidays
are used and what to do if one shows on the wrong date.Requires JDK 21. Pure-Kotlin modules build without an Android SDK:
./gradlew :core:domain:test :core:data:test
The :app module needs the standard Android SDK (compileSdk 35,
build-tools;35.0.0) on the local Android Studio install path. The CI
workflow shows the exact setup.
Some Android OEMs (Xiaomi, Oppo, OnePlus, aggressive Samsung profiles) kill
backgrounded apps and prevent the alarm from firing on schedule. See
dontkillmyapp.com for per-OEM workarounds —
typically “exclude from battery optimisations” and “allow autostart”. The
underlying scheduling primitive (setExactAndAllowWhileIdle with
USE_EXACT_ALARM) is the strictest the platform offers; anything that
suppresses it is a vendor-side override.