Устройства Wear OS часто используются для длительных действий, например отслеживания тренировок. Кроме того, в них может содержаться важная информация, к которой пользователю нужен быстрый доступ.
Это создает проблему для пользователей: если они начали выполнять задачу, а затем перешли на циферблат, они должны иметь возможность:
- Продолжать получать важные обновления.
- Чтобы вернуться к задаче, достаточно одного нажатия.
Возвращаться в приложение через панель запуска может быть неудобно, особенно на ходу.
В Wear OS 7 и более поздних версий для этого нужно связать текущее уведомление с OngoingActivity или уведомлением о текущих изменениях. Это позволяет устройству показывать информацию о длительном действии в интерфейсе, например значок в нижней части циферблата. Этот индикатор позволяет пользователям знать о фоновой задаче и одним нажатием вернуться в приложение.
Текущая активность или уведомления в реальном времени также дольше сохраняют видимость вашего приложения, предотвращая возврат системы к циферблату после периода бездействия. Подробнее о том, как сделать приложение заметным на устройствах Wear…
Используйте уведомление о текущей активности или Live Update, если действие, скорее всего, займет больше минуты или если пользователь, вероятно, покинет приложение до завершения задачи.
Примеры использования. Отслеживание тренировок, таймеры, отслеживание поездок в такси, запись голоса (например, на совещании), списки покупок, которые должны быть доступны в магазине.
Недопустимое использование: запись коротких голосовых сообщений, реклама, статус обновления приложения и предстоящие мероприятия в календаре.
Важно! Использование
OngoingActivityили динамического обновления в этих сценариях является обязательным в соответствии с рекомендациями по обеспечению качества приложений для Wear OS (WO-V4).
Например, в приложении для тренировок информация может показываться на циферблате в виде значка бега, на который можно нажать:
Рисунок 1. Индикатор активности.
Текущее уведомление также показывает информацию в разделе Недавние глобального запуска приложений. Это ещё одно удобное место, где пользователи могут посмотреть статус задачи и вернуться к приложению:
Рисунок 2. Глобальный запуск.
Текущее уведомление, связанное с текущей активностью, рекомендуется использовать в следующих случаях:
Рисунок 3. Таймер ведет обратный отсчет времени и останавливается, когда вы приостанавливаете или останавливаете его.
Рисунок 4. Пошаговая навигация. Озвучивает инструкции для достижения пункта назначения. Завершается, когда пользователь достигает пункта назначения или останавливает навигацию.
Рисунок 5. Мультимедиа. Воспроизводит музыку во время сеанса. Завершается сразу после того, как пользователь приостановит сеанс.
Wear автоматически создает для медиаприложений постоянные действия.
Подробный пример создания объектов Ongoing Activity для других типов приложений приведен в практической работе по созданию объектов Ongoing Activity.
Настроить
Чтобы начать использовать Ongoing Activity API в приложении, добавьте следующие зависимости в файл build.gradle приложения:
dependencies {
implementation "androidx.wear:wear-ongoing:1.1.0"
implementation "androidx.core:core:1.19.1"
}
Как создать постоянное действие
Процесс состоит из трех этапов:
- Создайте стандартный объект
NotificationCompat.Builderи настройте его как постоянный. - Создайте и настройте объект
OngoingActivity, передав ему конструктор уведомлений. - Примените Ongoing Activity к конструктору уведомлений и опубликуйте полученное уведомление.
Как создать и настроить уведомление
Начните с создания 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, используя его конструктор. Для OngoingActivity.Builder требуется Context, идентификатор уведомления и NotificationCompat.Builder, созданный на предыдущем шаге.
Настройте свойства ключа, которые будут отображаться в новом интерфейсе:
- Анимированные и статичные значки. Предоставьте значки, которые будут показываться на циферблате в активном и фоновом режимах.
- Намерение прикосновения.
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, вы можете настроить уведомления и текущие действия следующими способами: Однако в зависимости от реализации OEM-производителя эти настройки могут не использоваться.
Постоянное уведомление
- Категория определяет приоритет текущего действия.
CATEGORY_CALL– входящий голосовой или видеозвонок или аналогичный запрос на синхронную коммуникацию.CATEGORY_NAVIGATION– карта или пошаговая навигация.CATEGORY_TRANSPORT: управление воспроизведением медиаконтента.CATEGORY_ALARM– будильник или таймер.CATEGORY_WORKOUT: тренировкаCATEGORY_LOCATION_SHARING– категория временного доступа к местоположению.CATEGORY_STOPWATCH: секундомер
Текущие действия
Анимированный значок – черно-белый векторный объект, желательно на прозрачном фоне. Отображается на циферблате в активном режиме. Если анимированный значок не указан, используется значок уведомления по умолчанию. Значок уведомления по умолчанию для каждого приложения будет различаться.
Статический значок: векторный значок с прозрачным фоном. Отображается на циферблате в спящем режиме. Если анимированный значок не задан, в активном режиме на циферблате будет использоваться статический значок. Если не указано, используется значок уведомления. Если ни один из них не задан, будет выдано исключение. (В панели запуска приложений по-прежнему используется значок приложения.)
OngoingActivityStatus: обычный текст или
Chronometer. Отображается в разделе Недавние на панели запуска приложений. Если не указано, используется текст уведомления "context text".Намерение прикосновения –
PendingIntent, используемый для возврата в приложение, если пользователь нажмет на значок текущего действия. Отображается на циферблате или в элементе запуска. Он может отличаться от исходного намерения, использованного для запуска приложения. Если он не указан, используется намерение контента уведомления. Если не задано ни одно из этих значений, будет выдано исключение.LocusId: идентификатор, который назначает ярлык запуска, соответствующий текущей активности. Показывается в разделе Недавние на главном экране, пока выполняется действие. Если не указан, то в разделе Недавние будут скрыты все элементы приложений из того же пакета и показаны только активные действия.Идентификатор текущей активности. Идентификатор, используемый для различения вызовов
fromExistingOngoingActivity(), когда у приложения несколько текущих активностей.
Как обновить данные в Live Activity
Если вам нужно изменить статус, обновите Ongoing Activity для существующего уведомления, а не создавайте новое уведомление и Ongoing Activity. Чтобы обновить объект Ongoing Activity и опубликованное уведомление, используйте созданный ранее объект и вызовите метод update(), как показано в следующем примере:
ongoingActivity.update(context, newStatus)
Если сохранить ссылку на OngoingActivity невозможно, можно воспользоваться статическим методом для восстановления OngoingActivity. Однако этот вариант менее предпочтителен:
OngoingActivity.recoverOngoingActivity(context) ?.update(context, newStatus)
Как остановить текущее действие
Когда приложение завершает работу в качестве текущего действия, ему нужно только отменить текущее уведомление.
Вы также можете отменить уведомление или текущее действие, когда оно переходит на передний план, а затем воссоздать их, когда оно снова переходит на задний план, но это не обязательно.
Как приостановить текущее действие
Если в приложении есть явное действие остановки, после возобновления приостановленной активности продолжайте ее. Если в приложении нет явного действия для остановки, завершите активность, когда она будет приостановлена.
На что обратить внимание
При работе с Ongoing Activity API учитывайте следующее:
Установите статический значок для текущей активности в явном виде или в качестве резервного варианта с помощью уведомления. В противном случае вы получите ошибку
IllegalArgumentException.Используйте черно-белые векторные значки с прозрачным фоном.
Задайте намерение для нажатия на активное действие: явным образом или в качестве резервного варианта с помощью уведомления. В противном случае вы получите ошибку
IllegalArgumentException.Если в манифесте приложения объявлено несколько действий
MAIN LAUNCHER, опубликуйте динамический ярлык и свяжите его с текущим действием с помощьюLocusId.
Как публиковать уведомления о мультимедиа при воспроизведении контента на устройствах Wear OS
Если на устройстве Wear OS воспроизводится медиаконтент, опубликуйте уведомление о медиаконтенте. Это позволяет системе создать соответствующее текущее действие.
Если вы используете Media3, уведомление публикуется автоматически. Если вы создаете уведомление вручную, оно должно использовать MediaStyleNotificationHelper.MediaStyle, а соответствующий MediaSession должен содержать данные о действиях в сеансе.
Рекомендуем
- Примечание. Текст ссылки показывается, когда JavaScript отключен.
- Как создать уведомление {:#notification}
- Использование Ongoing Activity API для расширенного взаимодействия с пользователями Wear OS
- Как создать разворачиваемое уведомление {:#expandable-notification}