Текущая деятельность

Устройства 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"
}

Создайте постоянно обновляемую активность

Процесс состоит из трех этапов:

  1. Создайте стандартный объект NotificationCompat.Builder и настройте его как постоянно обновляемый.
  2. Создайте и настройте объект OngoingActivity , передав ему построитель уведомлений.
  3. Примените текущую активность к конструктору уведомлений и отправьте полученное уведомление.

Создайте и настройте уведомление.

Начните с создания объекта 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 должна содержать информацию о своей активности сессии .

{% verbatim %} {% endverbatim %} {% verbatim %} {% endverbatim %}