Wear OS Room Course Project

Runique

Advanced running tracker syncing mobile and smartwatch.

Runique Mockup

The Overview

Runique connects a phone companion app to a Wear OS smartwatch for live run tracking. Tracking a run end-to-end means continuous stream sync between the watch and the host phone, real-time geospatial data, map rendering, and the Android Health Services APIs.

The Challenge

Fitness apps need precision. Doze mode kills background processes, network latency drops mid-run, and async streaming between a phone and a Wear OS watch routinely causes sync issues.

The goal was to keep a live GPS trace on Google Maps while capturing health biometrics from the watch, without draining the battery or stalling when the user hits a cellular dead-zone.

Architecture & Technical Decisions

Runique is split into App, Auth, Run, Analytics, and Wear modules under a Clean Architecture layout.

Custom Gradle convention plugins encapsulate features and keep build times down. The local Room database is the source of truth: biometrics from the Wear OS Health Services API land in local buffers first, then Ktor batches them to the backend when the network is up. GPS emissions are high-frequency, so the pipeline leans heavily on Kotlin Flow operators, with Turbine in the test modules to keep async state assertions stable in CI.

Shared code vs platform scope

Rather than duplicating logic, the core domain and data layers serve both phone and Wear targets. Each presentation module then injects its own design system through Koin: Material 3 for the phone, a smaller Wear OS system for the watch.

Impact & Results

  • Sub-second sync between watch and phone for live health metrics.
  • Continuous GPS recording through cellular drops and Doze-mode cycles.
  • Faster builds via dynamic feature modularization and custom Gradle convention plugins.

The Tech Stack

Device Mobile / Wear OS
Persistence Room DB
Architecture Clean Architecture
Map Google Maps