Como criar um mostrador de relógio
Este guia explica como implementar um serviço de mostrador de relógio personalizado para Android Wear 1.0. Instruções passo a passo são fornecidas para a criação de um serviço de mostrador de relógio digital despojado, seguido de mais código para criar um mostrador de relógio de estilo analógico.
Visão geral
Neste passo a passo, um serviço básico de mostrador de relógio é criado para ilustrar os fundamentos da criação de um mostrador de relógio Android Wear 1.0 personalizado. O serviço de mostrador inicial exibe um relógio digital simples que exibe a hora atual em horas e minutos:
Depois que este mostrador de relógio digital é desenvolvido e testado, mais código é adicionado para atualizá-lo para um mostrador de relógio analógico mais sofisticado com três mãos:
Os serviços de face do relógio são agrupados e instalados como parte de um aplicativo Wear 1.0. Nos exemplos a seguir, MainActivity
contém nada mais do que o código do modelo de aplicativo Wear 1.0 para que o serviço de mostrador do relógio possa ser empacotado e implantado no relógio inteligente como parte do aplicativo. Na verdade, este aplicativo servirá puramente como um veículo para obter o serviço de mostrador do relógio carregado no dispositivo Wear 1.0 (ou emulador) para depuração e teste.
Requisitos
Para implementar um serviço de mostrador de relógio, é necessário o seguinte:
Android 5.0 (API nível 21) ou superior no dispositivo ou emulador Wear.
As bibliotecas de suporte do Xamarin Android Wear devem ser adicionadas ao projeto Xamarin.Android.
Embora o Android 5.0 seja o nível mínimo de API para implementar um serviço de mostrador de relógio, o Android 5.1 ou posterior é recomendado. Os dispositivos Android Wear com Android 5.1 (API 22) ou superior permitem que os aplicativos Wear controlem o que é exibido na tela enquanto o dispositivo está no modo ambiente de baixo consumo de energia. Quando o dispositivo sai do modo ambiente de baixo consumo de energia, ele está no modo interativo. Para obter mais informações sobre esses modos, consulte Mantendo seu aplicativo visível.
Iniciar um projeto de aplicativo
Crie um novo projeto Android Wear 1.0 chamado WatchFace (para obter mais informações sobre como criar novos projetos Xamarin.Android, consulte Olá, Android):
Defina o nome do pacote como com.xamarin.watchface
:
Além disso, role para baixo e habilite as permissões INTERNET e WAKE_LOCK :
Em seguida, baixe preview.png – isso será adicionado à pasta drawables mais adiante neste passo a passo.
Adicionar o pacote Xamarin.Android Wear
Inicie o Gerenciador de Pacotes NuGet (no Visual Studio, clique com o botão direito do mouse em Referências no Gerenciador de Soluções e selecione Gerenciar Pacotes NuGet...). Atualize o projeto para a versão estável mais recente do Xamarin.Android.Wear:
Em seguida, se Xamarin.Android.Support.v13 estiver instalado, desinstale-o:
Crie e execute o aplicativo em um dispositivo ou emulador Wear (para obter mais informações sobre como fazer isso, consulte o Guia de Introdução ). Você deve ver a seguinte tela do aplicativo no dispositivo Wear:
Neste ponto, o aplicativo Wear básico não tem a funcionalidade de mostrador de relógio porque ainda não fornece uma implementação de serviço de mostrador de relógio. Este serviço será adicionado em seguida.
CanvasWatchFaceService
O Android Wear implementa mostradores de relógio através da CanvasWatchFaceService
classe. CanvasWatchFaceService
é derivado de , que é derivado de WatchFaceService
WallpaperService
como mostrado no diagrama a seguir:
CanvasWatchFaceService
inclui um aninhado CanvasWatchFaceService.Engine
; ele instancia um CanvasWatchFaceService.Engine
objeto que faz o trabalho real de desenhar o mostrador do relógio. CanvasWatchFaceService.Engine
é derivado de WallpaperService.Engine
como mostrado no diagrama acima.
Não mostrado neste diagrama é um Canvas
que CanvasWatchFaceService
usa para desenhar o mostrador do relógio - isso Canvas
é passado através do OnDraw
método como descrito abaixo.
Nas seções a seguir, um serviço de mostrador de relógio personalizado será criado seguindo estas etapas:
Defina uma classe chamada
MyWatchFaceService
que é derivada deCanvasWatchFaceService
.Dentro
MyWatchFaceService
do , crie uma classe aninhada chamadaMyWatchFaceEngine
que é derivada deCanvasWatchFaceService.Engine
.No
MyWatchFaceService
, implemente umCreateEngine
método que instanciaMyWatchFaceEngine
e o retorna.No
MyWatchFaceEngine
, implemente oOnCreate
método para criar o estilo do mostrador do relógio e executar quaisquer outras tarefas de inicialização.Implemente o
OnDraw
método deMyWatchFaceEngine
. Esse método é chamado sempre que o mostrador do relógio precisa ser redesenhado (ou seja, invalidado).OnDraw
é o método que desenha (e redefine) elementos do mostrador do relógio, como hora, minuto e segundos ponteiros.Implemente o
OnTimeTick
método deMyWatchFaceEngine
.OnTimeTick
é chamado pelo menos uma vez por minuto (nos modos ambiente e interativo) ou quando a data/hora foi alterada.
Para obter mais informações sobre CanvasWatchFaceService
o , consulte a documentação da API do Android CanvasWatchFaceService .
Da mesma forma, CanvasWatchFaceService.Engine explica a implementação real do mostrador do relógio.
Adicionar o CanvasWatchFaceService
Adicione um novo arquivo chamado MyWatchFaceService.cs (no Visual Studio, clique com o botão direito do mouse em WatchFace no Gerenciador de Soluções, clique em Adicionar > Novo Item..., e selecione Classe).
Substitua o conteúdo deste arquivo com o seguinte código:
using System;
using Android.Views;
using Android.Support.Wearable.Watchface;
using Android.Service.Wallpaper;
using Android.Graphics;
namespace WatchFace
{
class MyWatchFaceService : CanvasWatchFaceService
{
public override WallpaperService.Engine OnCreateEngine()
{
return new MyWatchFaceEngine(this);
}
public class MyWatchFaceEngine : CanvasWatchFaceService.Engine
{
CanvasWatchFaceService owner;
public MyWatchFaceEngine (CanvasWatchFaceService owner) : base(owner)
{
this.owner = owner;
}
}
}
}
MyWatchFaceService
(derivado de CanvasWatchFaceService
) é o "programa principal" do mostrador do relógio. MyWatchFaceService
implementa apenas um método, OnCreateEngine
, que instancia e retorna um MyWatchFaceEngine
objeto (MyWatchFaceEngine
é derivado de CanvasWatchFaceService.Engine
). O objeto instanciado MyWatchFaceEngine
deve ser retornado como um WallpaperService.Engine
arquivo . O objeto de encapsulamento MyWatchFaceService
é passado para o construtor.
MyWatchFaceEngine
é a implementação real do mostrador do relógio – ele contém o código que desenha o mostrador do relógio. Ele também lida com eventos do sistema, como mudanças de tela (modos ambiente/interativo, desligamento da tela, etc.).
Implementar o método Engine OnCreate
O OnCreate
método inicializa o mostrador do relógio. Adicione o seguinte campo a MyWatchFaceEngine
:
Paint hoursPaint;
Este Paint
objeto será usado para desenhar a hora atual no mostrador do relógio. Em seguida, adicione o seguinte método a MyWatchFaceEngine
:
public override void OnCreate(ISurfaceHolder holder)
{
base.OnCreate (holder);
SetWatchFaceStyle (new WatchFaceStyle.Builder(owner)
.SetCardPeekMode (WatchFaceStyle.PeekModeShort)
.SetBackgroundVisibility (WatchFaceStyle.BackgroundVisibilityInterruptive)
.SetShowSystemUiTime (false)
.Build ());
hoursPaint = new Paint();
hoursPaint.Color = Color.White;
hoursPaint.TextSize = 48f;
}
OnCreate
é chamado logo após MyWatchFaceEngine
é iniciado. Ele configura o WatchFaceStyle
(que controla como o dispositivo Wear interage com o usuário) e instancia o Paint
objeto que será usado para exibir a hora.
A chamada para SetWatchFaceStyle
faz o seguinte:
Define o modo de visualização como
PeekModeShort
, o que faz com que as notificações apareçam como pequenos cartões de "espiar" na tela.Define a visibilidade em segundo plano como
Interruptive
, o que faz com que o plano de fundo de um cartão de visualização seja mostrado apenas brevemente se ele representar uma notificação interruptiva.Desativa a hora padrão da interface do usuário do sistema de ser desenhada no mostrador do relógio para que o mostrador do relógio personalizado possa exibir a hora.
Para obter mais informações sobre essas e outras opções de estilo de mostrador de relógio, consulte a documentação da API WatchFaceStyle.Builder do Android.
Após SetWatchFaceStyle
a conclusão, OnCreate
instancia o Paint
objeto () e define sua cor comohoursPaint
branco e seu tamanho de texto como 48 pixels (TextSize deve ser especificado em pixels).
Implementar o método Engine OnDraw
O OnDraw
método é talvez o mais importante CanvasWatchFaceService.Engine
– é o método que realmente desenha elementos do mostrador do relógio, como dígitos e ponteiros do mostrador do relógio.
No exemplo a seguir, ele desenha uma cadeia de caracteres de tempo no mostrador do relógio.
Adicione o seguinte método a MyWatchFaceEngine
:
public override void OnDraw (Canvas canvas, Rect frame)
{
var str = DateTime.Now.ToString ("h:mm tt");
canvas.DrawText (str,
(float)(frame.Left + 70),
(float)(frame.Top + 80), hoursPaint);
}
Quando o Android chama OnDraw
, ele passa em uma Canvas
instância e os limites em que o rosto pode ser desenhado. No exemplo de código acima, DateTime
é usado para calcular a hora atual em horas e minutos (no formato de 12 horas). A sequência de tempo resultante é desenhada na tela usando o Canvas.DrawText
método. A cadeia de caracteres aparecerá 70 pixels acima da borda esquerda e 80 pixels abaixo da borda superior.
Para obter mais informações sobre o OnDraw
método, consulte a documentação da API do Android onDraw .
Implementar o método Engine OnTimeTick
O Android chama periodicamente o OnTimeTick
método para atualizar a hora mostrada pelo mostrador do relógio. Ele é chamado pelo menos uma vez por minuto (nos modos ambiente e interativo), ou quando a data/hora ou o fuso horário foram alterados. Adicione o seguinte método a MyWatchFaceEngine
:
public override void OnTimeTick()
{
Invalidate();
}
Essa implementação de OnTimeTick
chamadas simples.Invalidate
O Invalidate
método agenda OnDraw
para redesenhar o mostrador do relógio.
Para obter mais informações sobre o OnTimeTick
método, consulte a documentação da API onTimeTick do Android.
Registrar o CanvasWatchFaceService
MyWatchFaceService
deve ser registrado no AndroidManifest.xml do aplicativo Wear associado. Para fazer isso, adicione o seguinte XML à <application>
seção :
<service
android:name="watchface.MyWatchFaceService"
android:label="Xamarin Sample"
android:allowEmbedded="true"
android:taskAffinity=""
android:permission="android.permission.BIND_WALLPAPER">
<meta-data
android:name="android.service.wallpaper"
android:resource="@xml/watch_face" />
<meta-data
android:name="com.google.android.wearable.watchface.preview"
android:resource="@drawable/preview" />
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService" />
<category android:name="com.google.android.wearable.watchface.category.WATCH_FACE" />
</intent-filter>
</service>
Esse XML faz o seguinte:
Define a
android.permission.BIND_WALLPAPER
permissão. Essa permissão dá ao serviço do mostrador do relógio permissão para alterar o papel de parede do sistema no dispositivo. Observe que essa permissão deve ser definida na<service>
seção e não na seção externa<application>
.Define um
watch_face
recurso. Esse recurso é um arquivo XML curto que declara umwallpaper
recurso (esse arquivo será criado na próxima seção).Declara uma imagem desenhável chamada
preview
que será exibida pela tela de seleção do seletor de relógio.Inclui um
intent-filter
para que o Android saiba queMyWatchFaceService
exibirá um mostrador do relógio.
Isso completa o código para o exemplo básico WatchFace
. O próximo passo é adicionar os recursos necessários.
Adicionar arquivos de recursos
Antes de executar o serviço de observação, você deve adicionar o recurso watch_face e a imagem de visualização. Primeiro, crie um novo arquivo XML em Resources/xml/watch_face.xml e substitua seu conteúdo pelo seguinte XML:
<?xml version="1.0" encoding="UTF-8"?>
<wallpaper xmlns:android="http://schemas.android.com/apk/res/android" />
Defina a ação de compilação deste arquivo como AndroidResource:
Esse arquivo de recurso define um elemento simples wallpaper
que será usado para o mostrador do relógio.
Se você ainda não fez isso, baixe preview.png.
Instale-o em Resources/drawable/preview.png. Certifique-se de adicionar esse arquivo ao WatchFace
projeto. Esta imagem de pré-visualização é apresentada ao utilizador no seletor de mostradores do relógio no dispositivo Wear. Para criar uma imagem de pré-visualização para o mostrador do relógio, pode tirar uma captura de ecrã do mostrador do relógio enquanto este está em execução. (Para obter mais informações sobre como obter capturas de tela de dispositivos Wear, consulte Tirar screenshots).
Experimente!
Crie e implante o aplicativo no dispositivo Wear. Você deve ver a tela do aplicativo Wear aparecer como antes. Faça o seguinte para ativar o novo mostrador do relógio:
Deslize para a direita até ver o plano de fundo da tela do relógio.
Toque e segure em qualquer lugar no plano de fundo da tela por dois segundos.
Deslize da esquerda para a direita para navegar pelos vários mostradores do relógio.
Selecione o mostrador do relógio Xamarin Sample (mostrado à direita):
Toque no mostrador do relógio Xamarin Sample para selecioná-lo.
Isso altera a face do relógio do dispositivo Wear para usar o serviço de mostrador de relógio personalizado implementado até agora:
Este é um mostrador de relógio relativamente bruto porque a implementação do aplicativo é muito mínima (por exemplo, ele não inclui um plano de fundo do mostrador do relógio e não chama Paint
métodos de suavização de serrilhado para melhorar a aparência).
No entanto, ele implementa a funcionalidade básica necessária para criar um mostrador de relógio personalizado.
Na próxima seção, este mostrador do relógio será atualizado para uma implementação mais sofisticada.
Atualizando o mostrador do relógio
No restante deste passo a passo, MyWatchFaceService
é atualizado para exibir um mostrador de relógio de estilo analógico e é estendido para oferecer suporte a mais recursos. Os seguintes recursos serão adicionados para criar o mostrador de relógio atualizado:
Indica o tempo com ponteiros analógicos de hora, minuto e segundo.
Reage a mudanças na visibilidade.
Responde a alterações entre o modo ambiente e o modo interativo.
Lê as propriedades do dispositivo Wear subjacente.
Atualiza automaticamente a hora em que ocorre uma alteração de fuso horário.
Antes de implementar as alterações de código abaixo, baixe drawable.zip, descompacte-o e mova os arquivos .png descompactados para Recursos/desenhável (substitua o preview.png anterior). Adicione os novos arquivos .png ao WatchFace
projeto.
Recursos do mecanismo de atualização
A próxima etapa é atualizar MyWatchFaceService.cs para uma implementação que desenha um mostrador de relógio analógico e oferece suporte a novos recursos. Substitua o conteúdo do MyWatchFaceService.cs pela versão analógica do código do mostrador do relógio em MyWatchFaceService.cs (você pode recortar e colar essa fonte no MyWatchFaceService.cs existente).
Esta versão do MyWatchFaceService.cs adiciona mais código aos métodos existentes e inclui métodos substituídos adicionais para adicionar mais funcionalidade. As seções a seguir fornecem uma visita guiada ao código-fonte.
OnCreate
O método OnCreate atualizado configura o estilo do mostrador do relógio como antes, mas inclui algumas etapas adicionais:
Define a imagem de plano de fundo para o recurso xamarin_background que reside em Resources/drawable-hdpi/xamarin_background.png.
Inicializa
Paint
objetos para desenhar o ponteiro das horas, o ponteiro dos minutos e o segundo manual.Inicializa um
Paint
objeto para desenhar os tiques de hora ao redor da borda do mostrador do relógio.Cria um temporizador que chama o
Invalidate
método (redesenhar) para que a segunda mão seja redesenhada a cada segundo. Observe que esse temporizador é necessário porqueOnTimeTick
as chamadasInvalidate
são feitas apenas uma vez a cada minuto.
Este exemplo inclui apenas uma imagem xamarin_background.png , no entanto, convém criar uma imagem de plano de fundo diferente para cada densidade de tela que seu mostrador de relógio personalizado suportará.
OnDraw
O método OnDraw atualizado desenha um mostrador de relógio de estilo analógico usando as seguintes etapas:
Obtém a hora atual, que agora é mantida em um
time
objeto.Determina os limites da superfície de desenho e seu centro.
Desenha o plano de fundo, dimensionado para caber no dispositivo quando o plano de fundo é desenhado.
Desenha doze tiques ao redor da face do relógio (correspondendo às horas no mostrador do relógio).
Calcula o ângulo, a rotação e o comprimento de cada ponteiro do relógio.
Desenha cada mão na superfície do relógio. Observe que o segundo ponteiro não é desenhado se o relógio estiver no modo ambiente.
OnPropertiesChanged
Esse método é chamado para informar MyWatchFaceEngine
sobre as propriedades do dispositivo de desgaste (como modo ambiente de baixo bit e proteção contra burn-in). No MyWatchFaceEngine
, esse método verifica apenas o modo de ambiente de bits baixos (no modo de ambiente de bits baixos, a tela suporta menos bits para cada cor).
Para obter mais informações sobre esse método, consulte a documentação da API Android onPropertiesChanged .
OnAmbientModeAlterado
Esse método é chamado quando o dispositivo de desgaste entra ou sai do modo ambiente. Na implementação, o MyWatchFaceEngine
mostrador do relógio desativa a suavização de borda quando está no modo ambiente.
Para obter mais informações sobre esse método, consulte a documentação da API Android onAmbientModeChanged .
OnVisibilityAlterado
Esse método é chamado sempre que o relógio se torna visível ou oculto. No MyWatchFaceEngine
, esse método registra/cancela o registro do receptor de fuso horário (descrito abaixo) de acordo com o estado de visibilidade.
Para obter mais informações sobre esse método, consulte a documentação da API Android onVisibilityChanged .
Recurso de fuso horário
O novo MyWatchFaceService.cs também inclui funcionalidade para atualizar a hora atual sempre que o fuso horário muda (como ao viajar entre fusos horários). Perto do final de MyWatchFaceService.cs, é definida uma alteração BroadcastReceiver
de fuso horário que manipula objetos Intent alterados por fuso horário:
public class TimeZoneReceiver: BroadcastReceiver
{
public Action<Intent> Receive { get; set; }
public override void OnReceive (Context context, Intent intent)
{
if (Receive != null)
Receive (intent);
}
}
Os RegisterTimezoneReceiver
métodos e UnregisterTimezoneReceiver
são chamados pelo OnVisibilityChanged
método.
UnregisterTimezoneReceiver
é chamado quando o estado de visibilidade do mostrador do relógio é alterado para oculto. Quando o mostrador do relógio estiver visível novamente, RegisterTimezoneReceiver
é chamado (consulte o OnVisibilityChanged
método).
O método engine RegisterTimezoneReceiver
declara um manipulador para o evento desse receptor de Receive
fuso horário, esse manipulador atualiza o time
objeto com a nova hora sempre que um fuso horário é cruzado:
timeZoneReceiver = new TimeZoneReceiver ();
timeZoneReceiver.Receive = (intent) => {
time.Clear (intent.GetStringExtra ("time-zone"));
time.SetToNow ();
};
Um filtro de intenção é criado e registrado para o receptor de fuso horário:
IntentFilter filter = new IntentFilter(Intent.ActionTimezoneChanged);
Application.Context.RegisterReceiver (timeZoneReceiver, filter);
O UnregisterTimezoneReceiver
método cancela o registro do receptor de fuso horário:
Application.Context.UnregisterReceiver (timeZoneReceiver);
Execute o mostrador do relógio melhorado
Crie e implante o aplicativo no dispositivo Wear novamente. Selecione o mostrador do relógio no seletor do mostrador do relógio como antes. A visualização no seletor de relógios é mostrada à esquerda e o novo mostrador do relógio é mostrado à direita:
Nesta captura de tela, a segunda mão está se movendo uma vez por segundo. Quando você executa esse código em um dispositivo Wear, o segundo ponteiro desaparece quando o relógio entra no modo ambiente.
Resumo
Neste passo a passo, um watchface personalizado do Android Wear 1.0 foi implementado e testado. As CanvasWatchFaceService
classes e CanvasWatchFaceService.Engine
foram introduzidas, e os métodos essenciais da classe de motores foram implementados para criar um mostrador de relógio digital simples. Essa implementação foi atualizada com mais funcionalidade para criar um mostrador de relógio analógico, e métodos adicionais foram implementados para lidar com alterações na visibilidade, modo ambiente e diferenças nas propriedades do dispositivo. Finalmente, um receptor de transmissão de fuso horário foi implementado para que o relógio atualize automaticamente a hora em que um fuso horário é ultrapassado.