Students Save 30%! Learn & create with unlimited courses & creative assets Students Save 30%! Save Now
Advertisement
  1. Code
  2. Android Wear
Code

Creando una watch face (carátula) para Android Wear

by
Difficulty:BeginnerLength:LongLanguages:

Spanish (Español) translation by Javier Salesi (you can also view the original English article)

Una de las características que hace a Android tan especial es la posibilidad de personalizar cada aspecto de la experiencia del usuario. Cuando Android Wear fue lanzado por primera vez en Google I/O 2014, muchos desarrolladores y usuarios encontraron que ésto no era exactamente una verdad para los relojes inteligentes, pues hacía falta la API oficial para crear watch faces. Dada la capacidad para elaborar watch faces personalizadas una de las claves requeridas por usuarios, no es sorprendente que los desarrolladores descubrieron una formar de crear sus propias watch faces con un método no documentado en Android Wear.

Por suerte, Google rápidamente comunicó a todos que una API oficial estaba en camino y en Diciembre de 2014 esa API fue lanzada finalmente a la comunidad de desarrollo.  En éste artículo, vas a aprender sobre la API oficial de Watch Faces para Android Wear e implementar una sencilla watch face que podrás expandir para tus propias necesidades. Implementar watch faces puede ser muy extenso para explicar, pero puedes encontrar la aplicación de ejemplo para éste artículo en Github.

1. Configurando tu IDE

Lo primero que vas a necesitar hacer para hacer tu propia watch face es configurar tu proyecto en Android Studio. Cuando creas tu proyecto, selecciona Phone and Table con un Minimum SDK de API 18 pues Android 4.3 es la versión más baja del sistema operativo para apoyar aplicaciones empaquetadas en Android Wear. También necesitarás marcar  la casilla Wear con un Minimum SDK de API 21 seleccionado.  Puedes ver un ejemplo de como ser verá tu pantalla Target Android Devices.

Cuando llegas a las dos pantallas Add an Activity, selecciona Add No Activity para ambas pantallas.

Una vez que hagas click en Finish, tu entorno de proyecto debería crear y tener un modulo para mobile y otro para wear.

2. Creando el  Wear Watch Service

Android Wear implementa watch faces a través del uso de WatchFaceService. En éste artículo, vas a crear una extensión de la clase CanvasWatchFaceService, que es un implementación de WatchFaceService que también proporciona un Canvas para dibujar tu watch face. Comienza por crear una nueva clase Java bajo el módulo wear en Android Studio que extienda de CanvasWatchFaceService.

Una vez que tienes tu clase, vas a necesitar crear una clase interna, WatchFaceEngine en los archivos fuente de éste artículo, que extiende de Engine. Éste es el motor de la watch face que maneja eventos del sistema, tal como apagado de la pantalla o pasar a modo ambiente.

Cuando tu código base para WatchFaceEngine está elaborado, regresa a la clase externa y aplica el modificador override en el método onCreateEngine para regresar tu nueva clase interna. Ésto asociará tu watch face service con el código que generará el display (la vista).

Una vez que tengas la estructura básica, puedes avanzar a las tareas generales habituales de actualizar tus archivos AndroidManifest para que tu servicio sea localizable por Android Wear. Ten en cuenta que tu código actual todavía no hará nada. Regresaremos a ésta clase y daremos cuerpo al motor después de hacer alguna tarea general del proyecto.

3. Actualizando los archivos AndroidManifest.

Abre el archivo AndroidManifest.xml en el módulo wear.  Cerca de la parte superior ya deberías ver una linea con la leyenda:

Debajo de la línea, necesitamos añadir los dos permisos requeridos para una watch face. Éstos requerimientos son:

Una vez que se establecen tus permisos, necesitarás añadir un nodo para tu servicio en el nodo application con permiso para BIND_WALLPAPER, unos cuantos meta-data que contienen referencias a imágenes de tu watch face para la pantalla de selección (en éste ejemplo estamos usando el ícono del lanzador), y un intent-filter para dejar al sistema saber que tu servicio esta destinado a mostrar una watch face.

Una vez que tu manifiesto wear está completo, necesitarás abrir el archivo AndroidManifest.xml en el módulo mobile y añadir los dos permisos que usamos en el módulo wear para PROVIDE_BACKGROUND y WAKE_LOCK, porque Android Wear requiere que tanto el módulo wear como el módulo mobile requieran los mismos permisos para que el APK de wear sea instalado en el reloj de un usuario. Una vez que estén llenos los dos archivos manifiesto, puedes regresar a CustomWatchFaceService.java para comenzar a implementar el motor.

