Запилил за вечер приложение на часы. Что я могу сказать про это? Функциональность самих API, которые предоставляются Google, очень плохая.


Гайд: Как разрабатывать приложение на часы под Android в Wear OS

Шаг 1: Создание проекта

С чего вам нужно начать: используйте шаблон, создайте по официальной документации приложение под Android. У вас будет одно приложение, которое вы запускаете. Вы делаете второе так же, только будет другой SDK target и парочка других твиков.

⚠️ Критически важно: Package ID

Важный, суперважный момент: у вашего приложения package ID (не тот что джавовый, а который Android-овский) должен быть точно такой же, как у вашего основного приложения, иначе они друг друга не узнают и не подконнектятся.

Особенно внимательно смотрите, если у вас у дебага и релиза приложения разные package ID. Например, вы используете package ID суффикс какой-нибудь. У меня была такая проблема, что они друг друга не узнавали. У вас не будет никаких ошибок, просто отличаются package ID.

Я надеялся свой неудачный package ID поменять на красивый, который я уже давно поменял везде, кроме package ID в Android, ибо его нельзя менять. Придется использовать старый.

Шаг 2: Выбор библиотек

Создаете этот проект, можно использовать Compose, добавляете все зависимости нужные.

Я рекомендую Horologist использовать для Wear OS приложения, а для телефона нет, если у вас оно супер простое. Если вы просто отправляете на Wear OS данные, можно обойтись через эти слушатели, написать враперы, использовать Kotlin сериализацию, и в принципе пойдет. Я пока так решил, потому что там баги в Horologist, но возможно вы захотите Horologist и на телефон затащить, потому что там по сути тоже такие же плюшки с корутинами, все эти обертки и листнеры в корутины завернуты.

Шаг 3: Настройка wear.xml и capabilities

Там есть специальный wear.xml файл, в котором вам нужно прописать ключ, называется capability.

Для Horologist используйте те, которые они вам скажут, потому что они используют в исходниках захардкоженные строки, которые вы должны добавить в этот XML файл, иначе ничего не запустится. Если не используете Horologist, можете любую фигню написать в этом XML для capability.

Главное, чтобы у вас было их два: один для телефона, другой для watch. На watch вы чекаете, есть ли capability телефона, а на телефоне чекаете, есть ли capability watch. Вы проверяете, поддерживает ли девайс этот capability - возможность связи с вашим приложением.

Это даст возможность понять, установлено ли приложение на часах и установлено ли оно на телефоне. Чтобы человеку показать: “Хей, слушай, у тебя не установлено приложение на телефоне, давай тебя в Google Play направлю.” И наоборот, конечно же.

Это всегда нужно продумать, потому что человек может установить приложение на часы, но не установить на телефон, или наоборот. Как он узнает, что у вас есть приложение на часы? Это нигде не показывается. Вам нужно самим сделать flow: “Йоу, здорово, а у нас есть приложение на часы, хочешь установить?” Вам нужно будет правильно распознать, когда это сделано или не сделано.

Шаг 4: UI и Material Components

Добавляете Compose Material 3, нужно использовать все собственные компоненты с нуля. Делаете как в Horologist, я рекомендую стырить их исходники, копировать себе, потому что там немножко неправильно сделали с ограничениями по размеру.

Нужно проверять, есть ли круглый экран у часов или квадратный, и вы делаете разную верстку в зависимости от этого. Не рекомендую делать только одну, потому что будет смотреться как кусок кала.

Шаг 5: Data Layer API для синхронизации состояния

Подключаете Wear OS Play SDK, и через него у вас там будет Data Manager, Data Layer. Он нужен как глобальный broadcast на все устройства - какие данные там сейчас находятся. Считайте, что это какой-то стейт, который шарится между вашим приложением и всеми приложениями на часах, и наоборот.

Часы могут отправлять данные, и телефон может отправлять данные. У меня телефон отправляет все данные, часы только их отображают. Для простоты сделано.

Используйте эту API для штук типа стейта, которые должны синхронизироваться между всеми часами. Часов даже может быть несколько, и телефонов может быть несколько. Это тоже проблема, нужно это как-то обрабатывать. Я решил, что я просто беру самый первый - первый телефон будет главным, остальные все будут просто игнорировать часы. Чисто для простоты. Мало у кого будет несколько телефонов с одними часами, это бред.

