CaffeineHealth
Caffeine Health
Track your caffeine. Protect your sleep.
Caffeine Health is a beautifully designed Android app that helps you understand how your caffeine intake affects your body throughout the day, and whether that late-afternoon espresso might cost you sleep tonight.
Log drinks from a curated catalog, watch your active caffeine level in real time on a 24-hour curve, and get a personalized sleep forecast based on your unique metabolism.
![]() Welcome |
![]() Onboarding |
![]() Dashboard |
![]() Source Analytics |
✨ Features
🏠 Dashboard
- Live caffeine curve: a smooth 24-hour chart showing your active caffeine level, updated in real time
- Emoji markers: each logged drink appears on the chart with its emoji for quick visual reference
- Sleep forecast: see how much caffeine will still be active at your bedtime and whether it crosses your safe threshold
- Today's total: at-a-glance milligram count for everything consumed today
- Drink detail sheet: tap any logged drink to see its contribution curve, peak level, current level, and total impact over time
- Quick actions: edit, duplicate, or delete entries directly from the detail sheet
☕ Drink Catalog
- Curated drink database: browse drinks across categories like coffee, tea, energy drinks, soda, and more
- Search & filter: Material 3 search bar with expressive category filter chips
- One-tap logging: log a drink with a single tap and get snackbar confirmation
- Custom serving sizes: adjust caffeine amount and timing before logging
- Recent servings: your latest servings as one-tap shortcuts (choose how many in Settings → Look & feel → Appearance)
🧬 Personalized Onboarding
- Guided profiling flow: set your age range, weight, bedtime, sleep sensitivity, lifestyle factors, and relevant medications
- Pharmacokinetic modeling: the app calculates a personalized caffeine half-life based on real-world factors (smoking, alcohol, CYP1A2 inhibitors and inducers)
- Science-backed sources: every lifestyle adjustment links to its pharmacological source
- Skip-friendly: sensible defaults if you prefer to get started immediately
⚙️ Settings
- Half-life tuning: fine-tune your caffeine metabolism rate
- Bedtime configuration: set your typical sleep time for accurate forecasts
- Sleep threshold: define the milligram level you consider safe before bed
- Appearance: theme and display preferences
- Date & time format: 12-hour / 24-hour clock, date format customization
- Automation: opt-in broadcast intent so Tasker, MacroDroid or an NFC tag can log drinks for you
🤖 Automation (Tasker, NFC tags)
Enable Settings → Connections & data → Automation, then send a broadcast:
| Field | Value |
|---|---|
| Action | com.uc.caffeine.action.LOG_DRINK |
| Package | com.uc.caffeine |
| Target | Broadcast receiver |
Extras (strings or numbers): drink_name (as shown in the app) or drink_id, plus optional unit (shot, can, cup (large)…), quantity (default 1), caffeine_mg (overrides the catalog amount; required for drinks not in the catalog), timestamp (epoch ms or s, default now) and duration_minutes (defaults to your Time to finish setting for that drink).
adb shell am broadcast -a com.uc.caffeine.action.LOG_DRINK -p com.uc.caffeine \
--es drink_name Espresso --es quantity 2
🏗️ Architecture
com.uc.caffeine
├── MainActivity.kt # Root scaffold, bottom nav, Navigation 3
├── MainNavigation.kt # Navigation destinations
├── data/
│ ├── model/ # Room entities (DrinkPreset, ConsumptionEntry, DrinkUnit)
│ ├── dao/ # Room DAOs
│ ├── CaffeineDatabase.kt # Room database with JSON preset seeding
│ ├── SettingsRepository.kt # DataStore-backed user preferences
│ └── UserSettings.kt # Settings data class
├── ui/
│ ├── screens/
│ │ ├── HomeScreen.kt # Dashboard with chart, sleep forecast, log
│ │ ├── AddScreen.kt # Drink catalog with search & filter
│ │ └── settings/ # Settings sub-screens (appearance, profile, etc.)
│ ├── components/ # Reusable UI: chart, scaffold, haptics, shimmer
│ ├── onboarding/ # Multi-step profiling flow
│ ├── theme/ # Material 3 color scheme, Montserrat typography
│ └── viewmodel/ # Shared CaffeineViewModel (MVVM)
└── util/
├── CaffeineCalculator.kt # One-compartment pharmacokinetic model
├── ChartDataGenerator.kt # 24-hour curve + contribution chart data
└── CategoryUtils.kt # Drink category helpers & icons
The app follows a single-activity MVVM pattern:
| Layer | Responsibility |
|---|---|
| View | Jetpack Compose screens + reusable components |
| ViewModel | CaffeineViewModel - shared state, actions, caffeine math orchestration |
| Data | Room database for drinks & entries, DataStore for user settings |
| Util | Pure calculation logic (pharmacokinetics, chart data generation) |
🧪 Tech Stack
| Component | Technology |
|---|---|
| Language | Kotlin |
| UI Framework | Jetpack Compose |
| Design System | Material 3 with Expressive motion |
| Navigation | Navigation 3 |
| Local Database | Room |
| Preferences | DataStore |
| Charts | Vico (Compose + M3 theming) |
| Image Loading | Coil 3 |
| Typography | Montserrat (Google Fonts) |
| Min SDK | 31 (Android 12) |
| Target SDK | 36 |
🔬 Caffeine Science
The app uses a one-compartment oral pharmacokinetic model:
- Absorption and elimination: a Bateman equation with gastric smoothing combines uptake and exponential decay; drinks are split into minute-sized doses over their consumption duration
- Half-life setting: your personal half-life controls the elimination rate
- Half-life personalization: computed from age, weight, smoking, alcohol, liver health, and CYP1A2-inhibiting medications during onboarding
This keeps the curve and sleep forecast grounded in real pharmacology while remaining practical for daily use.
🚀 Getting Started
Prerequisites
- Android Studio Ladybug (2024.3) or newer
- JDK 21 (used by the repository's CI; Java/Kotlin bytecode targets 11)
- Android SDK 36 installed via SDK Manager
Build & Run
# Clone the repository
git clone https://github.com/ohuc/CaffeineHealth.git
cd CaffeineHealth
# Open in Android Studio and sync Gradle, or build from CLI:
./gradlew :app:assembleFossDebug
# Install on a connected device / emulator:
./gradlew :app:installFossDebug
Note: The app requires Android 12 (API 31) or higher.
compileSdktargets API 36 - use an emulator with API 31+ to run it.
There are two editions built from the same source: foss (GitHub, F-Droid, IzzyOnDroid; every feature free, no proprietary SDKs) and play (Google Play). Check both before a release:
./gradlew :app:testFossDebugUnitTest :app:testPlayDebugUnitTest :app:verifyTranslations
Release checklist
- Pull the latest translation changes from Weblate into a clean working tree on
master. - Bump
versionNameand increaseversionCodeinapp/build.gradle.kts, and addfastlane/metadata/android/en-US/changelogs/<versionCode>.txt, in one commit. All other release source must already be committed. - Tag that exact commit as
v<versionName>(for examplev2.6.0), push the commit and tag, and wait for Verify release tag to pass. - With HEAD at the tag and nothing modified, run Build → Clean Project, then Build → Generate Signed App Bundle or APK in Android Studio: an APK for the
fossReleasevariant, and an App Bundle forplayRelease. Clean immediately before building; an incremental build is not reproducible. - Attach the FOSS APK to a draft GitHub release, renamed to
app-release.apk. F-Droid and IzzyOnDroid download it by that name. - Run Verify reproducible build for that tag. It rebuilds the FOSS APK from source and publishes the draft only if it matches. Never replace a published APK or move a published tag; ship a new patch instead.
- Upload the Play App Bundle to Google Play.
The unsigned fossRelease build is what F-Droid and IzzyOnDroid verify against. Both editions keep the application ID com.uc.caffeine; Android only updates an install in place when the new APK is signed with the same certificate.
Project Structure
CaffeineHealth/
├── app/ # Main application module
│ ├── src/main/
│ │ ├── assets/ # Drink preset JSON database
│ │ ├── java/ # Kotlin source code
│ │ └── res/ # Resources (drawables, fonts, values)
│ ├── src/foss/ # Free local-feature implementation, no billing SDK
│ ├── src/play/ # Plus UI, billing adapter and launcher aliases
│ ├── src/playDebug/ # Hidden developer controls for owner testing
│ ├── src/playRelease/ # Release counterpart without developer controls
│ └── build.gradle.kts # App-level dependencies
├── build.gradle.kts # Project-level config
├── settings.gradle.kts # Module includes
└── gradle/ # Gradle wrapper & version catalog
🎨 Design
Caffeine Health is built with Material 3 Expressive principles:
- Dynamic Color: adapts to your device wallpaper on Android 12+ with a curated espresso-toned fallback palette
- Expressive Motion:
MotionScheme.expressive()for fluid, personality-rich transitions - Montserrat typography: clean, modern font family throughout the entire app
- Haptic feedback: tactile responses on key interactions across dashboard, catalog, and settings
- Dark mode: full dark theme support with carefully tuned surface/container colors
- Animated splash screen: the Pulse Cup heartbeat traces itself in on cold start, then dissolves into the app — matching light or dark from the first frame
- Themed icon: dedicated monochrome launcher layer, so Android 13+ Material You tints the icon to your wallpaper
🤝 Contributing
Contributions are welcome! Here's how to get started:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
Guidelines
- Follow existing code style and architecture patterns
- Keep the shared ViewModel pattern - avoid per-screen ViewModels unless there's a strong reason
- Use Material 3 components and the app's existing design tokens
- Compile and run JVM unit tests for both flavors; device/UI validation belongs to the owner
🌍 Translation
This project is available on Hosted Weblate for translation.
You can contribute to this project even if you are not a developer by helping in translating this project into languages you know.
💖 Support Development
Caffeine Health is free, open source and has no ads. If it helps you, you can support its development through GitHub Sponsors, monthly or as a one-time amount. Sponsorship is entirely voluntary and never unlocks app features: the app works the same whether you sponsor or not.
| Tier | Monthly | One-time |
|---|---|---|
| ☕ Espresso shot · $1 | Sponsor badge, name in release notes | Sponsor badge, name in the next release notes |
| ☕ Cappuccino · $5 | + avatar in release notes, prioritise 1 feature request | Name and avatar in the next release notes |
| ☕ Cold brew · $10 | + name and avatar in this README, prioritise 2 feature requests | + name in this README |
| ☕ Whole pot · $15 | + prioritise 4 feature requests | + name and avatar in this README |
You can also choose any custom amount.
Sponsors
Thank you to everyone supporting Caffeine Health! Sponsors at the Cold brew tier and above are listed here.
Starring the repo, reporting bugs and translating help just as much.
⭐ Star History
📄 License
This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.
🙏 Acknowledgments
- Vico - beautiful charting library for Compose
- Coil - fast image loading for Kotlin
- Material 3 - Google's latest design system
- Montserrat - typeface by Julieta Ulanovsky
Made with ☕ and Kotlin




