Nuevas maneras de atraer usuarios de Wear OS con la API de Ongoing Activity

1. Introducción

a3457956a1735674.gif

Mira la animación anterior (demostración de actividad en curso). Nota: La animación de los GIF solo se reproduce una vez. Si te la perdiste, vuelve a cargar la página.

En la cara de reloj, aparecerá un ícono animado (para un temporizador) y, si el usuario lo presiona, se iniciará la app que está alimentando al temporizador.

Una actividad en curso es una función nueva de Wear OS que permite que aparezca una notificación en curso en las plataformas adicionales dentro de la interfaz de usuario de Wear OS, de modo que se pueda mantener más la interacción de los usuarios con las actividades de larga duración.

Por lo general, las notificaciones en curso se usan para indicar que una notificación tiene una tarea en segundo plano con la que el usuario interactúa de manera activa (por ejemplo, reproducir música) o está pendiente de alguna manera y, por lo tanto, ocupa el dispositivo (por ejemplo, la descarga de un archivo, una operación de sincronización o una conexión de red activa).

Por ejemplo, un usuario de Wear OS puede usar una app de temporizador para cronometrar un evento y, luego, salir de esa app a fin de iniciar otra tarea (consultar el pronóstico del clima, iniciar un entrenamiento, etc.).

Cuando el usuario salga de la app de temporizador, por lo general, la app hará una transición a una notificación en curso que está vinculada a algunas tareas en segundo plano (servicios, administradores de alarmas, etc.) para mantener informado al usuario sobre la cantidad de tiempo restante en el temporizador.

El usuario puede ver la notificación para actualizarse, así como interactuar.

Sin embargo, para ver la notificación, el usuario deberá deslizar el dedo en la bandeja de notificaciones que se encuentra debajo de la cara del reloj y buscar la notificación correcta, lo que no es tan práctico como otras plataformas.

Con la API de actividad en curso, una app puede mostrar información a varias plataformas nuevas y prácticas en Wear OS para mantener la interacción del usuario.

En el caso de la app de temporizador, la información puede aparecer en la cara del reloj del usuario como un ícono que se puede presionar (indicador de actividad en la parte inferior de la captura de pantalla):

b65ade9bf43c526e.png

Además, la app de temporizador puede aparecer en la sección Recientes del selector global de aplicaciones que enumera las actividades en curso:

1bc84dd2bd2d2b5d.png

Selector global

Lo mejor de todo es que solo debes agregar alrededor de 10 líneas de código para hacerlo.

Qué aprenderás

  • Crear y personalizar una actividad en curso
  • Vincular una actividad en curso a una notificación en curso
  • Probar una actividad en curso en un dispositivo o emulador
  • Agregar interacciones a tu actividad en curso (presionar)

Qué compilarás

Extenderás una app para el seguimiento de caminatas existente con una actividad en curso personalizada que muestre los puntos de caminata de una caminata activa en la cara principal del reloj y en la sección Recientes del selector de aplicaciones.

Requisitos previos

2. Cómo prepararte

En este paso, configurarás tu entorno y descargarás un proyecto inicial.

Qué necesitarás

  • Android Studio
  • Emulador de Wear OS (nivel de API 30 o superior)
  • Las actividades en curso solo están disponibles en el nivel de API 30 o posterior
  • ¿Es la primera vez que usa un emulador? (aquí te indicamos cómo configurarlo)

Cómo descargar el código

Si ya instalaste git, solo ejecuta el siguiente comando para clonar el código de este repositorio. Para comprobarlo, escribe git --version en la terminal o línea de comandos y verifica que se ejecute de forma correcta.

git clone https://github.com/android/codelab-ongoing-activity.git
cd ongoing-activity

Si no tienes git, puedes hacer clic en el siguiente botón para descargar todo el código de este codelab:

En cualquier momento, puedes ejecutar cualquiera de los módulos en Android Studio si realizas cambios en la configuración de ejecución en la barra de herramientas.

b059413b0cf9113a.png

Cómo abrir un proyecto en Android Studio

  1. En la ventana Welcome to Android Studio, selecciona Open.
  2. Selecciona la carpeta [Download Location].
  3. Cuando Android Studio haya importado el proyecto, prueba si puedes ejecutar los módulos start y finished en un emulador de Wear OS o un dispositivo físico.
  4. El módulo start debería verse como en la siguiente captura de pantalla. Aquí es donde realizarás todo el trabajo.

