Привет, Хабр! Меня зовут Сергей Орлов, я — Android-разработчик в Dodo Engineering. В этой статье я расскажу, как и зачем мы в приложение Додо Пиццы Live Updates завозили.

Сразу скажу, что вы не найдёте в статье готовых решений. Скорее, я расскажу о нюансах в реализации и тестировании Live Updates, которые не описаны в документации. Подсвечу те моменты, которые разошлись в представлении дизайнеров Google и разработчиков, написавших этот SDK.

Ещё до презентации Live Updates я увидел похожий функционал на смартфонах Samsung в их оболочке OneUI. Ждал, что компания откроет API для разработчиков, чтобы каждый смог запилить в своём приложении собственные Live Updates от Samsung... Но этого не произошло.

Уже весной Google представила Live Updates на презентации Google I/O 2025. С этого момента я стал пушить продактов, что нам это надо. И здорово, что у нас работают максимально открытые ребята, которые готовы помочь тебе в реализации своих амбиций.

Live Updates — это аналог Live Activities в iOS от Google, но со своими нюансами. Технически эта фича состоит из двух частей: режима повышения видимости (promoted ongoing) и специальных стилей контента: progress-centric, CallStyle и др. Вы можете использовать их по отдельности, но по задумке ребят из Google без первой части вторая просто теряет смысл: уведомление становится менее заметным и менее понятным пользователю.

По сути Live Updates — это режим повышенной видимости. Его можно включить не только для отображения прогресса, но и для других системных шаблонов, например, звонков (CallStyle) или навигации. Как я уже и говорил, фича работает и без progress-centric. Если использовать подходящий системный стиль, Android закрепит карточку сверху, добавит чип в статус-баре и выведет на заблокированный экран уведомление, которое будет работать даже в режиме Always-On-Display, что клёво.

Progress-centric — это именно стиль контента уведомления. Он хорошо живёт и как обычное уведомление в шторке без всякого Live Updates. В таком случае пользователь видит ��расивый прогресс с этапами.

Компоненты progress-centric и segment, point прогресс-бара

Углубимся ещё на один уровень и разберём progress-centric. Расскажу, чем он прекрасен и как ограничивает дизайнеров.

Главное отличие progress-centric от RemoteViews в том, что сверстать вид уведомления нельзя: RemoteViews — это кастомная разметка уведомления, которую вы приносите с собой. Здесь же вы можете только заполнить то, что вам предоставляет progress-centric style.

Давайте разберём изображение выше:

  • A – контекст события. Текст в шапке, уточняющий тип активности. Например, «В пути» или «Загрузка».

  • B – время обновления. Метка, когда статус был актуализирован.

  • C – текущий статус. Главный заголовок: что именно происходит прямо сейчас. Например, «Курьер подъезжает».

  • D – детали прогресса. Пояснение к статусу: сколько осталось времени или процентов до завершения отображаемого процесса.

  • E – шкала выполнения. Это визуальный индикатор того, сколько прошло и сколько осталось до завершения отображаемого процесса.

  • F – кнопка управления. Быстрое действие с процессом: «Оставить чаевые», «Позвонить» или «Отменить».

Также посмотрим на то, как выглядят сегменты и поинты в прогресс-баре:

Сегменты описывают длительные фазы процесса. Например, «Готовим» или «Везём». Технически это набор отрезков прогресс-бара с заданной длиной и цветом, которые система рисует в одну линию. Поинты — это маркеры этапов на прогресс-баре: квадраты 20×20 dp, которые лежат в одной плоскости с сегментами.

Однако на сегментах и поинтах дело не ограничивается. Мы можем использовать иконки! Они бывают двух форматов — либо квадратные (20x20 dp), либо вытянутые с соотношением 2:1 (40x20 dp). Они будут двигаться по прогресс-бару, находясь поверх него.

Звучит и выглядит это всё очень круто — особенно в теории. На практике же... Ух, знали бы вы, сколько раз нам пришлось перерисовывать макеты, чтобы видение Google билось с нашим! Устраивайтесь поудобнее — сейчас всё расскажу.

Наши кейсы с progress-centric.

Мы в команде стараемся быть на острие современных технологий, поэтому сразу обратили внимание на возможности Android 16. Наша главная цель — улучшить пользовательский опыт (UX) и сделать так, чтобы статус текущего процесса был максимально явным и наглядным для пользователя. Мы хотели, чтобы человек мог считать информацию мгновенно, не погружаясь в приложение.

