Creazione di una watch face

Questa guida illustra come implementare un servizio viso dell'orologio personalizzato per Android Wear 1.0. Vengono fornite istruzioni dettagliate per la creazione di un servizio viso dell'orologio digitale rimosso, seguito da altro codice per creare un viso orologio analogico.

Panoramica

In questa procedura dettagliata viene creato un servizio viso di controllo di base per illustrare gli elementi essenziali della creazione di un viso orologio Android Wear 1.0 personalizzato. Il servizio viso di controllo iniziale visualizza un semplice orologio digitale che visualizza l'ora corrente in ore e minuti:

Screenshot che mostra il viso dell'orologio digitale iniziale.

Dopo aver sviluppato e testato questo viso di orologio digitale, viene aggiunto più codice per aggiornarlo a un viso orologio analogico più sofisticato con tre mani:

Screenshot che mostra il viso dell'orologio analogico finale.

I servizi viso di controllo sono raggruppati e installati come parte di un'app Wear 1.0. Negli esempi seguenti non MainActivity contiene altro che il codice del modello di app Wear 1.0 in modo che il servizio espressioni di controllo possa essere inserito in un pacchetto e distribuito nello smart watch come parte dell'app. In effetti, questa app fungerà esclusivamente da veicolo per caricare il servizio viso dell'orologio nel dispositivo Wear 1.0 (o emulatore) per il debug e il test.

Requisiti

Per implementare un servizio viso di controllo, è necessario quanto segue:

  • Android 5.0 (livello API 21) o versione successiva nel dispositivo o nell'emulatore Wear.

  • Le librerie di supporto Xamarin Android Wear devono essere aggiunte al progetto Xamarin.Android.

Anche se Android 5.0 è il livello API minimo per l'implementazione di un servizio viso di controllo, è consigliabile usare Android 5.1 o versione successiva. I dispositivi Android Wear che eseguono Android 5.1 (API 22) o versione successiva consentono alle app Wear di controllare ciò che viene visualizzato sullo schermo mentre il dispositivo è in modalità ambiente a basso consumo. Quando il dispositivo lascia la modalità ambiente a basso consumo, è in modalità interattiva. Per altre informazioni su queste modalità, vedi Mantenere visibile l'app.

Avviare un progetto di app

Creare un nuovo progetto Android Wear 1.0 denominato WatchFace (per altre informazioni sulla creazione di nuovi progetti Xamarin.Android, vedere Hello, Android):

Impostare il nome del pacchetto su com.xamarin.watchface:

Inoltre, scorrere verso il basso e abilitare le autorizzazioni INTERNET e WAKE_LOCK :

Autorizzazioni necessarie

Scaricare quindi preview.png . Questa operazione verrà aggiunta alla cartella drawables più avanti in questa procedura dettagliata.

Aggiungere il pacchetto Wear Xamarin.Android

Avviare il Gestione pacchetti NuGet (in Visual Studio fare clic con il pulsante destro del mouse su Riferimenti nel Esplora soluzioni e scegliere Gestisci pacchetti NuGet ...). Aggiornare il progetto alla versione stabile più recente di Xamarin.Android.Wear:

Aggiunta di Gestione pacchetti NuGet

Successivamente, se Xamarin.Android.Support.v13 è installato, disinstallarlo:

Rimozione di Gestione pacchetti NuGet

Compilare ed eseguire l'app in un dispositivo o un emulatore Wear (per altre informazioni su come eseguire questa operazione, vedere la Guida introduttiva ). Verrà visualizzata la schermata dell'app seguente nel dispositivo Wear:

Screenshot dell'app

A questo punto, l'app Wear di base non dispone di funzionalità visore di controllo perché non fornisce ancora un'implementazione del servizio viso dell'orologio. Questo servizio verrà aggiunto successivamente.

CanvasWatchFaceService

Android Wear implementa i volti dell'orologio tramite la CanvasWatchFaceService classe . CanvasWatchFaceService è derivato da WatchFaceService, che stesso è derivato da WallpaperService come illustrato nel diagramma seguente:

Diagramma di ereditarietà

CanvasWatchFaceService include un oggetto annidato CanvasWatchFaceService.Engine, che crea un'istanza di un CanvasWatchFaceService.Engine oggetto che esegue il lavoro effettivo del disegno del viso dell'orologio. CanvasWatchFaceService.Engine è derivato da WallpaperService.Engine come illustrato nel diagramma precedente.