a40cc0c7e7e28bcf.png

Para probar la app, inicia una caminata de entrenamiento. Deberías notar que comienzas a ganar puntos cada 3 segundos aproximadamente. (La app utiliza datos ficticios, de modo que, en realidad, no es necesario caminar).

Prueba deslizar el dedo para salir de la app. Si navegas debajo de la cara del reloj a la bandeja de navegación, deberías poder encontrar la notificación en curso que continúa haciendo un seguimiento de tus puntos de caminata.

Cuando la presionas, se ve de la siguiente manera:

ac48b3ddc2a093bb.png

36fed11735ef4807.png

Puedes dejar de caminar.

Al final de este codelab, verás la misma información sobre la caminata en la cara del reloj y en la sección Recientes del selector global de aplicaciones.

App que aparece en la cara del reloj (consulta Indicador de actividad en la parte inferior):

59747518d70b053a.png

App que aparece en la sección Recientes del Selector de aplicaciones:

4817a55e6722629d.png

Cómo explorar el código de partida

En el módulo start:

  • build.gradle contiene la configuración básica de una app. Incluye las dependencias que se necesitan para crear una actividad en curso.
  • manifest > AndroidManifest.xml incluye las partes que se necesitan para marcar este archivo como una aplicación de Wear OS.
  • java > ... > data > WalkingWorkoutsRepository.kt se vincula a la clase WalkingWorkoutsDataStore.kt para almacenar los puntos de caminata y el estado de una caminata de entrenamiento. No te preocupes por los detalles; no necesitarás consultar estas clases para este codelab.
  • java > ... > MainApplication.kt crea un singleton del repositorio. No te preocupes por los detalles; no necesitarás consultar estas clases para este codelab.
  • java > ... > ForegroundOnlyWalkingWorkoutService.kt contiene código para iniciar y detener una caminata de entrenamiento. Si un entrenamiento está activo y el usuario sale de la app, se desvinculará de la actividad y se iniciará una notificación en curso para mantener informado al usuario sobre sus puntos de entrenamiento (mediante datos ficticios). En este paso, agregaremos nuestro código de actividad en curso (cerca del código de notificación).
  • java > ... > MainActivity.kt contiene una IU para que el usuario inicie o detenga una caminata de entrenamiento. La actividad se vincula al servicio anterior para que pueda controlar todas las tareas de entrenamiento.
  • java > ... > MainViewModel.kt es un elemento ViewModel simple que controla el código sin IU en MainActivity.kt. No te preocupes por los detalles; no necesitarás consultar estas clases para este codelab.

3. Cómo consultar la app

Esta app ya es una app para caminatas de entrenamiento que funciona.

Como se observó en los pasos anteriores, puedes iniciar la app y comenzar o detener una caminata de entrenamiento. A medida que transcurre el tiempo durante un entrenamiento activo, acumulas puntos de caminata.

En cada nueva caminata, los puntos se restablecen.

Si sales de la app durante un entrenamiento activo, puedes deslizar el dedo hacia abajo para ver una notificación en curso que continúa manteniéndote actualizado sobre tu progreso.

Desde esa notificación, puedes detener el entrenamiento o abrir la app.

En general, calcularías los puntos de caminata a partir de los datos de la ubicación y del sensor con un algoritmo patentado. En nuestro caso, solo simulamos los datos para simplificar el procedimiento.

¿Cómo funciona?

El elemento MainActivity crea la interfaz de usuario, se vincula a un objeto ViewModel para actualizar el estado del entrenamiento o los puntos de caminata, y se vincula a un servicio.

Cuando se inicia o se detiene un entrenamiento, el elemento MainActivity llama a un método equivalente para iniciar o detener en el servicio a fin de controlar la tarea pesada de hacer un seguimiento del entrenamiento.

Si el usuario sale, el elemento MainActivity solo se desvincula del servicio.

La mayor parte de la magia sucede en ForegroundOnlyWalkingWorkoutService. Esta es la clase que inicia o detiene los entrenamientos y guarda los cambios del estado o los puntos de caminata en el repositorio.

El servicio también hace una transición a un servicio en primer plano y se vincula asimismo a una notificación en curso si el usuario sale del elemento MainActivity durante una sesión.