4. Comienza Tu Engine (Motor)

El objeto Engine asociado con tu servicio es lo que genera tu watch face. Maneja timers (temporizadores), mostrando tu interfaz de usuario, entrando y saliendo de modo ambiente, y obteniendo información sobre el display del reloj físico. En resumen, aquí es donde ocurre la magia.

Paso 1: Definiendo Valores y Variables Necesarias

Lo primero que vas a querer hacer es implementar una serie de variables miembros en tu motor para mantener un seguimiento de los estados del dispositivo, intervalos de timer, y atributos para tu display.

Como puedes ver, definimos el TypeFace que usaremos para nuestro texto del reloj así como el color de fondo del watch face y el color del texto. El objeto Time es usado para, adivinaste, mantener seguimiento de la hora actual del dispositivo. mUpdateRateMs es usado para controlar un timer que necesitaremos implementar para actualizar nuestra watch face cada segundo (por tanto el valor de 1000 milisegundo para mUpdateRateMs), porque el estándar WatchFaceService sólo mantiene seguimiento del tiempo en incrementos de un minuto. mXOffset y mYOffset son definidos una vez que el motor sabe la forma física del reloj para que nuestra watch face pueda ser dibujada sin estar demasiado cerca de la parte superior o del extremo izquierdo de la pantalla, o sea cortada por una esquina redondeada. Los tres valores booleanos son usados para mantener seguimiento de diferentes estados del dispositivo y la aplicación.

El próximo objeto que necesitarás definir es un receptor de transmisión que maneja la situación donde un usuario puede estar viajando y cambian los husos horarios. Éste receptor simplemente borra el huso horario guardado y resetea o restablece el display del tiempo.

Después de que es definido tu receptor, el objeto final que necesitarás crear arriba de tu motor es un Handler que se encarga de actualizar tu watch face cada segundo. Ésto es necesario por las limitaciones de WatchFaceService discutidas previamente. Si tu propia watch face sólo necesita ser actualizado cada minuto, entonces con toda seguridad puedes ignorar ésta sección.

La implementación del Handler es muy sencilla. Primero revisa el ID del message (mensaje). Si coincide con MSG_UPDATE_TIME_ID, continúa para invalidar la vista actual para rediseñar. Después de que la vista ha sido invalidada, el Handler revisa si la pantalla está visible y no en modo ambiente. Si es visible, envía una reiterada petición un segundo más tarde. El motivo de que sólo estamos repitiendo la acción en el Handler cuando la watch face es visible y no en modo ambiente es que puede generar mucho consumo de batería al estar actualizando cada segundo. Si el usuario no está viendo la pantalla, simplemente nos apoyamos en la implementación del WatchFaceService que actualiza cada minuto.

Paso 2: Inicializando el Motor

Ahora que tus variables y objetos están declarados, es tiempo de comenzar a inicializar la watch face. Engine tiene un método onCreate que debe ser usado para crear objetos y otras tareas que pueden tomar una cantidad significante de tiempo y consumo de batería. También querrás establecer unas flags (opciones) para que WatchFaceStyle controle cómo interactúa el sistema con el usuario cuando tu watch face está activa.

Para la aplicación de ejemplo, usarás setWatchFaceStyle para establecer el fondo de tus tarjetas de notificación para que muestren brevemente si el tipo de tarjeta se establece en interruptiva. También establecerás el modo peek para que las tarjetas de notificación sólo tomen el espacio necesario.

Finalmente, querrás decir al sistema que no muestre el tiempo por defecto ya que lo estarás mostrando tu mismo. Mientras éstas son sólo unas pocas opciones disponibles, puedes encontrar más información en la documentación oficial para el objeto WatchFaceStyle.Builder.

Después de que ha sido establecido tu WatchFaceStyle, puedes inicializar mDisplayTime como un nuevo objeto Time.

initBackground y initDisplayText asignan los dos objetos Paint que definiste arriba del motor. El fondo y el texto tienen su color definido y el texto tiene su tipografía y tamaño de fuente establecidos, mientras que también activa el anti-aliasing (suavizado de los bordes).

Paso 3: Manejando el Estado del Dispositivo

Posteriormente, necesitas implementar varios métodos de la clase Engine que son  provocados por cambios en el estado del dispositivo. Comenzaremos por ir al método onVisibilityChanged, que es llamado cuando el usuario oculta o muestra la watch face.

Cuándo éste método es llamado, revisa si la watch face está visible o no. Si la watch face está visible, revisa si el BroadcastReceiver que definiste arriba del Engine está registrado. Si no, el método crea un IntentFilter para la acción ACTION_TIMEZONE_CHANGED y registra el BroadcastReceiver para escucharlo.