Non illustrato in questo diagramma è un Canvas oggetto che CanvasWatchFaceService usa per disegnare il viso dell'orologio, che Canvas viene passato tramite il OnDraw metodo come descritto di seguito.

Nelle sezioni seguenti verrà creato un servizio viso dell'orologio personalizzato seguendo questa procedura:

  1. Definire una classe denominata MyWatchFaceService derivata da CanvasWatchFaceService.

  2. All'interno MyWatchFaceServicedi creare una classe annidata denominata MyWatchFaceEngine derivata da CanvasWatchFaceService.Engine.

  3. In MyWatchFaceServiceimplementare un metodo che crea un'istanza MyWatchFaceEngineCreateEngine e la restituisce.

  4. In MyWatchFaceEngineimplementare il OnCreate metodo per creare lo stile del viso dell'orologio ed eseguire qualsiasi altra attività di inizializzazione.

  5. Implementare il OnDraw metodo di MyWatchFaceEngine. Questo metodo viene chiamato ogni volta che il viso dell'orologio deve essere ridisegnato (ad esempio invalidato). OnDraw è il metodo che disegna (e ridisegna) gli elementi del viso dell'orologio, ad esempio ore, minuti e mani seconde.

  6. Implementare il OnTimeTick metodo di MyWatchFaceEngine. OnTimeTick viene chiamato almeno una volta al minuto (sia in modalità ambientale che interattiva) o quando la data/ora è cambiata.

Per altre informazioni su CanvasWatchFaceService, vedere la documentazione dell'API Android CanvasWatchFaceService . Analogamente, CanvasWatchFaceService.Engine spiega l'implementazione effettiva del viso dell'orologio.

Aggiungere CanvasWatchFaceService

Aggiungere un nuovo file denominato MyWatchFaceService.cs (in Visual Studio fare clic con il pulsante destro del mouse su WatchFace nella Esplora soluzioni, scegliere Aggiungi > nuovo elemento e selezionare Classe).

Sostituire il contenuto di questo file con il codice seguente:

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 (derivato da CanvasWatchFaceService) è il "programma principale" del viso dell'orologio. MyWatchFaceService implementa un solo metodo, OnCreateEngine, che crea un'istanza e restituisce un MyWatchFaceEngine oggetto (MyWatchFaceEngine è derivato da CanvasWatchFaceService.Engine). L'oggetto di cui è stata creata MyWatchFaceEngine un'istanza deve essere restituito come .WallpaperService.Engine L'oggetto incapsulamento MyWatchFaceService viene passato al costruttore.

MyWatchFaceEngine è l'implementazione effettiva del viso dell'orologio: contiene il codice che disegna il viso dell'orologio. Gestisce anche eventi di sistema, ad esempio modifiche dello schermo (modalità di ambiente/interattive, disattivazione dello schermo e così via).

Implementare il metodo OnCreate del motore

Il OnCreate metodo inizializza il viso dell'orologio. Aggiungere il campo seguente a MyWatchFaceEngine:

Paint hoursPaint;

Questo Paint oggetto verrà utilizzato per disegnare l'ora corrente sul viso dell'orologio. Aggiungere quindi il metodo seguente 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 viene chiamato poco dopo MyWatchFaceEngine l'avvio. Configura WatchFaceStyle (che controlla il modo in cui il dispositivo Wear interagisce con l'utente) e crea un'istanza dell'oggetto Paint che verrà usato per visualizzare l'ora.

La chiamata a SetWatchFaceStyle esegue le operazioni seguenti:

  1. Imposta la modalità di visualizzazione su PeekModeShort, che fa sì che le notifiche vengano visualizzate come piccole schede di visualizzazione sullo schermo.

  2. Imposta la visibilità dello sfondo su Interruptive, che fa sì che lo sfondo di una scheda di visualizzazione venga visualizzato solo brevemente se rappresenta una notifica di interruzione.

  3. Disabilita il tempo predefinito dell'interfaccia utente del sistema dal disegno sul viso dell'orologio in modo che il viso dell'orologio personalizzato possa invece visualizzare l'ora.

Per altre informazioni su queste e altre opzioni relative allo stile del viso orologio, vedere la documentazione dell'API Android WatchFaceStyle.Builder .

Al SetWatchFaceStyle termine, OnCreate crea un'istanza dell'oggetto Paint (hoursPaint) e imposta il colore su bianco e le dimensioni del testo su 48 pixel (TextSize deve essere specificato in pixel).

