Устройства 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: объект
PendingIntentиспользуемый для возврата к приложению, если пользователь коснется значка текущей активности. Отображается на циферблате часов или в панели запуска. Он может отличаться от исходного Intent, использованного для запуска приложения. Если не указан, используется Intent содержимого уведомления. Если ни один из них не задан, генерируется исключение.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}