La notificación en curso continúa con la tarea de hacer el seguimiento del entrenamiento y está vinculada al servicio anterior como servicio en primer plano.

No te preocupes si no comprendes todos los detalles. Lo importante es comprender que es una app que funciona con su notificación ya compilada. Solo deseamos extender esta notificación para que se pueda ver en más plataformas con una actividad en curso.

Ese código de notificación se encuentra en el elemento ForegroundOnlyWalkingWorkoutService, y es allí donde realizas todo el trabajo para este codelab.

4. Cómo crear una actividad en curso

Cómo consultar las dependencias

En este paso, no codificaremos. En cambio, consultaremos las dependencias de la actividad en curso.

Abre el archivo app/build.gradle en el módulo start y busca "TODO: Review dependencies for Ongoing Activity".

Deberías ver lo siguiente:

Paso 1

    // TODO: Review dependencies for Ongoing Activity.
    implementation libs.androidx.wear.ongoing
    // Includes LocusIdCompat and new Notification categories for Ongoing Activity.
    implementation libs.androidx.core.ktx

La primera dependencia es obligatoria para usar la API de actividad en curso de Wear OS.

La segunda dependencia es para obtener las últimas funciones de las API de notificación que admiten varias funciones que se usan junto con una actividad en curso. Las siguientes dos funciones pueden aplicarse a las notificaciones en curso y, por lo tanto, también se pueden aplicar a las actividades en curso:

  • Category: Android usa algunas categorías predefinidas para todo el sistema a fin de determinar si es necesario molestar al usuario con una notificación determinada cuando este habilitó el modo No interrumpir. La función Category determina la prioridad de la actividad en curso en la cara del reloj. Hace poco, se agregaron categorías nuevas para admitir Wear.
  • LocusId: Locus es un concepto nuevo que se introdujo en Android 10 (nivel de API 29) y permite que el sistema Android correlacione el estado entre subsistemas diferentes, como la captura de contenido, accesos directos y notificaciones. Si tienes varios selectores, puedes usar la función LocusId para vincular tu actividad en curso a un elemento dinámico Shortcut específico, de modo que aparezca, de manera correcta, en la sección Recientes del selector de aplicaciones.

Cómo consultar el código de la notificación en curso

En este paso, no codificaremos. En cambio, solo consultaremos el código de la notificación.

Abre el archivo ForegroundOnlyWalkingWorkoutService.kt en el módulo start y busca "TODO: Review Notification builder code".

Deberías ver lo siguiente:

Paso 2

// TODO: Review Notification builder code.
val notificationBuilder = notificationCompatBuilder
    .setStyle(bigTextStyle)
    .setContentTitle(titleText)
    .setContentText(mainText)
    .setSmallIcon(R.mipmap.ic_launcher)
    .setDefaults(NotificationCompat.DEFAULT_ALL)
    // Makes Notification an Ongoing Notification (a Notification with a background task).
    .setOngoing(true)
    // Android uses some pre-defined system-wide categories to determine whether to
    // disturb the user with a given notification when the user has enabled Do Not Disturb
    // mode. The Category determines the priority of the Ongoing Activity and new
    // categories were added recently to support Wear
    .setCategory(NotificationCompat.CATEGORY_WORKOUT)
    .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
    .addAction(
        R.drawable.ic_walk, getString(R.string.launch_activity),
        activityPendingIntent
    )
    .addAction(
        R.drawable.ic_cancel,
        getString(R.string.stop_walking_workout_notification_text),
        servicePendingIntent
    )

// TODO: Create an Ongoing Activity.
// SKIP TODO FOR REVIEW STEP

return notificationBuilder.build()

Consulta el código anterior y lee los comentarios (omite la sección TODO posterior, que es para un paso que realizarás más adelante).

Encontrarás mucho más código de notificación arriba de este fragmento que prepara todo para este compilador.

Sin embargo, para este codelab, solo necesitamos enfocarnos en la llamada setOngoing() y setCategory(), en el compilador de notificaciones.

La función Category permite que Wear OS determine la prioridad de la notificación para la cara del reloj.

La llamada setOngoing() convierte nuestra notificación en una notificación en curso; es decir, una notificación con una tarea en segundo plano con la que el usuario interactúa de manera activa, por ejemplo, hacer el seguimiento de una caminata de entrenamiento.