Implementare il metodo OnDraw del motore

Il OnDraw metodo è forse il metodo più importante CanvasWatchFaceService.Engine : è il metodo che disegna effettivamente elementi del viso dell'orologio, ad esempio cifre e mani del viso orologio. Nell'esempio seguente viene disegnare una stringa di tempo sul viso dell'orologio. Aggiungere il metodo seguente 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 Android chiama OnDraw, passa un'istanza Canvas e i limiti in cui è possibile disegnare il viso. Nell'esempio di codice precedente viene DateTime usato per calcolare l'ora corrente in ore e minuti (in formato di 12 ore). La stringa temporale risultante viene disegnata nell'area di disegno usando il Canvas.DrawText metodo . La stringa apparirà 70 pixel rispetto al bordo sinistro e 80 pixel verso il basso dal bordo superiore.

Per altre informazioni sul OnDraw metodo, vedere la documentazione dell'API Android onDraw .

Implementare il metodo Engine OnTimeTick

Android chiama periodicamente il OnTimeTick metodo per aggiornare l'ora visualizzata dal viso dell'orologio. Viene chiamato almeno una volta al minuto (sia in modalità di ambiente che in modalità interattive) o quando la data/ora o il fuso orario sono stati modificati. Aggiungere il metodo seguente a MyWatchFaceEngine:

public override void OnTimeTick()
{
    Invalidate();
}

Questa implementazione di OnTimeTick chiama Invalidatesemplicemente . Il Invalidate metodo pianifica OnDraw di ridisegnare il viso dell'orologio.

Per altre informazioni sul OnTimeTick metodo, vedere la documentazione dell'API Android onTimeTick .

Registrare CanvasWatchFaceService

MyWatchFaceService deve essere registrato nella AndroidManifest.xml dell'app Wear associata. A tale scopo, aggiungere il codice XML seguente alla <application> sezione :

<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>

Questo codice XML esegue le operazioni seguenti:

  1. Imposta l'autorizzazione android.permission.BIND_WALLPAPER . Questa autorizzazione concede al servizio espressioni di controllo l'autorizzazione per modificare lo sfondo del sistema nel dispositivo. Si noti che questa autorizzazione deve essere impostata nella <service> sezione anziché nella sezione esterna <application> .

  2. Definisce una watch_face risorsa. Questa risorsa è un breve file XML che dichiara una wallpaper risorsa (questo file verrà creato nella sezione successiva).

  3. Dichiara un'immagine disegnabile denominata preview che verrà visualizzata dalla schermata di selezione selezione espressioni di controllo.

  4. Include un intent-filter oggetto per informare Android che MyWatchFaceService visualizzerà un viso dell'orologio.

Che completa il codice per l'esempio di base WatchFace . Il passaggio successivo consiste nell'aggiungere le risorse necessarie.

Aggiungere file di risorse

Prima di poter eseguire il servizio espressioni di controllo, è necessario aggiungere la risorsa watch_face e l'immagine di anteprima. Creare innanzitutto un nuovo file XML in Resources/xml/watch_face.xml e sostituirlo con il codice XML seguente:

<?xml version="1.0" encoding="UTF-8"?>
<wallpaper xmlns:android="http://schemas.android.com/apk/res/android" />

Impostare l'azione di compilazione del file su AndroidResource:

Questo file di risorse definisce un elemento semplice wallpaper che verrà usato per il viso dell'orologio.

Se non è ancora stato fatto, scaricare preview.png. Installarlo in Resources/drawable/preview.png. Assicurarsi di aggiungere questo file al WatchFace progetto. Questa immagine di anteprima viene visualizzata all'utente nella selezione del viso dell'orologio nel dispositivo Wear. Per creare un'immagine di anteprima per il viso dell'orologio, è possibile acquisire uno screenshot del viso dell'orologio mentre è in esecuzione. Per altre informazioni sul recupero di screenshot dai dispositivi Wear, vedi Acquisizione di screenshot).

Prova

Compilare e distribuire l'app nel dispositivo Wear. Verrà visualizzata la schermata Dell'app Wear come in precedenza. Eseguire le operazioni seguenti per abilitare il nuovo viso dell'orologio:

  1. Scorri verso destra fino a visualizzare lo sfondo della schermata di controllo.

  2. Toccare e tenere premuto in qualsiasi punto dello sfondo dello schermo per due secondi.

  3. Scorri da sinistra a destra per esplorare i vari volti dell'orologio.

  4. Selezionare il viso dell'orologio di esempio Xamarin (visualizzato a destra):

    Selezione watchface

  5. Toccare il viso dell'orologio di esempio Xamarin per selezionarlo.

