A simple, modern Android app to save the birthdays of the people you care about and never forget them again. It shows an at-a-glance countdown to each upcoming birthday and sends you a reminder notification on the day.
- Save birthdays — name, date, and optional notes.
- Optional birth year — record it to see the age someone is turning, or leave it out.
- Upcoming-first list — birthdays are automatically sorted by how soon they are, with a
friendly countdown (
Today! 🎉,Tomorrow,In 12 days). - Edit & delete — tap any birthday to update or remove it.
- Daily reminder notifications — a background job checks every morning (~9 AM) and notifies you about any birthdays happening that day.
- Offline & private — all data is stored locally on the device in a Room (SQLite) database. Nothing leaves your phone.
- Leap-year safe — Feb 29 birthdays are handled gracefully in non-leap years.
| Concern | Choice |
|---|---|
| Language | Kotlin |
| UI | Jetpack Compose + Material 3 (dynamic color) |
| Architecture | MVVM (ViewModel + Repository) |
| Persistence | Room (SQLite) |
| Navigation | Navigation-Compose |
| Background work | WorkManager |
| Min SDK / Target | 24 / 34 |
app/src/main/java/com/example/birthdaysaver/
├── BirthdayApplication.kt # App entry: DB, notification channel, schedules worker
├── MainActivity.kt # Hosts Compose UI, requests notification permission
├── data/ # Room entity, DAO, database, repository
├── ui/
│ ├── BirthdayViewModel.kt # State + save/delete, sorts by days-until
│ ├── navigation/AppNavigation.kt
│ ├── screens/ # BirthdayListScreen, AddEditBirthdayScreen
│ └── theme/ # Compose Material 3 theme
├── util/DateUtils.kt # "days until", "turning age", formatting
└── notification/ # WorkManager worker + notification channel
- Open the project in Android Studio (Hedgehog or newer).
- Let Gradle sync (it will download the Android Gradle Plugin 8.5 and dependencies).
- Run on an emulator or device (API 24+).
Or from the command line, once the Gradle wrapper is present:
./gradlew assembleDebug # builds app/build/outputs/apk/debug/app-debug.apk
./gradlew installDebug # builds and installs on a connected deviceNote: If
gradlew/gradle-wrapper.jarare missing, rungradle wrapperonce (with a local Gradle install) or open the project in Android Studio, which generates them.
- Each
Birthdaystoresmonth/dayseparately from an optionalyear, so "next occurrence" is computed regardless of birth year. DateUtils.nextOccurrence()finds the next date the birthday lands on (this year or next), which drives both sorting and the countdown label.BirthdayWorkerruns daily via WorkManager, loads all birthdays, and notifies for any withdaysUntil == 0.