Для решения этой задачи мы выбрали использование Live Updates со стилем progress-centric. Казалось, что это идеальный инструмент, но при переносе дизайн-макетов в реальность мы столкнулись с ограничениями системы.

Обратите внимание на синий круг с белой стрелочкой: иконка плавно обрезает по радиусу чёрный сегмент. В реальности она никогда не сможет так аккуратно его обрезать.

Дело в том, что у всей конструкции слоистая структура. То есть иконка «лежит» на прогресс-баре. Она не может отделиться от сегмента, просто потому что она с ним даже не в одной плоскости.

И это ещё не самая большая проблема! Изначально в наших макетах иконка находилась между макетами — казалось, что уж тут ограничений не будет. 

Перед тем, как перейти к самим ограничениям, скажу, что об использовании поинтов речи не шло — они не могут менять свою форму. Нам нужна была именно иконка, которая могла бы перемещаться между несколькими сегментами. И да, одним сегментом мы не могли ограничиться:

Один из вариантов нашего Live Updates
Один из вариантов нашего Live Updates

Ознакомившись с тем, что Google показывал в своей документации, мы считали, что такой вариант идеально подходит. По крайней мере, нам так казалось.

Пример Live Updates из документации
Пример Live Updates из документации

Чтобы понять, где документация Google снова разошлась с реальностью, возьмём пример из документации – скриншот выше – и сравним его с сэмплом, который находится ниже. 

Мы видим, что у грузовика пропал прозрачный фон — это раз. Вокруг него по бокам пропали отступы – это два.

Пример Live Updates из сэмпл-приложения
Пример Live Updates из сэмпл-приложения

Теперь посмотрим на ресурсы сэмпла и увидим, что на макетах в документации у грузовика нет никакого transparent-бэкграунда. Просто потому что это не реализуемо — сэмпл это только лишний раз подтверждает:

Иконка из сэмпл-проекта
Иконка из сэмпл-проекта

Конечно, грузовик всегда можно поместить внутрь поинта. Правда, тогда его размер будет настолько мал, что пользователь вряд ли его различит — не советуем так делать.

«Раз иконка размещается только на прогресс-баре, создадим микросегмент шириной с иконку» — подумали мы, учтя новые вводные. Так мы сможем разместить иконку в центре этого микросегмента. Да и расстояние между ней и остальными сегментами будет таким, будто иконка находится между ними.

Правда, проблему это никак не решит. На коротких сегментах иконка притягивается или к началу, или к концу, а нужного расстояния между иконками и сегментом нет.

Overlay и ад цветоподбора

Это не последнее, что нам удалось выяснить. Когда мы поняли, что реализовать иконку между сегментами невозможно, мы решили изменить дизайн и реализовать вытянутую иконку, которая как капля скользила бы по прогресс-бару. Тем самым мы бы использовали не классическую иконку 20x20 и могли бы привнести своё визуальное решение.

Цвет иконки не совпадает с цветом прогресс-бара
Цвет иконки не совпадает с цветом прогресс-бара

Обратите внимание на цвет иконки и прогресс-бара: у последнего явно есть overlay, о котором в документации нигде не сказано (по крайней мере, на момент написания статьи). Первый раз, когда мы это увидели, мы подумали, что просто установили разные цвета иконки и прогресс-бара.

Это ещё одна мелочь, которая ограничивает дизайнеров и разработчиков. Поэтому от этой идеи пришлось также отказаться и двигаться к следующей итерации.

Status Chips и Always-On-Display

К счастью для нас, помимо неожиданных проблем, при разработке Live Updates мы наткнулись и на уже ожидаемые! Так на эмуляторе Android нельзя было увидеть всех возможностей новой фичи — только на физическом устройстве.

Чёрный фон у чипсы не отображается на эмуляторе
Чёрный фон у чипсы не отображается на эмуляторе

В нашем случае эмулятор не смог отобразить чипс в статус-баре. Почему это для нас важно? Потому что особенность чипс в том, что её фон скрывается, если приложение, использующее Live Updates, находится на переднем плане.

Конечно, это мелочь. В документации об этом нет информации, но, возможно, кому-то будет полезно об этом узнать до начала разработки.

Live Updates на Always-On-Display скрывает некоторые UI-элементы
Live Updates на Always-On-Display скрывает некоторые UI-элементы

Одна из полезнейших возможностей Live Updates — это отображение уведомления в режиме Always-On-Display, если его, конечно, поддерживает устройство. Но и тут без нюансов не обошлось.