In questo modo il viso dell'orologio del dispositivo Wear viene modificato in modo da usare il servizio viso dell'orologio personalizzato implementato finora:

Screenshot che mostra un orologio digitale personalizzato in esecuzione nel dispositivo Wear.

Si tratta di un viso orologio relativamente grezzo perché l'implementazione dell'app è così minima (ad esempio, non include uno sfondo del viso dell'orologio e non chiama Paint metodi anti-alias per migliorare l'aspetto). Tuttavia, implementa la funzionalità bare-bones necessaria per creare un viso orologio personalizzato.

Nella sezione successiva questo viso di controllo verrà aggiornato a un'implementazione più sofisticata.

Aggiornamento del viso dell'orologio

Nella parte restante di questa procedura dettagliata, MyWatchFaceService viene aggiornato per visualizzare un viso orologio in stile analogico ed è esteso per supportare più funzionalità. Verranno aggiunte le funzionalità seguenti per creare il viso dell'orologio aggiornato:

  1. Indica l'ora con ore analogiche, minuti e mani seconde.

  2. Reagisce alle modifiche nella visibilità.

  3. Risponde alle modifiche tra la modalità di ambiente e la modalità interattiva.

  4. Legge le proprietà del dispositivo Wear sottostante.

  5. Aggiorna automaticamente l'ora in cui si verifica una modifica del fuso orario.

Prima di implementare le modifiche al codice seguenti, scaricare drawable.zip, decomprimerlo e spostare i file di .png decompressi in Risorse/disegnabili (sovrascrivere il preview.png precedente). Aggiungere i nuovi file .png al WatchFace progetto.

Funzionalità del motore di aggiornamento

Il passaggio successivo è l'aggiornamento MyWatchFaceService.cs a un'implementazione che disegna un viso orologio analogico e supporta nuove funzionalità. Sostituire il contenuto di MyWatchFaceService.cs con la versione analogica del codice del viso dell'orologio in MyWatchFaceService.cs (è possibile tagliare e incollare questa origine nell'MyWatchFaceService.cs esistente).

Questa versione di MyWatchFaceService.cs aggiunge altro codice ai metodi esistenti e include metodi di override aggiuntivi per aggiungere altre funzionalità. Le sezioni seguenti forniscono una panoramica guidata del codice sorgente.

OnCreate

Il metodo OnCreate aggiornato configura lo stile del viso dell'orologio come in precedenza, ma include alcuni passaggi aggiuntivi:

  1. Imposta l'immagine di sfondo sulla risorsa xamarin_background che risiede in Resources/drawable-hdpi/xamarin_background.png.

  2. Inizializza gli Paint oggetti per disegnare la mano dell'ora, la mano dei minuti e la seconda mano.

  3. Inizializza un Paint oggetto per disegnare i segni di graduazione dell'ora intorno al bordo del viso dell'orologio.

  4. Crea un timer che chiama il Invalidate metodo (ridisegnato) in modo che la seconda mano venga ridisegnata ogni secondo. Si noti che questo timer è necessario perché OnTimeTick chiama Invalidate una sola volta ogni minuto.

In questo esempio è inclusa una sola immagine xamarin_background.png . È tuttavia possibile creare un'immagine di sfondo diversa per ogni densità dello schermo supportata dal viso dell'orologio personalizzato.

Ondraw

Il metodo OnDraw aggiornato disegna un viso orologio in stile analogico seguendo questa procedura:

  1. Ottiene l'ora corrente, ora gestita in un time oggetto .

  2. Determina i limiti della superficie di disegno e del relativo centro.

  3. Disegna lo sfondo, ridimensionato per adattarsi al dispositivo quando viene disegnato lo sfondo.

  4. Disegna dodici segni di graduazione intorno alla faccia dell'orologio (corrispondente alle ore sul viso dell'orologio).

  5. Calcola l'angolo, la rotazione e la lunghezza per ogni mano dell'orologio.

  6. Disegna ogni mano sulla superficie dell'orologio. Si noti che la seconda mano non viene disegnata se l'orologio è in modalità ambientale.

OnPropertiesChanged

