FitBuddy:AI 驱动的 Android 健康追踪应用,支持区域化饮食与拍照记餐
anantdark/FitBuddy
FitBuddy 是一款 AI 驱动的 Android 健康追踪应用,支持拍照或文字记录饮食与运动,由 LLM 估算热量和宏量营养素。它提供区域包定制 AI 提示词与食材、可编辑的餐食复核与运动记录、30 天滚动分析图表,以及 AES-256-GCM 加密备份。
AI-powered health tracker for Android with region-aware diets and daily routines. Log meals and workouts with a photo or loose text; an LLM estimates calories and macros. Includes dashboards, progress charts, editable meal review, and reusable food presets.
Features
- Region packs — personalise AI prompts, staples, portion language, and log examples to your region
- Smart logging — photo or text input; AI parses food and exercise
- Meal review — edit dish name, tweak ingredient weights with live macro recalc
- Editable workouts — structured sessions with AI-suggested names; upgrade simple logs
- Presets — bookmark meals for one-tap logging
- Dashboard — daily calorie ring, food/exercise logs, macro breakdown
- Science-based body goals — track weight, body fat, BMR, and muscle mass; deterministic adult calorie/macronutrient estimates include weight milestones, quality-gated trend personalization, bounded AI-assisted choices, and activity guidance; methodology and evidence
- Analytics — custom Canvas charts; rolling 30-day “monthly” window
- Encrypted backups — AES-256-GCM local export + cloud; gzip; append-only chunk chains
- Loading animations — per-slot Analyzing / Insights choices in Settings
- Offline fallback — works without AI config via built-in simulator
- Crash reports — optional anonymous Sentry reports (opt out in Settings; Support ID for 1:1 help)
- Material You — dynamic color theming on Android 12+
Download
Pre-built APKs and AABs are also attached to GitHub Releases. Every push to main (including merged PRs) publishes a new build tagged v{versionName}-build{N}. Release APKs are arm64-v8a only. Update checks open the APK download in the system browser (no in-app installer).
FitBuddy is on F-Droid and OpenAPK — same codebase and commit as GitHub Releases, built with the fdroid product flavor instead of github. F-Droid owns updates for that build; it's signed with a different key from the GitHub Releases APK, so the two aren't interchangeable updates for the same install.
AI providers
Configure at runtime in Settings (stored locally via DataStore):
| Provider | Notes |
|---|---|
| OpenRouter | Free vision models via model dropdown; optional account sign-in |
| Gemini | Google AI Studio key; OpenAI-compatible endpoint |
| OpenAI | Direct API key; curated gpt-4o catalog |
| Ollama / compatible | Local or cloud; any OpenAI-compatible host (LM Studio, vLLM, LocalAI); optional API key |
First-run defaults can be seeded from local.properties (see below). Without a key, the app uses the offline simulator.
Crash reporting
Anonymous crashes go to Sentry using a DSN committed obfuscated in app/build.gradle.kts. No meals, photos, or API keys are sent. Users can opt out under Settings → Crash reports and copy a Support ID when messaging you — search that id in Sentry to find their events.
With reporting on, the app may send one anonymous daily heartbeat the first time it opens each UTC day:
- Crons — check-in on monitor
fitbuddy-daily-heartbeat - Explore → Metrics — counter
fitbuddy.daily_active(sum; group bymodel/app_version/manufacturer) - Explore → Logs — message “FitBuddy daily heartbeat” with the same device/app/AI attributes (filter
heartbeat:true)
Does not create Issues. No meals, photos, or API keys.
Build from source
Requirements
- JDK 21
- Android SDK with API 36.1 (compile) / API 29+ (min)
- macOS/Linux/WSL (Gradle wrapper included)
Setup
git clone https://github.com/anantdark/FitBuddy.git cd FitBuddy # SDK path + optional AI defaults (never commit this file) cp local.properties.example local.properties # Edit local.properties — set sdk.dir and optional API keys
Compile & test
export JAVA_HOME=/opt/homebrew/opt/openjdk@21/libexec/openjdk.jdk/Contents/Home # macOS Homebrew ./gradlew :app:compileDebugKotlin ./gradlew :app:testDebugUnitTest
Install release build (dev)
Release builds use R8 minify + resource shrink. Local keystore.properties should point at a
local/dev keystore (see DISTRIBUTION.md) — not the CI/Play release key.
Without keystore.properties, release falls back to the Android debug key:
./gradlew :app:assembleRelease
# --user 0 = personal profile only (avoids installing into a work profile)
adb install -r --user 0 app/build/outputs/apk/release/FitBuddy-3.0.0-dev.apkCI release signing uses GitHub RELEASE_* secrets only. For Play Store setup, see DISTRIBUTION.md.
Project structure
app/src/main/java/com/anant/fitbuddy/
├── FitBuddyApp.kt # Application / manual DI
├── data/
│ ├── database/ # Room entities & DAOs
│ ├── model/ # API & domain models
│ ├── remote/ # Retrofit, AI prompts, DTOs
│ ├── repository/ # Business logic
│ └── settings/ # DataStore preferences
├── ui/
│ ├── screens/ # Compose screens
│ ├── viewmodel/ # MainViewModel
│ └── components/ # Charts, snackbar, etc.
└── util/ # DateUtils, ImageUtils
Architecture: MVVM — UI → ViewModel → Repository → Room + Remote AI.
CI / CD
| Workflow | Trigger | What it does |
|---|---|---|
| CI | Push & PR to main |
Compile debug/release, run unit tests |
| Release | Push to main |
Build signed APK + AAB, publish GitHub Release (latest) |
| F-Droid Release | Manual dispatch | Bump version, tag, build fdroid flavor, publish prerelease |
Releasing
The GitHub release triggers automatically on every push to main (including merged PRs). Version is 3.2.<run_number % 100>.
The F-Droid release is triggered manually from Actions → F-Droid Release → Run workflow. You provide the major.minor version (e.g. 3.2), and the patch is computed as run_number % 100. The workflow auto-bumps build.gradle.kts, commits, tags, builds, and publishes. See FDROID.md for the full process.
See FDROID.md for the full F-Droid process.
Required: signed release builds in CI
Release workflow fails without these repository secrets (so every APK shares one signing key and browser-based updates can install over the previous release):
| Secret | Value |
|---|---|
RELEASE_KEYSTORE_BASE64 |
Base64-encoded .jks file (base64 -i fitbuddy-release.jks | pbcopy) |
RELEASE_STORE_PASSWORD |
Keystore password |
RELEASE_KEY_ALIAS |
Key alias (default: fitbuddy) |
RELEASE_KEY_PASSWORD |
Key password |
See DISTRIBUTION.md to create the keystore. After the first release signed with a new keystore, uninstall any older install once, then install that APK — later updates over that install will succeed.
Contributing
- Fork and create a feature branch
- Run
./gradlew :app:compileDebugKotlin :app:testDebugUnitTest - Open a PR against
main— CI must pass
Bug reports and feature requests: Issues.
Support development
If FitBuddy helps you, support its continued development through GitHub Sponsors. Indian users can also use the heart button in the app for UPI or card contributions.
License
GPL-3.0 — see LICENSE.
Related docs
- FDROID.md — F-Droid release process, tagging, and submission notes
- DISTRIBUTION.md — Play Store publishing & keystore setup
- Health target methodology — formulas, limitations, and evidence
- AGENTS.md — contributor context for architecture and conventions
- Docs site — onboarding, usage guide, encryption, FAQ, privacy
来源:GitHub · github.com