Si la watch face no está visible, éste método revisará si el BroadcastReceiver puede estar no registrado. Una vez que el BroadcastReceiver ha sido manejado, updateTimer es llamado para desencadenar la no validación de la watch face y volver a dibujar la watch face. updateTimer detiene cualquier acción Handler que esté pendiente y revisa si otra debería ser enviada.

Paso 4: Cooperando con el Hardware Wearable (de dispositivos de la tecnología del vestir)

Cuando tu servicio es asociado con Android Wear, sólo onApplyWindowInsets es llamado. Éste es usado para determinar si el dispositivo en el que se ejecuta tu watch face es redondo o cuadrado. Ésto te permite cambiar tu watch face para que coincida con el hardware.

Cuando éste método es llamado en la aplicación de ejemplo, éste método revisa la forma del dispositivo y cambia la posición-x offset  usada para diseñar el watch face para asegurarse que tu watch face está visible en el dispositivo. 

El próximo método que necesitarás aplicar el modificador override es onPropertiesChanged. Éste método es llamado cuando las propiedades del hardware para el dispositivo Wear son determinadas, por ejemplo, si el dispositivo apoya protección contra el efecto fantasma o modo ambiente con el brillo disminuido.

En éste método, revisas si esos atributos aplican al dispositivo que ejecuta tu watch face y los guarda en una variable miembro definida arriba de tu Engine.

Paso 5: Conservando la Batería en Modos Ambiente y Silencio.

Después de que manejas los estados iniciales del dispositivo, querrás implementar onAmbientModeChanged y onInterruptionFilterChanged. Como el nombre implica, onAmbientModeChanged es llamado cuando el dispositivo ingresa o sale de un modo ambiente.

Si el dispositivo está en modo ambiente, querrás cambiar el color de tu watch face a blanco y negro para disminuir el consumo de la batería del usuario. Cuando el dispositivo está regresando de modo ambiente, puedes resetear los colores de tu watch face. También querrás estar consciente de anti-aliasing para dispositivos que requieren soporte para modo ambiente con brillo disminuído . Después de definirse todas las variables, puedes causar que se invalide la watch face y rediseñarla, y luego revisar si debería iniciar el timer de un segundo.


onInterruptionFilterChanged es llamado cuando el usuario cambia manualmente la configuración de interrupción en su dispositivo de la tecnología del vestir. Cuando ésto ocurre, necesitarás revisar si el dispositivo está silenciado y luego alterar la interfaz de usuario consecuentemente. En ésta situación, cambiarás la transparencia de tu watch face, establecer tu Handler a sólo actualizar cada minuto si el dispositivo esta en modo silencio, y entonces volver a dibujar tu watch face.

Cuando tu dispositivo está en modo ambiente, el timer Handler será deshabilitado. Tu watch face puede aún actualizarse con la hora actual cada minuto al usar el método integrado onTimeTick para invalidar el Canvas.

Paso 6: Diseñando la Watch Face

Una vez que están cubiertas todas tus contingencias, es momento de diseñar finalmente tu watch face. CanvasWatchFaceService usa un objeto estándar Canvas, así que necesitarás añadir onDraw a tu Engine y diseñar manualmente tu watch face. 

En éste tutorial simplemente vas a diseñar una representación textual del tiempo, aunque podrías cambiar tu onDraw para soportar fácilmente una watch face análoga.  En éste método, querrás verificar que estás mostrando la hora correcta al actualizar tu objeto Time y luego puedes comenzar a aplicar tu watch face.

drawBackground aplica un color sólido al fondo del dispositivo Wear.

drawTimeText, sin embargo, crea la hora textual que será mostrada con la ayuda de un par de métodos auxiliares y luego la aplica al canvas en los puntos x y y que definiste en onApplyWindowInsets.

Conclusión

Una vez que has implementado los métodos para diseñar tu watch face, deberías tener todo el conocimiento básico para elaborar tus propias watch faces. Lo agradable de las watch faces de Android Wear es que apenas es una insinuación de lo que es posible.

Puedes añadir actividades paralelas en la configuración en el reloj o en el teléfono, remplazar la watch face basada en Canvas con una implementación OpenGL, o derivar tu propia clase desde WatchFaceService para satisfacer tus necesidades. 

Agrega a ello que puedes accesar a otras APIs o información desde el teléfono del usuario y las posibilidades parecen infinitas. Echa a volar tu creatividad con tus watch faces y disfruta.

¡Sé el primero en conocer las nuevas traducciones–sigue @tutsplus_es en Twitter!

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.