Questo metodo viene chiamato per informare MyWatchFaceEngine le proprietà del dispositivo Wear (ad esempio la modalità di ambiente a basso bit e la protezione da burn-in). In MyWatchFaceEngine, questo metodo controlla solo la modalità di ambiente a bit basso (in modalità ambiente a bit basso, lo schermo supporta un minor numero di bit per ogni colore).

Per altre informazioni su questo metodo, vedere la documentazione dell'API Android onPropertiesChanged .

OnAmbientModeChanged

Questo metodo viene chiamato quando il dispositivo Wear entra o esce dalla modalità di ambiente. Nell'implementazione MyWatchFaceEngine , il viso di controllo disabilita l'anti-aliasing quando è in modalità ambientale.

Per altre informazioni su questo metodo, vedere la documentazione dell'API Android onAmbientModeChanged .

OnVisibilityChanged

Questo metodo viene chiamato ogni volta che l'orologio diventa visibile o nascosto. In MyWatchFaceEnginequesto metodo registra/annulla la registrazione del ricevitore del fuso orario (descritto di seguito) in base allo stato di visibilità.

Per altre informazioni su questo metodo, vedere la documentazione dell'API Android onVisibilityChanged .

Funzionalità fuso orario

La nuova MyWatchFaceService.cs include anche funzionalità per aggiornare l'ora corrente ogni volta che cambia il fuso orario ,ad esempio durante il viaggio tra fusi orari. Alla fine di MyWatchFaceService.cs, viene definita una modifica BroadcastReceiver del fuso orario che gestisce gli oggetti Finalità con modifica del fuso orario:

public class TimeZoneReceiver: BroadcastReceiver
{
    public Action<Intent> Receive { get; set; }
    public override void OnReceive (Context context, Intent intent)
    {
        if (Receive != null)
            Receive (intent);
    }
}

I RegisterTimezoneReceiver metodi e UnregisterTimezoneReceiver vengono chiamati dal OnVisibilityChanged metodo . UnregisterTimezoneReceiver viene chiamato quando lo stato di visibilità del viso dell'orologio viene modificato in nascosto. Quando il viso dell'orologio è nuovamente visibile, RegisterTimezoneReceiver viene chiamato (vedere il OnVisibilityChanged metodo ).

Il metodo del motore RegisterTimezoneReceiver dichiara un gestore per l'evento del ricevitore del Receive fuso orario. Questo gestore aggiorna l'oggetto time con la nuova ora ogni volta che viene intersecato un fuso orario:

timeZoneReceiver = new TimeZoneReceiver ();
timeZoneReceiver.Receive = (intent) => {
    time.Clear (intent.GetStringExtra ("time-zone"));
    time.SetToNow ();
};

Viene creato e registrato un filtro finalità per il ricevitore del fuso orario:

IntentFilter filter = new IntentFilter(Intent.ActionTimezoneChanged);
Application.Context.RegisterReceiver (timeZoneReceiver, filter);

Il UnregisterTimezoneReceiver metodo annulla la registrazione del ricevitore del fuso orario:

Application.Context.UnregisterReceiver (timeZoneReceiver);

Eseguire il viso dell'orologio migliorato

Compilare e distribuire di nuovo l'app nel dispositivo Wear. Selezionare il viso dell'orologio dal selettore viso di controllo come in precedenza. L'anteprima nella selezione espressioni di controllo viene visualizzata a sinistra e il nuovo viso dell'orologio viene visualizzato a destra:

Screenshot che mostra un viso analogico migliorato nella selezione e nel dispositivo.

In questo screenshot, la seconda mano si sposta una volta al secondo. Quando si esegue questo codice in un dispositivo Wear, la seconda mano scompare quando l'orologio entra in modalità ambientale.

Riepilogo

In questa procedura dettagliata è stato implementato e testato un watchface Android Wear 1.0 personalizzato. Sono CanvasWatchFaceService state introdotte le classi e CanvasWatchFaceService.Engine e i metodi essenziali della classe motore sono stati implementati per creare un semplice viso da orologio digitale. Questa implementazione è stata aggiornata con maggiore funzionalità per creare un viso da orologio analogico e sono stati implementati metodi aggiuntivi per gestire le modifiche in visibilità, modalità ambientale e differenze nelle proprietà del dispositivo. Infine, è stato implementato un ricevitore di trasmissione del fuso orario in modo che l'orologio aggiorni automaticamente l'ora in cui viene intersecato un fuso orario.