CaffeineHealth

Project Url: ohuc/CaffeineHealth
Introduction: Track your caffeine. Protect your sleep. A privacy-first Material 3 Expressive Android app that shows your active caffeine level in real time and tells you if that late espresso will cost you tonight.
More: Author   ReportBugs   
Tags:

Caffeine Health logo — a coffee cup with a beating heartbeat line

Caffeine Health

Track your caffeine. Protect your sleep.

GitHub release F-Droid License Platform Min SDK GitHub Sponsors

Get it on GitHub Get it on F-Droid

Get it on IzzyOnDroid

Translation status


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.

Set your baseline
Welcome
Profile Ready
Onboarding
Home Dashboard
Dashboard
Caffeine by Source
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. compileSdk targets 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

  1. Pull the latest translation changes from Weblate into a clean working tree on master.
  2. Bump versionName and increase versionCode in app/build.gradle.kts, and add fastlane/metadata/android/en-US/changelogs/<versionCode>.txt, in one commit. All other release source must already be committed.
  3. Tag that exact commit as v<versionName> (for example v2.6.0), push the commit and tag, and wait for Verify release tag to pass.
  4. 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 fossRelease variant, and an App Bundle for playRelease. Clean immediately before building; an incremental build is not reproducible.
  5. Attach the FOSS APK to a draft GitHub release, renamed to app-release.apk. F-Droid and IzzyOnDroid download it by that name.
  6. 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.
  7. 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:

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Commit your changes: git commit -m 'Add amazing feature'
  4. Push to the branch: git push origin feature/amazing-feature
  5. 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.

Translation status


💖 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.

Sponsor ohuc on GitHub
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

Star History Chart

📄 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

Apps
About Me
GitHub: Trinea
Facebook: Dev Tools
AI Daily Digest