Реализация трекинга тренировок в мобильном приложении

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.
Разработка и поддержка любых видов мобильных приложений:
Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Предлагаемые услуги
Показано 1 из 1 услугВсе 1735 услуг
Реализация трекинга тренировок в мобильном приложении
Средняя
~3-5 рабочих дней
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1054
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    445

Реализация трекинга тренировок в мобильном приложении

Трекинг тренировки — это управляемая сессия с несколькими параллельными потоками данных: GPS, акселерометр/гироскоп, ЧСС (с носимого устройства), барометр (высота). Всё это нужно записывать синхронно, отображать в реальном времени и сохранять без потерь при падении приложения или разряде батареи.

Архитектура сессии тренировки

Центральный элемент — WorkoutSession (или как вы её называете), конечный автомат с состояниями:

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

Переходы триггерятся пользователем (кнопки Start/Pause/Finish) и системой (потеря GPS, разряд батареи). Всё состояние хранится в WorkoutRepository, персистируется через Room (Android) или CoreData/SQLite (iOS) после каждого обновления — чтобы при краше восстановить сессию.

@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
)

Каждые 5 секунд вставляем новую запись в БД. При завершении тренировки — агрегируем всё в WorkoutSummary. Промежуточные точки не удаляем — они нужны для построения трека.

GPS-трекинг и точность

Фильтрация GPS-шума

Сырые GPS-данные содержат шум ±5–15 м. На маршруте это визуально выглядит как «зигзаги» вместо прямого отрезка. Фильтруем через Kalman-фильтр — самый адекватный метод для GPS:

Для мобильной разработки не нужно реализовывать Kalman с нуля. На Android — FusedLocationProviderClient уже применяет внутреннюю фильтрацию. На iOS — CLLocationManager с kCLLocationAccuracyBestForNavigation использует сенсорный fusion. Дополнительно: отбрасываем точки с horizontalAccuracy > 20 м.

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)
}

Расчёт дистанции и темпа

Дистанция — сумма расстояний между последовательными GPS-точками (CLLocation.distance(from:) на iOS, Location.distanceTo() на Android). Темп (мин/км) = 1000 / скорость (м/с) / 60. Скорость берём из CLLocation.speed / Location.speed — они вычисляются по доплеровскому сдвигу, точнее чем разность координат.

При speed < 0 (нет достоверных данных) — используем скорость из координат.

Фоновое выполнение

iOS

Добавляем в Info.plist:

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

И запрашиваем Always разрешение. Без этого GPS останавливается через ~15 секунд после перехода приложения в фон. allowsBackgroundLocationUpdates = true на CLLocationManager — обязательно.

Android

Foreground Service с уведомлением (иначе Android убьёт процесс при нехватке памяти):

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 — система перезапустит сервис если убьёт процесс, с null интентом. Обрабатываем null и восстанавливаем состояние из Room.

Интеграция с носимыми устройствами

ЧСС от Apple Watch — через HKWorkoutBuilder на iOS (Watch автоматически добавляет семплы). На Android — Wear OS через HealthServicesClient или Bluetooth GATT с профилем Heart Rate (UUID 0x180D).

Bluetooth GATT для внешних датчиков (нагрудный пояс Polar H10, 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)
    }
}

Сохранение в HealthKit / Health Connect

По завершению тренировки записываем полный HKWorkout (iOS) или ExerciseSessionRecord (Android) со всеми вложенными метриками: дистанция, ЧСС, маршрут. На iOS — HKWorkoutRouteBuilder для GPS-трека. Пользователь должен видеть тренировку в системном приложении «Здоровье» или Health Connect.

Сроки

Базовый трекер бега с GPS, дистанцией и темпом — 3–5 недель. Полный трекер с ЧСС, BLE-датчиками, несколькими типами активностей, экспортом GPX и интеграцией в платформенные хранилища — 2–4 месяца.