Creamos esta notificación cuando el usuario tiene una caminata de entrenamiento activa y sale del elemento MainActivity.

Cómo crear una actividad en curso

Una actividad en curso debe estar vinculada a una notificación en curso. Como tenemos nuestra notificación en curso, ahora, crearemos una actividad en curso.

Busca "TODO: Create an Ongoing Activity" y reemplaza la línea "// SKIP TODO FOR REVIEW STEP" por el siguiente código.

Paso 4

// TODO: Create an Ongoing Activity.
val ongoingActivityStatus = Status.Builder()
    // Sets the text used across various surfaces.
    .addTemplate(mainText)
    .build()

val ongoingActivity =
    OngoingActivity.Builder(applicationContext, NOTIFICATION_ID, notificationBuilder)
        // Sets icon that will appear on the watch face in active mode. If it isn't set,
        // the watch face will use the static icon in active mode.
        .setAnimatedIcon(R.drawable.animated_walk)
        // Sets the icon that will appear on the watch face in ambient mode.
        // Falls back to Notification's smallIcon if not set. If neither is set,
        // an Exception is thrown.
        .setStaticIcon(R.drawable.ic_walk)
        // Sets the tap/touch event, so users can re-enter your app from the
        // other surfaces.
        // Falls back to Notification's contentIntent if not set. If neither is set,
        // an Exception is thrown.
        .setTouchIntent(activityPendingIntent)
        // In our case, sets the text used for the Ongoing Activity (more options are
        // available for timers and stop watches).
        .setStatus(ongoingActivityStatus)
        .build()

// Applies any Ongoing Activity updates to the notification builder.
// This method should always be called right before you build your notification,
// since an Ongoing Activity doesn't hold references to the context.
ongoingActivity.apply(applicationContext)

Antes de crear una actividad en curso, primero, crea una actividad en curso Status que incluya el texto que aparecerá en las distintas plataformas de Wear OS.

Configuramos el texto con .addTemplate() en el elemento Status.Builder, en el mismo texto principal que usamos para nuestra notificación.

En realidad, puedes personalizar el aspecto del texto (especificar colores, negrita, etc.), pero, para este codelab, lo simplificamos. Sin embargo, si deseas obtener más información, consulta la guía de actividades en curso.

A continuación, crearemos el mismo elemento OngoingActivity. Pasamos el contexto, un ID de notificación y el compilador de notificaciones que creamos arriba de este código al constructor de OngoingActivity.Builder().

El ID de notificación y la instancia NotificationCompat.Builder son importantes para vincular el elemento OngoingActivity a la notificación en curso.

Primero, configuramos un ícono animado (para la cara de reloj en modo activo) y un ícono estático (para la cara de reloj en modo ambiente).

Luego, configuramos un evento táctil y, finalmente, el texto con el objeto Status que creamos antes de cerrar la sentencia con .build().

La interfaz de usuario OngoingActivity se brinda con el ícono y el texto de Status. El evento táctil le permite al usuario presionar y volver a la app desde la cara del reloj o la sección Recientes del selector global de aplicaciones.

Por último, llamamos a apply() en la actividad en curso y pasamos el contexto. Este es el último paso que aplica cualquier cambio en la actividad en curso al compilador de notificaciones.

Eso es todo. ¡Ya terminamos!

Cuando se llame al elemento notificationManager.notify(NOTIFICATION_ID, notification) con esta notificación, ahora aparecerá en las plataformas nuevas.

Ahora, ejecuta tu app en el nuevo emulador o dispositivo Wear OS.

Inicia una caminata desde la app y desliza el dedo para salir de esta.

En la cara de reloj, deberías ver un ícono pequeño de una persona caminando como el siguiente (pero animado):

59747518d70b053a.png

Si lo presionas, volverás a la app.

Vuelve a salir de la app y presiona el botón del selector de aplicaciones en tu dispositivo Wear OS.

Deberías ver algo similar a lo siguiente:

4817a55e6722629d.png

Si haces clic en la app de caminata en la sección Recientes, deberías volver a entrar a la app.

5. Felicitaciones

¡Felicitaciones! Aprendiste a compilar una actividad en curso en Wear OS.

Las actividades en curso son una manera excelente de atraer a los usuarios a las nuevas plataformas de Wear.

¿Qué sigue?

Consulta los otros codelabs de Wear OS:

Lecturas adicionales