Устройства Wear OS часто используются для длительных задач, таких как отслеживание тренировок. Это создает проблему для пользовательского опыта: если пользователь начинает выполнение задачи, а затем переходит к циферблату часов, как ему вернуться? Возврат в приложение через лаунчер может быть затруднен, особенно в движении, что создает ненужные неудобства.
Решение заключается в том, чтобы связать текущее уведомление с событием OngoingActivity . Это позволяет устройству отображать информацию о длительной активности в пользовательском интерфейсе, обеспечивая такие функции, как нажимаемая иконка в нижней части циферблата. Это позволяет пользователям быть в курсе фоновой задачи и обеспечивает возможность вернуться в приложение одним касанием.
Постоянная активность также позволяет вашему приложению дольше оставаться видимым, предотвращая возвращение системы к циферблату часов после периода бездействия. Для получения дополнительной информации см. раздел «Поддержание видимости вашего приложения на Wear» .
Например, в этом приложении для тренировок информация может отображаться на циферблате часов пользователя в виде интерактивного значка бега:

Рисунок 1. Индикатор активности.
Постоянно отображаемое уведомление также показывает информацию в разделе «Недавние» глобального лаунчера приложений. Это предоставляет пользователям еще одно удобное место для просмотра статуса своей задачи и повторного взаимодействия с приложением.

Рисунок 2. Глобальная пусковая установка.
Ниже перечислены ситуации, в которых целесообразно использовать постоянно действующее уведомление, привязанное к текущей активности:

Рисунок 3. Таймер: Активно отсчитывает время и завершает отсчет, когда таймер приостанавливается или останавливается.

Рисунок 4. Пошаговая навигация: озвучивает указания к месту назначения. Заканчивается, когда пользователь достигает пункта назначения или останавливает навигацию.

