Tired of unpredictable weather? Rain keeps you prepared with accurate forecasts, interactive maps, and beautiful design. ๐ฆ๏ธ๐ฑ๐บ๏ธ
๐ Available in 38 languages โข ๐จ Material You & AMOLED โข ๐จ Air quality (EU/US AQI) โข ๐บ๏ธ Interactive weather map โข ๐ฑ Home screen widgets
๐ก๏ธ Comprehensive Weather Data
- Real-time conditions with feels-like temperature โข Hourly forecasts (12 days) โข 12-day daily outlooks
- Location-aware time: forecast slots use each place's Open-Meteo timezone and UTC offset; HTTP
Dateskew corrects a wrong device clock - Detailed metrics: UV index, humidity, wind speed/direction, precipitation, visibility, pressure, dew point
- Day/night-aware weather icons โข Sunrise/sunset times โข Expandable hourly variable details
๐จ Air Quality
- Hourly air quality from Open-Meteo Air Quality API (7-day forecast, aligned to weather timestamps)
- Summary card on the main weather screen: AQI value, severity badge, colored scale, health advice
- Pollutant breakdown with progress bars: PM2.5, PM10, Oโ, NOโ, SOโ, CO (ฮผg/mยณ)
- Choose European AQI or US AQI in Settings โข Cached offline with weather data
๐บ๏ธ Interactive Weather Map
- OpenStreetMap-based interactive map โข Weather markers for all saved cities
- Tap markers for quick weather preview โข Long-press to add new locations
- Visual city selection with GPS support โข Map tile caching (30 days) โข Dark mode styling
๐๏ธ Multi-City Management
- Save unlimited cities to your watchlist โข Drag-to-reorder โข Pull-to-refresh all
- Live local wall clock on each city card โข Correct offsets between cities even when the device clock is off
- City search with autocomplete โข Manual coordinate entry โข GPS auto-detection
- Edit or remove saved cities โข Timezone from the weather API for each location
๐ Smart Notifications
- Scheduled weather forecasts (1-5 hour intervals) โข Custom time window (start/end)
- Weather-condition-specific icons โข Silent notifications (no sound/vibration)
- Automatic cancellation when disabled โข Background scheduling
๐ฑ Home Screen Widgets (Android)
- Three Material You widgets โ pin any from Settings โ Widget (home screen and lock screen):
- Compact (1ร1) โ weather icon and temperature, fixed size
- Current (2ร2) โ resizable card with temperature on top and weather icon at bottom-left
- Clock (4ร1 bar) โ live clock and date, weather icon, city name and temperature; horizontally resizable
- Respects app Celsius/Fahrenheit, rounded temperature, and 12h/24h time format (Clock widget)
- Background refresh (Workmanager, ~15 min minimum): fetches stale main weather when online, then pushes widget data โข Custom background and text colors (HSV picker)
- Updates when the app loads cached weather, after fresh fetches, and from the periodic background task
๐จ Beautiful Design
- Material You dynamic theming (wallpaper colors) โข Pure AMOLED black theme
- Light/Dark/System modes โข Large element mode toggle โข Edge-to-edge display
- Google Fonts (Ubuntu) โข Smooth animations โข Shimmer loading states
๐ Extensive Localization
- 38 languages including: English, ะ ัััะบะธะน, ไธญๆ, ุงูุนุฑุจูุฉ, เคนเคฟเคจเฅเคฆเฅ, Espaรฑol, Franรงais, Deutsch, Portuguรชs, ํ๊ตญ์ด, ๆฅๆฌ่ช, Tรผrkรงe, and many more
- Regional preferences โข 12h/24h time format support
๐งฎ Customization Options
- Temperature: Celsius/Fahrenheit โข Measurement system: Metric/Imperial
- Wind speed: kph/m/s โข Pressure: hPa/mmHg โข Rounded temperatures (app + widget)
- Air quality standard: European AQI / US AQI
- 12h/24h time format (app, pickers, notifications, and Clock widget)
- Widget color customization with HSV color picker
Get the latest APK or builds for other platforms from the Releases Section.
- Flutter SDK 3.44 or higher (see
pubspec.yaml) - Dart SDK 3.12 or higher
- Android Studio / Xcode for platform-specific builds
# Clone the repository
git clone https://github.com/darkmoonight/Rain.git
cd Rain
# Install dependencies
flutter pub get
# Generate code (Isar, Freezed, JSON, translations)
dart run slang
dart run build_runner build --delete-conflicting-outputs
# Run the app (Android uses flavor gms by default; see pubspec `default-flavor`)
flutter run
# floss on device/emulator: flutter run --flavor floss
# Build for production
flutter build appbundle --release # Android App Bundle (Play Store)
flutter build ios --release # iOSGradle flavors gms (default, Play Store deps) and floss (no Play Services, IzzyOnDroid). Output names match GitHub Releases.
| Variant | Files |
|---|---|
| gms | rain-release-gms.apk, rain-arm64-v8a-release-gms.apk, rain-armeabi-v7a-release-gms.apk, rain-x86_64-release-gms.apk |
| floss | rain-release-floss.apk, rain-arm64-v8a-release-floss.apk, rain-armeabi-v7a-release-floss.apk, rain-x86_64-release-floss.apk |
All APKs land in build/app/outputs/flutter-apk/ after ./scripts/rename_apk_outputs.sh.
chmod +x scripts/*.sh
./scripts/build_apk.sh gms --target-platform android-arm64
./scripts/build_apk.sh floss --target-platform android-arm64Per variant: first split APKs (--split-per-abi), then universal (no extra flags). Four builds total:
./scripts/build_release_apks.shRuns four builds and then ./scripts/restore_pub_default.sh (FOSS overrides must not stay in pubspec.lock for normal dev).
Same steps manually:
./scripts/build_apk.sh gms --split-per-abi
./scripts/build_apk.sh gms
./scripts/build_apk.sh floss --split-per-abi
./scripts/build_apk.sh floss
./scripts/restore_pub_default.shpubspec_overrides.yaml must exist before flutter pub get. After pub get, patch the jni package so libdartjni.so is reproducible (same step as IzzyOnDroid RB):
cp tool/pubspec_overrides.floss.yaml pubspec_overrides.yaml
flutter pub get
./scripts/patch_jni_reproducible_build.sh
dart run slang && dart run build_runner build --delete-conflicting-outputs
flutter build apk --release --flavor floss --target-platform android-arm64
./scripts/rename_apk_outputs.sh flossEquivalent one-liner for the jni patch (idempotent; set PUB_CACHE in CI):
sed -i -E 's|target_link_options\(jni PRIVATE "-Wl,[^"]*max-page-size=16384"\)|target_link_options(jni PRIVATE "-Wl,--build-id=none,-z,max-page-size=16384")|' \
"${PUB_CACHE:-$HOME/.pub-cache}"/hosted/*/jni-*/src/CMakeLists.txtpubspec_overrides.yaml is gitignored; pubspec.lock in the repo targets gms.
The project has 338 unit and widget tests (93 *_test.dart files) with an Isar test bootstrap and fake platform services (geocoding, home widget, path provider).
flutter test
flutter analyzeIf widget tests hang, run flutter test --concurrency=1.
Optional coverage report (output in coverage/, gitignored):
flutter test --coverageWell covered: data/domain (repos, mappers, validators), core services/utils (notifications, connectivity, location parsing, HTTP date parsing), bootstrap (AppInitializer), router redirect/cache sync, settings provider updates, cities notifier (CRUD, loadError, delete edge cases), confirmation/selection dialogs, weather widgets and notifiers, location wall clock (TimeIndexHelper, clock skew persistence), air quality (AqiHelper, AirQualityMapper, graceful AQ API fallback).
Notification regression tests: stable notification IDs (notificationIdFor), one slot per hour when duplicate daily rows exist, and MainWeatherNotifier._init not calling cancelAll() while notifications stay enabled.
Widget/screen gaps (intentionally skipped): cold-start main.dart, WorkManager, OSM tile network/cache, onboarding โ home E2E, geolocation submit โ full navigation E2E.
If alerts stopped after an update that fixed notification scheduling, toggle notifications off and on in Settings (Android 13+ may need to grant notification permission once).
Widget tests that hit city search or forecast APIs should use createFakeWeatherRemoteDatasource() from test/helpers/fixtures.dart so geocoding and forecast share one stubbed Dio client.
The project uses code generation for:
- Isar Community โ local database schemas
- Freezed โ immutable API models
- JSON Serializable โ JSON serialization
- Slang โ translations from
assets/i18n/*.i18n.json
After changing models or locale files:
dart run slang
dart run build_runner build --delete-conflicting-outputs- Flutter + Riverpod 3 โข Go Router โข Isar Community
- home_widget + Workmanager (Android widgets) โข flutter_local_notifications
- Open-Meteo Weather API โข Open-Meteo Air Quality API โข flutter_map + OSM tiles
- timezone + flutter_timezone for IANA lookups and per-location wall clocks
Rain uses free, open weather APIs with no API key required:
- Weather Data: Open-Meteo Weather API - Free, open-source weather API
- Air Quality: Open-Meteo Air Quality API - Hourly AQI and pollutant concentrations (CC BY 4.0)
- Geocoding: Open-Meteo Geocoding API - City search and coordinates
- Map Tiles: OpenStreetMap - Collaborative mapping project
We welcome contributions! Please see CONTRIBUTING.md for setup, testing, and pull request guidelines. Use the bug report or feature request templates when opening issues.
If Rain has become an indispensable part of your daily routine, consider supporting development:
This project is licensed under the MIT License.
Thanks to all our amazing contributors!
Made with โค๏ธ using Flutter