В чём дело? Если вы используете эмулятор, а не физическое устройство, то не сможете протестировать отображение Live Updates на Always-On-Display — эмулятор его просто не поддерживает.

Так что будьте готовы к тому, что вам придётся выпрашивать у бизнеса новенький Google Pixel 10 Pro для тестировщика. Ну или на крайняк попросить дешёвенький Android-девайс c Android 16, OLED-экраном и работающим Live Updates.

Кастомизация iOS Live Activities vs Android Live Updates

Ну и, конечно, мы не можем не сравнить Live Activities на iOS и Live Updates на Android. Да начнётся срач в комментах.

Мы с командой заметили, что Live Activities на iOS — это маленький брендированный виджет. Мы сами верстаем контент на Swift UI, добавляем свои градиенты, прогресс-индикаторы, карточки, аватар курьера и даже интерактивные элементы. А ещё Live Activities отображается в режиме StandBy, которого просто нет на Android.

В общем, Apple оставляет строгие рамки по зонам и размерам, но внутри них у дизайнера есть поле для творчества. Результат выглядит живым, узнаваемым и аккуратно встроенным в экосистему.

В Live Activities больше свободы для творчества
В Live Activities больше свободы для творчества

А вот на Androooid... Live Updates — это даже не мини-виджет. Это просто системный шаблон уведомления с прогрессом, который Google использует для journey-сценариев вроде доставки или такси.

Мы описываем шаги и статусы, и даже можем поиграть с цветами и формами, но строго в рамках шаблона. Кастомизация тут минимальна, а целостность и нативность — максимальны. Так что вместо того, чтобы рисовать свой UI, мы просто заполняем формуляр, получая за это понятный и унифицированный опыт пользователя.

Унифицированный стиль Live Updates
Унифицированный стиль Live Updates

Микс отображения

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

В приложении Додо мы совместили Live Updates со стилем progress-сentric на этапах от создания заказа до его передачи курьеру.

Progress-сentric стиль и Live Updates режим
Progress-сentric стиль и Live Updates режим

А вот оценку заказа уже оставили на RemoteViews:

RemoteViews API
RemoteViews API

Кстати, последовательность использования стилей уведомления неважна. Вы можете поместить RemoteViews хоть в середину, хоть в начало. В общем, тут всё реально удобно.

Финал

Подведём итоги. Начнём с ограничений Live Updates на Android — так уж получилось, что их больше:

  1. Нельзя расположить иконку между сегментами — она может только лежать на прогресс-баре.

  2. Нельзя изменить форму поинта — только впиливать в него иконки.

  3. У прогресс-бара есть оверлей — вы никогда не сможете покрасить иконку и прогресс-бар в один цвет.

  4. Пилюля не отображается, если приложение на переднем плане.

  5. Эмулятор неидеален. Вы не сможете увидеть на нём ни то, как Live Updates работают в режиме Always-On-Display, ни то, как он с пилюлей смотрится.

  6. По сравнению с iOS Live Activities решение Google сильно проигрывает в кастомизации.

Плюсов не так много, но они есть:

  1. Можно отображать уведомление в режиме Always-On-Display.

  2. У нас теперь есть новый стандартизированный стиль уведомлений. Прямо как CallStyle, MediaStyle и другие, но со своими фишками.

  3. Для пользователя прогресс отображаемого на Live Updates процесса гораздо очевиднее.

Пусть плюсов немного, но это не делает фичу плохой. Главное, что Live Updates полезны для пользователей. Так что ограничения API и эмулятора не должны нам помешать сделать приложение чуть удобнее.

В общем, если вы хотите унифицировать свои кастомные реализации, используя рекомендованный Google подход, или получить дополнительные возможности для отображения уведомлений, Live Updates c progress-centric — точно для вас! Хотелось бы, правда, в будущих версиях API больше кастомизации…

Ну да ладно. Думаю, что когда Google зарядит большой апдейт своих Live Updates, я вам о нём расскажу. А на этом у меня пока всё.

В комментариях расскажите, успели ли вы уже что-то реализовать, используя Live Updates? Что порадовало в процессе, а что расстроило?

Спасибо, что дочитали статью! О том, как мы развиваем IT в Додо в целом, читайте в Telegram-канале Dodo Engineering. Там мы рассказываем о жизни нашей команды, культуре и последних разработках.

В своём личном канале «Орлов катит в прод» я делюсь опытом мобильной разработки: от энтерпрайза до пет-проектов. Заглядывайте!