A disc golf putting practice tracker for Android with an optional Garmin watch companion. Log sessions by distance, track make percentage over time, and sync batches directly from your wrist.
- Sessions broken into configurable batches (e.g. 4 throws at 30 ft) — delete or correct batches mid-session or after saving
- Per-session chart + full history view
- Stats page with make % over time broken out by distance
- Home screen focused on your 30 ft lifetime numbers — the most useful quick glance
- Save session context: basket, wind level, notes, and an optional photo; all editable after the fact
- Garmin Vivoactive 6 companion app — log a batch from your wrist and it syncs to the phone over Bluetooth via Garmin Connect IQ
putt-tracker/
├── lib/
│ ├── db/ # SQLite schema and queries (sqflite)
│ ├── models/ # Session, Batch data classes
│ ├── providers/ # SessionProvider, BasketProvider (state via provider)
│ ├── screens/ # One file per screen + bottom sheets
│ │ ├── home_screen.dart
│ │ ├── session_screen.dart # Active session entry
│ │ ├── session_detail_screen.dart
│ │ ├── stats_screen.dart
│ │ ├── history_screen.dart
│ │ ├── baskets_screen.dart
│ │ ├── save_session_sheet.dart
│ │ └── edit_session_sheet.dart
│ └── services/
│ └── garmin_service.dart # Garmin Connect IQ bridge
├── android/ # Standard Flutter Android host
└── putt-tracker-garmin/ # Garmin Connect IQ watch app (Monkey C)
├── source/PuttTrackerApp.mc
├── resources/
└── monkey.jungle
- Flutter / Dart —
providerfor state,sqflitefor local persistence,fl_chartfor charts - Garmin Connect IQ (Monkey C) — watch app targeting the Vivoactive 6; communicates with the phone via the
watch_connectivity_garminFlutter plugin
# Phone app (from repo root)
flutter build apk --release
# → build/app/outputs/flutter-apk/app-release.apk
# Watch app (from putt-tracker-garmin/)
monkeyc --jungle monkey.jungle --output PuttTracker.prg \
--device vivoactive6 --private-key developer_key
# Requires the Garmin Connect IQ SDK; set sdk path in your environment or use the build scripts# Sideload to a connected Android device
adb -s <device-serial> install -r build/app/outputs/flutter-apk/app-release.apk
# Watch app — sideload via Garmin Express or Connect IQ Device SimulatorThe phone app and watch app live in the same repo. Changes to the Garmin side go in putt-tracker-garmin/; phone-side changes go in lib/.
A few things worth knowing before diving in:
- Session state lives entirely in
SessionProvider— the screens are mostly stateless consumers. If you're adding a new piece of session data, start there and in the DB schema. - The Garmin bridge is one-way at the moment — the watch can push a completed batch to the phone, but the phone doesn't push anything back beyond session-start and batch-size signals.
- No tests yet — the
test/directory is the default Flutter stub. Unit tests forSessionProviderand DB helpers would be the highest-value first addition.