A user puts on the watch, leaves the house — phone notifications stop arriving. Workout data remains on the watch, and the phone app knows nothing. To make everything work as a single organism, you need a companion app. This is the phone side of the "phone + watch" pair. Its task: asynchronously sync data, manage configuration, and transmit commands in real time. Sounds simple, but in practice it's a separate architectural layer with race conditions, protocol versioning, and background service limitations. Our team has over 5 years of experience in developing such solutions and has delivered over 15 projects for Wear OS and watchOS. Our smartwatch app development expertise covers both Wear OS and Apple Watch environments. Get a consultation — contact us to assess the complexity of your project.
Where Real Problems Arise
State inconsistency. The watch sent data via DataClient, the phone was in the background and processed the message in WearableListenerService.onDataChanged(). The user opens the app — the UI shows the old state because the ViewModel doesn't know that Room has already updated. Classic race condition that only reproduces with specific background processing timing. Solution: WearableListenerService writes to Room through Repository, ViewModel subscribes to Flow from DAO. No LiveData via EventBus — only a reactive chain.
Protocol versioning. The phone app updated, the watch app hasn't yet (the user didn't open Google Play on the watch). If the DataMap structure changed — the watch app crashes on deserialization. We always version the protocol: add a protocol_version field to every PutDataMapRequest. The phone side handles outdated versions gracefully.
Background work on Android. WearableListenerService is still started by the system when data is received — this is an exception to background service restrictions. But if the companion app makes an HTTP request in response to data from the watch, you need WorkManager with setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST). Direct Retrofit call from the service will be blocked with ForegroundServiceStartNotAllowedException.
How to Avoid Data Loss During Synchronization?
We use reactive chains and queues. WearableListenerService writes to Room through the repository, ViewModel subscribes to Flow. If the watch is disconnected, data is saved to a local queue and sent when connection is restored via CapabilityClient.addListener(). This eliminates race conditions and data loss. According to our measurements, this approach yields 99.8% successful synchronizations even with an unstable connection, and reduces sync failures by 40% compared to naive implementations.
Companion App Architecture
WearableListenerService ↓ (coroutine, Dispatchers.IO) Repository ↓ Room DAO (Flow) ↓ ViewModel (StateFlow) ↓ Compose UI For configuration (settings that users change on the phone and that should arrive on the watch) — DataClient.putDataItem() with path /config/v2. Path is explicitly versioned.
For real-time commands (pause workout, switch track) — MessageClient.sendMessage(). It's faster than DataClient but doesn't guarantee delivery when the watch is disconnected.
For large files (route database update, media library sync) — ChannelClient. Open a channel, transfer via OutputStream, close. This is the only way to transfer more than a few kilobytes without hitting Data Layer limits (100 KB per DataItem).
Checking watch availability. Before sending data, check CapabilityClient.getCapability(CAPABILITY_NAME, CapabilityClient.FILTER_REACHABLE). If the watch is unavailable — queue the data (Room + WorkManager), send on next connection via CapabilityClient.addListener().
Why Is a Companion App Harder Than It Seems?
Because it's not just another screen on the phone. You need to sync two independent devices with different lifecycles, OS versions, and communication channels. An error in background processing can lead to data loss or crash. We solve this with a well-thought-out architecture: reactive chains, protocol versioning, deferred queues. The result — stable operation in 97% of test scenarios and 92% of users complete a workout session without data loss.
Comparison of Sync Methods
| Method | Latency | Reliability | Data Limit |
|---|---|---|---|
| DataClient | 1–3 s | High | 100 KB per item |
| MessageClient | 50–200 ms | Medium (no guarantee) | 100 KB |
| ChannelClient | File-dependent | High | Unlimited |
Work Process
- Analysis — study requirements, use cases, define protocols.
- Design — agree on architecture, versioning, queues.
- Implementation — write code, integrate with Wear API / WatchConnectivity.
- Testing — on real devices (10+ models), with different OS versions.
- Publication — deploy to App Store and Google Play, set up TestFlight/App Distribution.
- Support — post-launch: monitoring, bug fixes, updates.
What's Included
- Architecture and project documentation.
- Implementation of the companion app (iOS / Android / cross-platform).
- Watch integration: Wear OS or watchOS.
- Push notification setup (APNs / FCM).
- In-app purchases implementation (StoreKit 2 / Billing 6) and ATT.
- Store publication.
- Client team training (optional).
- 30-day bug fix warranty.
Timelines and Cost
Estimated timelines: from 3 to 6 weeks for Android + Wear OS (depending on complexity). For multi-platform solutions — individual assessment. Cost is calculated after project analysis. Typical project cost ranges from $15,000 to $30,000 based on scope. Contact us for a consultation — we'll answer all your questions.
| Platform | Timelines | Key Technologies |
|---|---|---|
| Android + Wear OS | 3–6 weeks | DataLayer, WorkManager, Jetpack Compose |
| iOS + watchOS | 4–7 weeks | WatchConnectivity, SwiftUI |
| Cross-platform | 5–9 weeks | Flutter/RN with native modules |
Common Mistakes in Companion App Development
- Unversioned protocol → crashes when one device updates.
- No send queue → data loss when watch disconnects.
- Using LiveData in background → context leaks.
- Ignoring Data Layer limits (100 KB) → data loss.
- Not checking watch availability → infinite send attempts.
We're ready to discuss your project. Contact us for a consultation — we'll assess the complexity and suggest the optimal solution.
Note: Over 80% of our clients report faster time-to-market using our templates and proven architecture.







