Skip to content

Repository files navigation

ExerSight

ExerSight is an Android app that uses the device camera and on-device pose detection to count workout repetitions in real time. Point the camera at yourself while doing push-ups, squats, or jumping jacks and the app tracks your form and counts reps as you go.

Features

  • Real-time pose detection via Google ML Kit, fed from a CameraX analysis pipeline.
  • Repetition counting for push-ups, squats, and jumping jacks, each with its own detection logic (data/exercise).
  • Front/back camera flip while counting.
  • Runtime camera permission handling with a graceful "permission unavailable" fallback.

Tech stack & architecture

Layer Choice
UI Jetpack Compose, Material 3
Navigation Navigation 3 (androidx.navigation3) with type-safe destinations
DI Hilt, with @AssistedInject/@AssistedFactory for passing navigation arguments into ViewModels
Camera CameraX (camera-core, camera-view, camera-video, camera-mlkit-vision)
Pose detection Google ML Kit Pose Detection
Async Kotlin Coroutines & Flow
Build Gradle version catalog (gradle/libs.versions.toml), KSP (no kapt)

Navigation

The app uses Navigation 3, Google's Compose-first navigation library that replaces NavController/NavHost with a back stack you own directly:

  • Destinations are plain NavKey implementations (see ui/navigation/NavKey.kt) — Home and ExerciseCounter, the latter carrying its arguments (exerciseType, exerciseTitle) as typed properties instead of a string route.
  • The back stack is a NavBackStack created with rememberNavBackStack in ExerSightApp.kt and rendered with NavDisplay in ui/navigation/AppNavigation.kt, using the entryProvider { entry<T> { } } DSL.
  • ExerciseCounterViewModel receives its destination directly through Hilt's assisted injection (@AssistedInject + @AssistedFactory), so there's no SavedStateHandle string-key lookup — the navigation argument is just a constructor parameter.

Project structure

app/src/main/java/yao/ic/mediapipe/
├── data/exercise/        # Per-exercise rep-counting logic (PushUp, Squat, JumpingJack)
├── di/                   # Hilt modules (e.g. PoseDetector provider)
├── domain/               # Pose/exercise state and the CameraX ImageAnalysis.Analyzer
├── ui/
│   ├── navigation/       # NavKey destinations + Navigation 3 setup
│   ├── screen/home/      # Exercise picker screen
│   ├── screen/exercise_counter/ # Camera screen + rep counter overlay + ViewModel
│   ├── common/components/ # Shared composables (camera preview, pose overlay, dialogs)
│   └── theme/            # Compose theme
└── utils/                # Geometry/scaling helpers for overlay drawing

Requirements

  • Android Studio with support for AGP 9.x / Gradle 9.x.
  • JDK 17.
  • A device or emulator running Android 8.0 (API 26) or later, with a camera.

Building

./gradlew :app:assembleDebug

Dependency versions are centralized in gradle/libs.versions.toml — bump a version there rather than in app/build.gradle.kts.

Permissions

The app requests CAMERA at runtime (via Accompanist Permissions) before showing the exercise counter screen.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages