Skip to main content
The cover image for "Do I need a coat? - I've made a smartwatch app"

Do I need a coat? - I've made a smartwatch app

Sidebar

I've finally polished up and released a smartwatch app I created two years ago. "Do I need a coat?" is a refreshingly minimalist wear app that tells you whether you need a coat, extra layers, or sunglasses based on the upcoming forecast.

I’ve finally polished up and released a smartwatch app I created two years ago. “Do I need a coat?” is a refreshingly minimalist wear app that tells you whether you need a coat, extra layers, or sunglasses based on the upcoming forecast.

Download from Google Play

The app #

In a world of increasingly complicated weather apps, “Do I need a coat?” provides a refreshingly simple solution to answer your core questions: Should I take a coat today? Do I need a jumper? Will I need sunblock?

Swipe on your watch face to see Do I need a coat?'s tile. It shows you which items you’ll need for your day at a glance. Tap the tile to see more details. The app shows you the forecast for your current location, powered by AccuWeather.

Do I need a coat? demo video

Development #

Do I need a coat? is a native Android app created using the WearOS SDK. The app was written following modern Android architecture, using Kotlin and Jetpack components. The app uses a multi-module design to enforce architecture layers and make it easy to add a mobile app in the future.

Tiles and protolayout #

Tiles are the screens shown when you swipe left or right on the watch. They’re similar to mobile widgets: they’re always loaded but have limited functionality. Creating a tile required learning yet another view system by Google.

To create widgets for a phone, you use an API called remote views. Widgets are displayed on the launcher and not as part of your app, and so they need a secure view API that can be easily serialized. This API is remote views. Remote views are incredibly limited, especially when it comes to making responsive layouts. You can use Compose Glance to make mobile widgets using Compose. This is just a layer on top of remote views, it doesn’t fix the fundamental limitations.

Wear tiles are written using an API called wear protolayout, a completely new API that doesn’t use Compose. I’m not sure why they did this. I’m not saying that they should have used remote views - as they are awful - but I would have liked to see a new API for both widgets and tiles with more capabilities, based on Compose.

Widget and tile architecture #

I design widgets and tiles to act as thin UI layers subscribing to a repository. The repository is the data layer, and stores the state for the widget or tile. The state can be updated in the background using WorkManager, and then the widget or tile updates to match the state. Using an architecture like this reduces the complexity of widgets and improves testability.

When writing a mobile widget, I can subscribe to the repository using Kotlin flows. This means that the widget will react to any data changes whilst the widget worker is running. This is helpful as state updates are often emitted in quick succession.

This is not possible for tiles. I need to ensure that I trigger the tile updater after all data has been written. This isn’t a huge problem but is a little bit annoying when it comes to trying to make the same architecture.

Conclusion #

This was a rather fun project and a chance to use something new. I created this after I bought a smartwatch two years ago; it’s nice to have the freedom to write software for hardware you own. It’s also nice to be using my Google Play developer account again.

I have some plans for future development but it depends on how much interest this app receives. I’d like to add customisation, the ability to search for a location, precipitation charts, and a mobile app with widgets.

rubenwardy's profile picture, the letter R

Andrew Ward

Hi, I'm Andrew Ward. I'm a software developer, an open source maintainer, and a graduate from the University of Bristol. I’m a core developer for Luanti, an open source voxel game engine.

Comments

Leave comment

Shown publicly next to your comment. Leave blank to show as "Anonymous".
Optional, to notify you if rubenwardy replies. Not shown publicly.
Max 1800 characters. You may use plain text, HTML, or Markdown.