clothescast

ClothesCast

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 jumper at home” or “50% chance of rain at 3pm — take an umbrella” — 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.

Status

Working v1: full daily-insight pipeline (Open-Meteo → on-device rendering → notification +/- TTS), Compose Settings UI for everything (location, schedule, delivery mode, units, clothes rules, voice engine, API keys, calendar tie-in), runtime permission UX, boot/timezone/locale alarm re-arm, and a debug “Fire insight now” button 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.

Tech stack

Modules

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

Installing on a phone

Three options, in roughly increasing order of friction:

First-run setup

  1. Notifications: on Android 13+ a banner at the top of Settings will ask for POST_NOTIFICATIONS. Without it the daily insight has nowhere to go.
  2. Location: tap Set location and search for a city, or enable Use device location (Settings → Data Sources) to pick up the phone’s coarse location at notify-time. Until you do one of these, the worker falls back to London.
  3. Schedule: pick a time and the days of the week you want the notification.
  4. Clothes rules (optional): the defaults (jumper, jacket, shorts, umbrella) are a sensible starting set. Add your own — e.g. gloves when temperature drops below 5°C.
  5. Voice (optional): the platform TTS engine works out of the box. To use a more natural online voice, pick Gemini in Settings → Voice and paste your API key in Settings → API Keys.
  6. Calendar tie-in (optional): toggle Use calendar events in Settings → Data Sources and grant READ_CALENDAR to let the daily sentence reference an overlapping event by name.
  7. Verify: tap the Fire insight now button (About → Debug card, only in debug builds) to exercise the full pipeline without waiting until the scheduled time.

Building locally

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.

OEM background restrictions

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.

Roadmap