Рисунок 5. Медиа: Воспроизводит музыку на протяжении всего сеанса. Заканчивается сразу после того, как пользователь приостанавливает сеанс.
Wear автоматически создает текущие действия для медиаприложений.
В практическом руководстве по созданию непрерывных действий для других типов приложений вы найдете подробный пример.
Настраивать
Чтобы начать использовать API текущих действий в вашем приложении, добавьте следующие зависимости в файл build.gradle вашего приложения:
dependencies {
implementation "androidx.wear:wear-ongoing:1.1.0"
implementation "androidx.core:core:1.17.0"
}
Создайте постоянно обновляемую активность
Процесс состоит из трех этапов:
- Создайте стандартный объект
NotificationCompat.Builderи настройте его как постоянно обновляемый. - Создайте и настройте объект
OngoingActivity, передав ему построитель уведомлений. - Примените текущую активность к конструктору уведомлений и отправьте полученное уведомление.
Создайте и настройте уведомление.
Начните с создания объекта NotificationCompat.Builder . Ключевой шаг — вызвать setOngoing(true) чтобы пометить уведомление как текущее. На этом этапе вы также можете установить другие свойства уведомления, такие как значок и категория.
// Create a PendingIntent to pass to the notification builder val pendingIntent = PendingIntent.getActivity( this, 0, Intent(this, AlwaysOnActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_SINGLE_TOP }, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE, ) val notificationBuilder = NotificationCompat.Builder(this, CHANNEL_ID) .setContentTitle("Always On Service") .setContentText("Service is running in background") .setSmallIcon(R.drawable.animated_walk) // Category helps the system prioritize the ongoing activity .setCategory(NotificationCompat.CATEGORY_WORKOUT) .setContentIntent(pendingIntent) .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) .setOngoing(true) // Important!
Создать текущую активность
Далее создайте экземпляр OngoingActivity , используя его построитель. Для работы OngoingActivity.Builder требуется Context , идентификатор уведомления и NotificationCompat.Builder , созданный вами на предыдущем шаге.
Настройте ключевые свойства, которые будут отображаться на новых элементах пользовательского интерфейса:
- Анимированные и статические значки : Предоставляют значки, отображаемые на циферблате часов в активном и фоновом режимах.
- Touch intent :
PendingIntent, который возвращает пользователя в ваше приложение при нажатии на значок текущей активности. Вы можете повторно использоватьpendingIndentсозданный на предыдущем шаге.
val ongoingActivity = OngoingActivity.Builder(applicationContext, NOTIFICATION_ID, notificationBuilder) // Sets the icon that appears on the watch face in active mode. .setAnimatedIcon(R.drawable.animated_walk) // Sets the icon that appears on the watch face in ambient mode. .setStaticIcon(R.drawable.ic_walk) // Sets the tap target to bring the user back to the app. .setTouchIntent(pendingIntent) .build()
Подайте заявку на участие в конкурсе и опубликуйте объявление.
Последний шаг — связать объект OngoingActivity с уведомлением, а затем отправить его. Метод ongoingActivity.apply() изменяет исходный конструктор уведомлений, добавляя необходимые данные, чтобы система могла отобразить его на дополнительных поверхностях. После применения вы можете создать и отправить уведомление как обычно.
// This call modifies notificationBuilder to include the ongoing activity data. ongoingActivity.apply(applicationContext) // Post the notification. startForeground(NOTIFICATION_ID, notificationBuilder.build())
Добавить динамический текст состояния в панель запуска
Приведенный выше код добавляет на циферблат часов иконку, на которую можно нажать. Чтобы обеспечить еще более информативные обновления в режиме реального времени в разделе «Последние» панели запуска, создайте объект Status и прикрепите его к вашему OngoingActivity . Если вы не укажете пользовательский Status , система по умолчанию будет использовать текст содержимого уведомления (заданный с помощью setContentText() ). Для отображения динамического текста используйте Status.Builder . Вы можете определить шаблонную строку с заполнителями и предоставить объекты Status.Part для заполнения этих заполнителей. Status.Part может быть динамическим, например, секундомер или таймер.
В следующем примере показано, как создать статус, отображающий "Запуск для [секундомера]":
// Define a template with placeholders for the activity type and the timer. val statusTemplate = "#type# for #time#" // Set the start time for a stopwatch. // Use SystemClock.elapsedRealtime() for time-based parts. val runStartTime = SystemClock.elapsedRealtime() val ongoingActivityStatus = Status.Builder() // Sets the template string. .addTemplate(statusTemplate) // Fills the #type# placeholder with a static text part. .addPart("type", Status.TextPart("Run")) // Fills the #time# placeholder with a stopwatch part. .addPart("time", Status.StopwatchPart(runStartTime)) .build()
Наконец, свяжите этот Status с вашим OngoingActivity вызвав setStatus() в объекте OngoingActivity.Builder .
val ongoingActivity = OngoingActivity.Builder(applicationContext, NOTIFICATION_ID, notificationBuilder) // ... // Add the status to the OngoingActivity. .setStatus(ongoingActivityStatus) .build()
Дополнительные настройки
Помимо Status , вы можете настроить текущую активность или уведомления следующими способами. Однако эти настройки могут быть недоступны в зависимости от реализации производителя оборудования.
Текущее уведомление
- Набор категорий определяет приоритет текущей деятельности.
-
CATEGORY_CALL: входящий голосовой или видеозвонок или аналогичный запрос на синхронную связь. -
CATEGORY_NAVIGATION: карта или пошаговая навигация -
CATEGORY_TRANSPORT: управление передачей мультимедиа для воспроизведения -
CATEGORY_ALARM: будильник или таймер -
CATEGORY_WORKOUT: тренировка -
CATEGORY_LOCATION_SHARING: категория временного обмена местоположением -
CATEGORY_STOPWATCH: секундомер
-
Текущая деятельность
Анимированная иконка: черно-белый векторный рисунок, предпочтительно с прозрачным фоном. Отображается на циферблате часов в активном режиме. Если анимированная иконка не предоставлена, используется иконка уведомлений по умолчанию. Иконка уведомлений по умолчанию отличается для каждого приложения.
Статическая иконка: векторная иконка с прозрачным фоном. Отображается на циферблате в фоновом режиме. Если анимированная иконка не задана, в активном режиме на циферблате используется статическая иконка. Если она не указана, используется иконка уведомления. Если ни одна из них не задана, генерируется исключение. (Средство запуска приложений по-прежнему использует иконку приложения.)
OngoingActivityStatus: обычный текст или
Chronometer. Отображается в разделе « Недавние» на панели запуска приложений. Если не указано, используется «контекстный текст» уведомления.Touch Intent: a
PendingIntentused to switch back to the app if the user taps on the ongoing activity icon. Displays on the watch face or on the launcher item. It can be different from the original intent used to launch the app. If not provided, the notification's content intent is used. If neither is set, an exception is thrown.LocusId: Идентификатор, присваивающий ярлык запуска, соответствующий текущей активности. Отображается в разделе «Недавние» на панели запуска во время выполнения активности. Если не указан, панель запуска скрывает все элементы приложений из того же пакета в разделе « Недавние » и отображает только текущую активность.Идентификатор текущей активности: идентификатор, используемый для уточнения вызовов функции
fromExistingOngoingActivity(), когда в приложении выполняется более одной текущей активности.
Обновить текущую активность
В большинстве случаев разработчики создают новое текущее уведомление и новое текущее действие, когда им нужно обновить данные на экране. Однако API текущих действий также предлагает вспомогательные методы для обновления OngoingActivity , если вы хотите сохранить экземпляр, а не создавать его заново.
Если приложение работает в фоновом режиме, оно может отправлять обновления в API текущей активности. Однако не следует делать это слишком часто, поскольку метод обновления игнорирует вызовы, которые выполняются слишком близко друг к другу. Несколько обновлений в минуту — это разумная частота.
Для обновления текущей активности и отправленного уведомления используйте созданный ранее объект и вызовите update() , как показано в следующем примере:
ongoingActivity.update(context, newStatus)
Для удобства предусмотрен статический метод для создания постоянно обновляемой активности.
OngoingActivity.recoverOngoingActivity(context) ?.update(context, newStatus)
Остановить текущую деятельность
Когда приложение завершит свою работу в режиме непрерывной активности, ему останется только отменить текущее уведомление.
Вы также можете отменить уведомление или текущую активность, когда приложение переходит в активный режим, а затем воссоздать их при переходе в фоновый режим, но это необязательно.
Приостановить текущую деятельность
Если в вашем приложении есть явное действие остановки, продолжите текущую активность после возобновления работы. В приложении без явного действия остановки завершите активность после её приостановки.
Ключевые соображения
При работе с API текущих действий помните о следующих моментах:
Укажите статическую иконку для вашей текущей активности либо явно , либо в качестве запасного варианта с помощью уведомления . В противном случае вы получите исключение
IllegalArgumentException.Используйте черно-белые векторные иконки с прозрачным фоном.
Задайте намерение касания для текущей активности, либо явно , либо в качестве запасного варианта, используя уведомление . В противном случае вы получите исключение
IllegalArgumentException.Если в манифесте вашего приложения указано более одной активности
MAIN LAUNCHER, опубликуйте динамический ярлык и свяжите его с текущей активностью, используяLocusId.
Публиковать уведомления о воспроизведении медиафайлов на устройствах Wear OS
Если на устройстве Wear OS воспроизводится медиаконтент, отправьте уведомление о воспроизведении медиафайла . Это позволит системе создать соответствующее сообщение о текущей активности.
Если вы используете Media3, уведомление публикуется автоматически. Если вы создаете уведомление вручную, оно должно использовать MediaStyleNotificationHelper.MediaStyle , а соответствующая MediaSession должна содержать информацию о своей активности сессии .
Рекомендуем вам
- Примечание: текст ссылки отображается, когда JavaScript отключен.
- Создать уведомление {:#notification}
- Откройте для пользователей Wear OS новые возможности взаимодействия с помощью API текущей активности.
- Создайте расширяемое уведомление {:#expandable-notification}