Шаг 6: Messages API для RPC

Если вам нужно отправить сообщение, вы используете Messages API. Тоже есть отдельная штука на колбеках. Это по сути просто RPC - вы можете вызывать функции.

Протобаф можно добавить и все это прописать, но я не хочу добавлять протобаф, меня он бесит, он очень тяжелый. Поэтому я все запилил через Kotlin сериализацию и события как на вебсокетах. Там просто отправляются байты, которые парсятся на телефоне.

На телефоне практически тот же самый код, очень похоже. Делаете singleton с вашим репозиторием, который будет наблюдать за часами в нужное flow. Например, у меня ритуал стартует, и вы начинаете отправлять данные через Data Layer API. А часы будут через Messages API вам посылать события, которые вы должны использовать. Таким образом и строите взаимодействие. В принципе, ничего сложного.

Чеклист: Что обязательно нужно проверить

Только не забудьте проверить:

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

Про токены и авторизацию

Если вам нужно с часов выходить в интернет или использовать токены авторизации, для этого есть специальные API - бандл токена идентификации. Вы можете пошарить токены между устройствами благодаря этому. Это единственный способ безопасно это сделать. Там начинается отдельная долбежка.

Поэтому я рекомендую все-таки делать приложение на часы обычным slave-приложением, а приложение на телефон источником данных. То есть оно просто будет неким куском UI, который будет работать на часах.


Мой опыт в 2024:

Проблема №1: Зависимость от Google Play Services

Все работает только через Google Play Services. Если на девайсе нет Google Play Services, или что-то с ним не так, или старая версия Android, то все пойдет наперекосяк. Это надо обрабатывать конкретно и пытаться помочь человеку решить этот вопрос или скрывать от него эту функциональность, чтобы он не оставил ревью на одну звезду.

Проблема №2: Древние API и нулевая документация

Там все написано на Java, древнеегипетские API через колбеки и слушатели. Документация вообще 0, просто API surface, ничего не объясняется, все обфусцировано в коде. В code labs ничего непонятно, специфичных use cases нет. Там только описана зачем-то авторизация, и как это все связать друг с другом тоже непонятно.

Там только отдельные куски: вот тебе функция, вызови ее. Где ее вызывать, когда вызывать, как вызывать, как получить результат, как создать нужные для нее объекты? Там какие-то билдеры все время, куча непонятных вещей, которые вообще никак не задокументированы.

Альтернатива: Horologist (но и тут не без проблем)

Если хочется чего-то на Kotlin получше, то есть только одна альтернатива - библиотека Horologist от самих Google на GitHub. Как Accompanist в свое время был игровой площадкой для команды Google, где они могли пушить в master что хотят и смотреть, что останется висеть на стене, так и здесь то же самое, только для часов.

Они сделали какую-то библиотеку, больше похожую на проект, где свой кусок своей кодовой базы выкинули в open source. Мол, нам это нужно было, мы это добавили. Например, сделали Kotlin функцию, чтобы как с Flow смотреть за результатами, но у этого 0 кастомизации.

Все заложено на их технический стек: Firebase, DataStore, ProtoBuf, Preferences и ProtoLite, который крашится. Сейчас там баг есть на GitHub, из-за него пользоваться этим тоже очень сложно, практически невозможно. Опять же, ничего не задокументировано, многие use cases не покрыты. Покрыто только то, что Google нужно было теоретически, и из-за того, что есть свой технический стек, который нужно как-то связать со стеком Respawn. У нас тоже много чего написано своего.

Так что это была просто эпопея. Самое сложное в разработке приложения на часы было в этом.

Плюсы Wear OS разработки

Это по сути приложение на Android. Можно все переиспользовать практически: подключить свои модули, подключить всю бизнес-логику и доменные модели, и писать UI на обычном Compose. Только там нет Material 3, только Material 2. Нужны отдельные компоненты. Обычные, конечно же, не получится использовать, потому что там очень ограниченный форм-фактор девайса.

Но все равно, за вечер, с божьей помощью, исходниками Horologist и собственного опыта, я смог создать приложение, которое показывает статус текущего ритуала, как медиаплеер, как Spotify на часах. Такой очень простой MVP-приложение-компаньон.