Running Beat is a specialized training tool designed to help runners optimize their running cadence for maximum efficiency and minimal fatigue. Built with Flutter for cross-platform compatibility, the app leverages scientific research showing that the optimal running cadence for efficiency and joint health is between 170-180 BPM.
Whether you're a beginner learning proper running form or a veteran looking to optimize your stride, Running Beat provides precise audio cues to help you maintain the ideal cadence, reducing joint impact and improving running economy.
- Single-beat metronome pulse: The cadence engine now supports a uniform click with no 4/4 accent pattern, making it easier to follow any training rhythm at a glance.
Scientific studies have demonstrated that maintaining a cadence of 170-180 steps per minute:
- Optimizes the natural rebound of leg joints and tendons
- Minimizes vertical oscillation (wasted energy)
- Reduces impact forces on joints, lowering injury risk
- Improves running economy and reduces perceived effort
Running Beat makes cadence training accessible and effective through precise, high-quality audio cues that work seamlessly in the background while you run.
- Precise BPM Control: Range from 1 to 320 BPM with microsecond-level timing accuracy
- Optimal Cadence Range: Quick access to the scientifically-proven 170-180 BPM sweet spot
- Intuitive UI: Large BPM display with increment/decrement buttons, slider control, and elevated add-block button that stays clear of training controls
- High-Quality Audio: Crystal-clear cadence cues (48kHz, stereo WAV) audible even during outdoor runs
- Glitch-Free Playback: Native
metro_drone_pluginengine delivers sample-accurate ticks on both Android and iOS, even at fast tempos - Background Playback: Continues playing when app is minimized or screen is locked
- Persistent Foreground Notification: Always visible notification with real-time cadence display
- Notification Controls: Interactive Play/Pause/Stop buttons directly in the notification
- Real-Time Sync: Notification text and buttons update instantly based on training state
- BPM Updates: Live cadence display even when adjusted from the app
- Background Audio Session: Properly configured AVAudioSession for uninterrupted training
- Lock Screen Controls: Media controls appear automatically on lock screen (on physical devices)
- Seamless Integration: Native iOS audio behavior and system integration
- Robust State Management: Timestamp-based command system prevents race conditions
- Cross-Isolate Communication: Reliable communication between main app and background service
- Automatic Cleanup: Prevents ghost commands on app restart
- Battery Optimized: Efficient implementation for extended training sessions
Running Beat is evolving into a comprehensive running training platform with features designed for runners at all levels:
- Variable Cadence Intervals: Create custom training blocks with different cadence targets
- Walking & Rest Periods: Incorporate recovery intervals into your training
- Exercise Blocks: Add strength and mobility exercises for comprehensive beginner programs
- Timeline-Based UI: Intuitive drag-and-drop interface to build and edit workout sequences
- Apple Watch App: Native watchOS companion for hands-free training
- Wear OS Support: Android smartwatch compatibility for seamless cadence training
- Haptic Feedback: Vibration cues as an alternative to audio
- Beginner Programs: Couch-to-5K style progression programs with guided cadence training
- Custom Workouts: Save and share training templates
- Progress Tracking: Statistics and historical data to monitor improvement
- Adaptive Training: Gradual cadence adjustments to build proper form over time
- Visual Metronome: Flashing indicators for visual cadence cues
- Multiple Sound Options: Different audio cues to prevent monotony
- Pace Integration: Combine cadence with pace targets for complete training control
| Main Screen | Notification Controls | Training in Progress |
|---|---|---|
| Coming soon | Coming soon | Coming soon |
- Framework: Flutter 3.7.2
- Language: Dart 3.0+
- UI: Material Design with custom styling optimized for running use cases
- Audio Playback: metro_drone_plugin (git) provides native metronome generation with deterministic timing
- Audio Session Management: audio_session ^0.1.21 for iOS background audio
- High-precision timing: Plugin-powered scheduling keeps cadence aligned with BPM selections
- Android Foreground Service: flutter_foreground_task ^8.14.0
- Notifications: flutter_local_notifications ^18.0.1
- State Persistence: Efficient cross-isolate communication
- Android: Custom TaskHandler for notification button events and persistent service
- iOS: AVAudioSession configuration for background audio and lock screen integration
The app uses a custom state management solution optimized for background execution:
- Timestamp-based command tracking to prevent duplicate execution
- Shared data storage for cross-isolate communication
- Polling mechanism with lock to handle notification button events reliably
metro_drone_pluginrenders ticks directly on the native audio thread for rock-solid pulse- The app configures BPM/time signature per block before launching playback
- Background-safe audio session configuration keeps output stable during screen locks
Main App (UI Thread)
↕ Polling (200ms)
Shared Data Storage (FlutterForegroundTask)
↕ Events
Background TaskHandler (Isolate)
↕ Updates
Android Notification System / iOS Media Controls
- Flutter SDK 3.7.2 or higher
- Dart 3.0 or higher
- Android Studio / Xcode for platform-specific builds
- Android SDK (API 31+) / iOS 12.0+
- Clone the repository:
git clone git@github.com:Spettacolo83/RunningBeat.git
cd RunningBeat- Install dependencies:
flutter pub get- Run on your device:
# Android
flutter run -d <android-device-id>
# iOS
flutter run -d <ios-device-id>lib/
├── l10n/
│ └── app_localizations.dart # Localization helper
└── main.dart # Main app entry point, UI, and business logic
assets/
├── icon.png # App icon
└── sounds/
├── metronome_click.wav # Legacy click sound assets (optional)
└── metronome_click_hq.wav # High-quality cadence cue (48kHz stereo)
android/
├── app/
│ └── src/main/
│ ├── AndroidManifest.xml # Permissions and service declarations
│ └── kotlin/... # Android native code
ios/
├── Runner/
│ ├── Info.plist # iOS permissions and capabilities
│ └── AppDelegate.swift # Background audio configuration
- Android: The project is configured to use Android NDK
27.0.12077973. Ensure this version is installed in Android Studio (SDK Manager ▸ SDK Tools ▸ NDK) for smooth builds.
The cadence engine delegates scheduling to metro_drone_plugin, which renders ticks on the native audio thread using the configured BPM and time signature for sample-accurate playback.
Commands from notification buttons use timestamps to prevent duplicates:
final timestamp = DateTime.now().millisecondsSinceEpoch;
FlutterForegroundTask.saveData(key: 'commandTimestamp', value: timestamp);On app startup, old commands are cleared to prevent ghost executions:
await FlutterForegroundTask.saveData(key: 'command', value: '');
await FlutterForegroundTask.saveData(key: 'commandTimestamp', value: 0);FOREGROUND_SERVICE: Run cadence service during trainingPOST_NOTIFICATIONS: Show persistent training notification (Android 13+)WAKE_LOCK: Keep device awake during runs
UIBackgroundModes(audio): Background audio playback during training- Properly configured AVAudioSession category for outdoor use
Problem: Rapid tapping caused state desynchronization between app and notification. Solution: Implemented timestamp-based command system with processing locks to prevent race conditions.
Problem: Old commands persisted between app sessions, causing unexpected behavior. Solution: Added initialization cleanup that clears all saved commands on app startup.
Problem: Original audio file had crackling/distortion that affected outdoor usability. Solution: Generated high-quality 48kHz stereo WAV with proper fade-in/fade-out to eliminate artifacts.
Problem: Audio stopped when app went to background on iOS. Solution: Configured AVAudioSession with correct category and options in AppDelegate for continuous playback.
- Precise cadence control (1-320 BPM)
- Background playback (Android/iOS)
- Notification controls (Android)
- Lock screen integration (iOS)
- High-quality audio cues
- Timeline-based workout builder
- Variable cadence intervals
- Walking and rest period blocks
- Exercise integration for beginners
- Workout templates and saving
- Apple Watch companion app
- Wear OS companion app
- Haptic feedback for cadence cues
- Training statistics and progress tracking
- Historical data visualization
- Pre-built training programs (beginner to advanced)
- Adaptive cadence training
- Pace + cadence integration
- Social features and workout sharing
- Integration with popular running platforms
flutter build apk --release
# or for Play Store
flutter build appbundle --releaseflutter build ios --releaseStart your running journey with proper form from day one. Running Beat helps you establish the optimal cadence pattern, reducing injury risk and building good habits.
Fine-tune your stride for maximum efficiency. Use Running Beat to maintain your target cadence during tempo runs, intervals, or long runs.
Rebuild proper running form after injury or time off. The consistent cadence cues help retrain muscle memory and movement patterns.
- Flutter debug crash on iOS 18.4 devices: A recent iOS update breaks Flutter's debug runtime on physical hardware. Until the upstream fix lands, develop on a simulator, use a device on iOS ≤ 18.3, or run in
--profile/--releasemode. Track progress in flutter/flutter#163984.
This is a personal portfolio project, but feedback and suggestions are welcome! Feel free to open issues for bugs or feature requests.
This project is created as a portfolio piece to demonstrate Flutter and mobile development skills.
Stefano Russello
- GitHub: @Spettacolo83
- Email: [Your email for professional contact]
- Scientific running community for cadence research
- Flutter team for the excellent cross-platform framework
- Audio processing libraries: audioplayers, audio_session
- Background service: flutter_foreground_task
- All runners who provided feedback and inspiration
Run smarter, not harder - with Running Beat