Live Updates на Android
Pushwoosh поддерживает Android Live Updates через модуль pushwoosh-liveupdates (SDK 6.9.0 и более поздние версии). Live Update — это постоянное уведомление в стиле прогресс-бара, которое система выводит на экран блокировки, в шторку уведомлений и в виде чипа состояния в строке состояния, чтобы пользователи могли следить за активностью, не открывая ваше приложение.
Весь жизненный цикл управляется с сервера: ваш бэкенд отправляет push-уведомление, когда активность начинается, новые push-уведомления по мере ее продвижения и финальное push-уведомление, когда она заканчивается. SDK отображает каждое из них автоматически.
Что такое Live Updates
Anchor link toLive Updates были представлены в Android 16 (API 36) как способ отображения инициированной пользователем, чувствительной ко времени активности от начала до конца. Они основаны на системных уведомлениях, ориентированных на прогресс, и API Notification.ProgressStyle. Концептуально они являются аналогом Live Activities в iOS.
Эта страница описывает только интеграцию с Pushwoosh. Для получения информации о поведении платформы, правилах продвижения и рекомендациях по дизайну обратитесь к официальной документации Android:
- Уведомления, ориентированные на прогресс
- Создание live update уведомлений (Views)
- Создание live update уведомлений (Compose)
Когда использовать Live Updates
Anchor link toLive Updates предназначены для активностей, которые являются продолжительными, инициированными пользователем и чувствительными ко времени — то, что имеет четкое начало и конец и о чем пользователь активно заботится в данный момент. Типичные сценарии для клиентов Pushwoosh:
- Доставка еды — заказ принят, готовится, в пути, прибывает.
- Вызов такси и поездки — водитель назначен, в пути, прибывает, поездка в процессе.
- Отслеживание заказов и доставок — текущий статус заказа, который активно находится в пути.
- Прямые трансляции спортивных событий и медиа — счет и время матча по ходу игры.
- Фитнес — активная тренировка или пробежка с указанием прошедшего времени и прогресса.
- Финтех — транзакция или процесс верификации, проходящий через свои этапы.
Поскольку жизненный цикл управляется реальными событиями, о которых ваш бэкенд уже знает (статус заказа меняется, курьер движется), Live Update обычно представляет собой один вызов API, встроенный в ваш существующий поток событий, а не что-то, что человек отправляет вручную.
Требования
Anchor link to- Android 16 (API 36) или новее. На старых устройствах модуль остается неактивным, и каждый вызов API Live Update является безопасной пустой операцией (no-op).
- Pushwoosh Android SDK 6.9.0 или более поздней версии.
Добавление модуля pushwoosh-liveupdates
Anchor link toДобавьте зависимость в ваш файл app/build.gradle:
dependencies { implementation 'com.pushwoosh:pushwoosh-liveupdates:<latest-version>'}Замените <latest-version> на текущую версию из Maven Central.
Модуль обнаруживается автоматически при запуске. Он объявляет необходимое разрешение POST_PROMOTED_NOTIFICATIONS, регистрирует собственный канал уведомлений и перехватывает push-уведомления Live Update до стандартного пути обработки уведомлений. Дополнительного кода инициализации не требуется — SDK устанавливает флаги ongoing и promoted, загружает большую иконку, сопоставляет кнопки действий и публикует уведомление за вас.
Отправка Live Update
Anchor link toВы отправляете Live Updates через Messaging API v2, добавляя поля Live Update в объект root_params контент-блока android. Используйте transactional запрос — Live Update нацелен на конкретного пользователя, чью активность он отслеживает. Поле schedule является обязательным; { "after": "0s" } отправляет немедленно. Жизненный цикл имеет три операции, устанавливаемые в pw_live_op:
start— первое push-уведомление для активности. Публикует постоянное уведомление.update— последующее push-уведомление для той же активности. Обновляет его на месте, беззвучно.end— завершающее push-уведомление. Закрывает уведомление.
Все push-уведомления, относящиеся к одной и той же активности, должны иметь одинаковый pw_live_id. Этот идентификатор связывает обновления вместе, а также используется для закрытия обновления из приложения.
Каждое push-уведомление полностью описывает уведомление — ничего не переносится из предыдущего. Повторно отправляйте каждое поле, которое хотите сохранить, например, сегменты и большую иконку, с каждым update; пропущенное поле отображается как отсутствующее.
Параметры Live Update
Anchor link toЭти ключи помещаются в объект root_params контент-блока android. Заголовок, тело и большая иконка используют стандартные поля Android push-уведомлений (title, body, custom_icon).
| Параметр | Тип | Описание |
|---|---|---|
pw_live_op | string | Операция жизненного цикла: start, update или end. Обязательно. |
pw_live_id | string | Стабильный идентификатор активности, общий для всех push-уведомлений одного Live Update. Обязательно. |
pw_live_progress | int | Значение прогресса, измеряемое относительно суммарной длины сегментов. |
pw_live_progress_indeterminate | bool | Показывать неопределенную анимацию вместо конкретного значения. |
pw_live_segments | JSON string | Упорядоченные сегменты прогресса, каждый в формате {"color": "#RRGGBB", "length": N}. |
pw_live_extras | JSON string | Произвольные данные, передаваемые кастомному провайдеру стилей. |
pw_live_when | long | Временная метка для заголовка в миллисекундах эпохи. |
pw_live_chronometer | bool | Показывать время в заголовке как работающий таймер. |
pw_live_chronometer_count_down | bool | Работающий таймер отсчитывает время в обратном порядке, а не вперед. |
pw_live_show_when | bool | Показывать ли вообще столбец времени в заголовке. По умолчанию true. |
Четыре поля времени комбинируются следующим образом: если pw_live_show_when установлено в false, время скрыто; в противном случае pw_live_when является опорной точкой, pw_live_chronometer превращает его в работающий счетчик, а pw_live_chronometer_count_down заставляет этот счетчик идти в обратном направлении.
Push для старта
Anchor link tocurl -X POST https://api.pushwoosh.com/messaging/v2/notify \ -H "Authorization: Token YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "transactional": { "application": "XXXXX-XXXXX", "platforms": ["ANDROID"], "users": { "list": ["customer-42"] }, "payload": { "content": { "localized_content": { "default": { "android": { "title": "Order #4521", "body": "We are preparing your order", "custom_icon": "https://example.com/restaurant.png", "root_params": { "pw_live_op": "start", "pw_live_id": "order_4521", "pw_live_progress": "1", "pw_live_segments": "[{\"color\":\"#34A853\",\"length\":3},{\"color\":\"#FBBC05\",\"length\":4},{\"color\":\"#4285F4\",\"length\":3}]", "pw_live_extras": "{\"eta\":\"18:40\"}" } } } } } }, "schedule": { "after": "0s" }, "message_type": "MESSAGE_TYPE_TRANSACTIONAL" } }'Push для обновления
Anchor link toОтправьте update с тем же pw_live_id, когда активность продвигается вперед. Повторите сегменты и иконку — обновление, в котором они отсутствуют, будет отображено без них.
curl -X POST https://api.pushwoosh.com/messaging/v2/notify \ -H "Authorization: Token YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "transactional": { "application": "XXXXX-XXXXX", "platforms": ["ANDROID"], "users": { "list": ["customer-42"] }, "payload": { "content": { "localized_content": { "default": { "android": { "title": "Order #4521", "body": "Your courier is on the way", "custom_icon": "https://example.com/restaurant.png", "root_params": { "pw_live_op": "update", "pw_live_id": "order_4521", "pw_live_progress": "7", "pw_live_segments": "[{\"color\":\"#34A853\",\"length\":3},{\"color\":\"#FBBC05\",\"length\":4},{\"color\":\"#4285F4\",\"length\":3}]" } } } } } }, "schedule": { "after": "0s" }, "message_type": "MESSAGE_TYPE_TRANSACTIONAL" } }'Push для завершения
Anchor link toЗавершающему push-уведомлению нужны только операция и идентификатор.
curl -X POST https://api.pushwoosh.com/messaging/v2/notify \ -H "Authorization: Token YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "transactional": { "application": "XXXXX-XXXXX", "platforms": ["ANDROID"], "users": { "list": ["customer-42"] }, "payload": { "content": { "localized_content": { "default": { "android": { "root_params": { "pw_live_op": "end", "pw_live_id": "order_4521" } } } } } }, "schedule": { "after": "0s" }, "message_type": "MESSAGE_TYPE_TRANSACTIONAL" } }'Настройка внешнего вида
Anchor link toSDK поставляется со стилем прогресса по умолчанию, созданным из pw_live_progress, pw_live_progress_indeterminate и pw_live_segments. Чтобы получить полный контроль над прогресс-баром, реализуйте LiveUpdateProgressStyleProvider и самостоятельно сформируйте Notification.ProgressStyle.
Провайдер является единственной точкой кастомизации. SDK по-прежнему управляет настройкой канала, флагами ongoing и promoted, большой иконкой, кнопками действий и временем в заголовке — кастомный провайдер может формировать только прогресс-бар, поэтому он не может нарушить право на продвижение. Он должен быть без состояния (stateless): возвращаемый стиль должен зависеть только от предоставленного LiveUpdateState. Если он выбрасывает исключение, SDK возвращается к стилю по умолчанию, и уведомление все равно публикуется.
import android.app.Notification;import androidx.annotation.NonNull;import com.pushwoosh.liveupdates.LiveUpdateProgressStyleProvider;import com.pushwoosh.liveupdates.LiveUpdateSegment;import com.pushwoosh.liveupdates.LiveUpdateState;import java.util.List;
public class OrderStyleProvider implements LiveUpdateProgressStyleProvider { @NonNull @Override public Notification.ProgressStyle createStyle(@NonNull LiveUpdateState state) { Notification.ProgressStyle style = new Notification.ProgressStyle(); if (state.getProgress() != null) { style.setProgress(state.getProgress()); } style.setProgressIndeterminate(state.isProgressIndeterminate());
List<LiveUpdateSegment> segments = state.getSegments(); int boundary = 0; for (int i = 0; i < segments.size(); i++) { LiveUpdateSegment seg = segments.get(i); style.addProgressSegment( new Notification.ProgressStyle.Segment(seg.getLength()).setColor(seg.getColor())); boundary += seg.getLength(); if (i < segments.size() - 1) { style.addProgressPoint(new Notification.ProgressStyle.Point(boundary)); } } return style; }}import android.app.Notificationimport com.pushwoosh.liveupdates.LiveUpdateProgressStyleProviderimport com.pushwoosh.liveupdates.LiveUpdateState
class OrderStyleProvider : LiveUpdateProgressStyleProvider { override fun createStyle(state: LiveUpdateState): Notification.ProgressStyle { val style = Notification.ProgressStyle() state.progress?.let { style.setProgress(it) } style.setProgressIndeterminate(state.isProgressIndeterminate)
val segments = state.segments var boundary = 0 segments.forEachIndexed { i, seg -> style.addProgressSegment( Notification.ProgressStyle.Segment(seg.length).setColor(seg.color)) boundary += seg.length if (i < segments.size - 1) { style.addProgressPoint(Notification.ProgressStyle.Point(boundary)) } } return style }}Зарегистрируйте провайдер с помощью тега <meta-data> в AndroidManifest.xml. Класс должен иметь публичный конструктор без аргументов.
<meta-data android:name="com.pushwoosh.LIVE_UPDATE_STYLE_PROVIDER" android:value="com.example.OrderStyleProvider" />Используйте LiveUpdateState.getExtras() для чтения JSON, который вы отправили в pw_live_extras, и адаптируйте стиль к вашим собственным бизнес-данным.
Управление Live Updates из вашего приложения
Anchor link toСервер управляет каждым start, update и end, поэтому нет API на стороне приложения для публикации или обновления Live Update. Фасад PushwooshLiveUpdates охватывает только то, что не может сделать сервер — локальное закрытие обновления и проверка, какие из них отображаются на экране.
import com.pushwoosh.liveupdates.PushwooshLiveUpdates;
// Закрыть конкретный Live Update, когда пользователь завершает активность в приложении,// не дожидаясь финального push-уведомления "end" от сервераPushwooshLiveUpdates.endLiveUpdate("order_4521");
// Получить список идентификаторов активностей, отображаемых в данный момент этим приложениемList<String> active = PushwooshLiveUpdates.getActiveIds();
// Очистить все, что показывает это приложение, например, при выходе из системыPushwooshLiveUpdates.endAllLiveUpdates();Все методы безопасно вызывать из любого потока, и они являются пустой операцией (no-op) на устройствах с версией Android ниже 16.