Workout tracking implementation in mobile app

NOVASOLUTIONS.TECHNOLOGY is engaged in the development, support and maintenance of iOS, Android, PWA mobile applications. We have extensive experience and expertise in publishing mobile applications in popular markets like Google Play, App Store, Amazon, AppGallery and others.
Development and support of all types of mobile applications:
Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1 servicesAll 1735 services
Workout tracking implementation in mobile app
Medium
~3-5 business days
FAQ
Our competencies:
Development stages
Latest works
  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1050
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    445

Workout Tracking Implementation in Mobile Application

Workout tracking — managed session with multiple parallel data streams: GPS, accelerometer/gyroscope, heart rate (from wearable), barometer (altitude). Must record all synchronously, display realtime and save without loss on app crash or battery drain.

Workout Session Architecture

Central element — WorkoutSession (or your name), state machine with states:

Idle → Preparing → Active → Paused → Active → Finishing → Saved

Transitions triggered by user (Start/Pause/Finish buttons) and system (GPS loss, low battery). All state stored in WorkoutRepository, persisted via Room (Android) or CoreData/SQLite (iOS) after each update — recover on crash.

@Entity
data class WorkoutPoint(
    @PrimaryKey(autoGenerate = true) val id: Long = 0,
    val sessionId: String,
    val timestamp: Long,
    val latitude: Double?,
    val longitude: Double?,
    val altitude: Double?,
    val heartRate: Int?,
    val speed: Double?,
    val distance: Double
)

Every 5 seconds insert new record in DB. On finish — aggregate all into WorkoutSummary. Don't delete intermediate points — needed for track rendering.

GPS Tracking and Accuracy

GPS Noise Filtering

Raw GPS data contains ±5–15 m noise. Visually on route looks like "zigzags" instead straight segment. Filter via Kalman filter — most adequate method for GPS.

For mobile development no need implement Kalman from scratch. On Android — FusedLocationProviderClient already applies internal filtering. On iOS — CLLocationManager with kCLLocationAccuracyBestForNavigation uses sensor fusion. Additionally: discard points with horizontalAccuracy > 20 m.

func locationManager(_ manager: CLLocationManager,
                     didUpdateLocations locations: [CLLocation]) {
    guard let location = locations.last,
          location.horizontalAccuracy <= 20,
          location.horizontalAccuracy >= 0 else { return }

    if let previous = lastLocation {
        let segment = location.distance(from: previous)
        totalDistance += segment
    }
    lastLocation = location
    trackPoints.append(location)
}

Distance and Pace Calculation

Distance — sum of distances between sequential GPS points (CLLocation.distance(from:) on iOS, Location.distanceTo() on Android). Pace (min/km) = 1000 / speed (m/s) / 60. Speed from CLLocation.speed / Location.speed — calculated via Doppler shift, more accurate than coordinate difference.

At speed < 0 (no reliable data) — use speed from coordinates.

Background Execution

iOS

Add to Info.plist:

<key>UIBackgroundModes</key>
<array>
    <string>location</string>
</array>

Request Always permission. Without this GPS stops ~15 seconds after app backgrounding. allowsBackgroundLocationUpdates = true on CLLocationManager — mandatory.

Android

Foreground Service with notification (otherwise Android kills process on memory shortage):

class WorkoutTrackingService : Service() {
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        val notification = buildTrackingNotification()
        startForeground(NOTIFICATION_ID, notification)
        startLocationUpdates()
        return START_STICKY
    }
}

START_STICKY — system restarts service if killed, with null intent. Handle null and restore state from Room.

Wearable Integration

Heart rate from Apple Watch — via HKWorkoutBuilder on iOS (Watch auto-adds samples). On Android — Wear OS via HealthServicesClient or Bluetooth GATT with Heart Rate profile (UUID 0x180D).

Bluetooth GATT for external sensors (Polar H10 chest strap, Wahoo TICKR):

val hrServiceUUID = UUID.fromString("0000180d-0000-1000-8000-00805f9b34fb")
val hrCharacteristicUUID = UUID.fromString("00002a37-0000-1000-8000-00805f9b34fb")

override fun onCharacteristicChanged(gatt: BluetoothGatt,
                                      characteristic: BluetoothGattCharacteristic) {
    if (characteristic.uuid == hrCharacteristicUUID) {
        val flag = characteristic.properties
        val format = if (flag and 0x01 != 0) {
            BluetoothGattCharacteristic.FORMAT_UINT16
        } else {
            BluetoothGattCharacteristic.FORMAT_UINT8
        }
        val heartRate = characteristic.getIntValue(format, 1) ?: 0
        onHeartRateReceived(heartRate)
    }
}

Save to HealthKit / Health Connect

On completion record full HKWorkout (iOS) or ExerciseSessionRecord (Android) with all nested metrics: distance, heart rate, route. On iOS — HKWorkoutRouteBuilder for GPS track. User should see workout in system Health or Health Connect.

Timeframes

Basic run tracker with GPS, distance and pace — 3–5 weeks. Full tracker with heart rate, BLE sensors, multiple activity types, GPX export and platform storage integration — 2–4 months.