A local-first Android calorie and macro tracker with a retro tactical terminal interface. It estimates nutritional values from meal photos using a vision model, lets you log or correct entries by hand, and keeps your data stored locally on your device.
- Meal photo estimation: Snap or pick a picture to get an estimate of calories, protein, carbs, and fat. Every result is presented in a review sheet before anything is saved.
- Manual logging & editing: Log meals manually without needing an API key or internet connection, and edit any logged meal's name, calories, macros, or beverage status at any time.
- Daily progress & targets: Track calories against a daily target with remaining calorie calculations and macro progress bars.
- Weekly trends: View seven-day consumption charts, macro distribution breakdown, and weekly summaries.
- Optional geotagging: Disabled by default. Local meal geotagging and including coordinates in AI analysis are separate opt-ins; Android location permission is also required.
- Terminal themes: Switch between Cyber Cyan, Phosphor Green, Amber CRT, and Stark Mono themes.
- Data export & restore: Export your history as JSON backups or CSV files for spreadsheets, and restore from backup anytime.
- Home screen widget: Quick glance at today's calorie totals directly from your launcher.
- Reminders: Optional notifications scheduled via WorkManager if nothing has been logged for a while.
Note: MacroMandate is a personal tracking tool and is not medical software. Nutritional estimates from AI models are approximations and should always be reviewed.
When you take or pick a meal photo:
- The image is downsampled and corrected for EXIF orientation.
- The image is sent to an OpenAI-compatible vision endpoint (by default, Hugging Face router running
google/gemma-4-31B-it, configurable via Settings or build properties). - The model returns estimated calories, protein, carbohydrates, and fat.
- An Analysis Review Sheet pops up with the parsed numbers. You can adjust any values or discard the estimate entirely before saving.
- Local-first storage: Meals and audit records live in an on-device Room database. No third-party accounts, analytics, or sync servers are run for this project.
- Network calls: Network requests are only made when you trigger photo analysis or generate a summary. Analysis decodes, scales, and re-encodes the image as JPEG, stripping source EXIF metadata; the original file is not uploaded byte-for-byte.
- API key storage: Your API token is saved in app-private DataStore preferences protected by standard Android application sandboxing. The app excludes credentials from logs, backups, and exports.
- Geotagging disclosure: Local geotagging stores a fresh-enough coordinate with the meal. Coordinates are rendered into the analysis image only when the separate “Include location in AI analysis image” option is enabled.
- Backup policy: Android cloud backup and device-to-device transfer are disabled and explicitly exclude the database, evidence photos, credentials, and sensitive preferences. User-initiated JSON/CSV exports remain available.
- Deletion: Per-meal deletion reports photo cleanup failures. “Erase everything” succeeds only when Room records, activity logs, and all evidence files are gone; partial file failures are shown and can be retried.
- Language & UI: Kotlin 2.1, Jetpack Compose, Material 3
- Architecture: MVVM with Repository pattern, StateFlow, Coroutines
- Storage: Room Database (with explicit migrations), DataStore Preferences
- Camera & Images: CameraX, Coil
- Networking: Retrofit 2, OkHttp (OpenAI-compatible chat completions)
- Background tasks: WorkManager
- Widget: Jetpack Glance
- Android Studio Ladybug or newer
- JDK 17+
- Android SDK 37 (
minSdk29)
git clone https://github.com/shareef01/MacroMandate.git
cd MacroMandate
# Run unit tests
./gradlew test
# Assemble debug APK
./gradlew assembleDebugTo use image analysis:
- Open the app and navigate to Settings.
- Enter your Hugging Face API token under Analysis API Key.
For local development, you can optionally set defaults in local.properties:
HUGGINGFACE_API_KEY=your_token_here
MANDATE_API_BASE_URL=https://router.huggingface.co/
MANDATE_MODEL_ID=google/gemma-4-31B-it(Note: Release builds disallow compiled-in API keys in local.properties by default to prevent accidental credential leakage.)
Run the test suite:
# Unit tests
./gradlew test
# Static analysis
./gradlew lintDebug
# Instrumented tests (requires connected device/emulator)
./gradlew connectedDebugAndroidTestdocs/AUDIT_REPORT.md: Comprehensive security, privacy, and architecture review.docs/PRIVACY_THREAT_MODEL.md: Threat model, data inventory, and network boundary analysis.docs/PLAY_RELEASE_CHECKLIST.md: Pre-flight checklist for store release.RELEASE_GUIDE.md: Keystore setup, signing configuration, and build commands.
Shareef — @shareef01
All rights reserved.



