Mostra aggiornamenti periodici nei riquadri

Crea riquadri con contenuti che cambiano nel tempo.

Lavorare con le sequenze temporali

Una cronologia è costituita da una o più TimelineEntry, ciascuna delle quali contiene un layout visualizzato durante un intervallo di tempo specifico. Tutti i riquadri richiedono una sequenza temporale.

Diagramma della cronologia dei riquadri

Riquadri con una voce

Spesso un riquadro può essere descritto con un singolo TimelineEntry. Il layout è fisso e cambiano solo le informazioni al suo interno. Ad esempio, un riquadro che mostra i tuoi progressi relativi all'attività fisica della giornata mostra sempre lo stesso layout, anche se puoi modificarlo per visualizzare valori diversi. In questi casi, non sai in anticipo quando i contenuti potrebbero cambiare.

Vedi l'esempio seguente di un riquadro con un singolo TimelineEntry:

override fun onTileRequest(
    requestParams: RequestBuilders.TileRequest
): ListenableFuture<Tile?> {
    val tile =
        Tile.Builder()
            .setResourcesVersion(RESOURCES_VERSION)
            // We add a single timeline entry when our layout is fixed, and
            // we don't know in advance when its contents might change.
            .setTileTimeline(Timeline.fromLayoutElement(simpleLayout(this)))
            .build()
    return Futures.immediateFuture(tile)
}

Voci della cronologia con limite di tempo

Un TimelineEntry può facoltativamente definire un periodo di validità, consentendo a un riquadro di cambiare il layout in un momento prestabilito senza che l'app debba inviare un nuovo riquadro.

L'esempio canonico è un riquadro dell'agenda la cui sequenza temporale contiene un elenco di eventi imminenti. Ogni evento imminente contiene un periodo di validità per indicare quando mostrarlo.

L'API riquadri consente periodi di validità sovrapposti, in cui viene mostrata la schermata con il periodo di tempo rimanente più breve. Viene visualizzato un solo evento alla volta.

Gli sviluppatori possono fornire una voce di riserva predefinita. Ad esempio, la scheda dell'agenda potrebbe avere un riquadro con un periodo di validità infinito, che viene utilizzato se non è valida un'altra voce della cronologia, come mostrato nel seguente esempio di codice:

override fun onTileRequest(
    requestParams: RequestBuilders.TileRequest
): ListenableFuture<Tile?> {
    val timeline = Timeline.Builder()

    // Add fallback "no meetings" entry
    // Use the version of TimelineEntry that's in androidx.wear.protolayout.
    timeline.addTimelineEntry(
        TimelineBuilders.TimelineEntry.Builder().setLayout(getNoMeetingsLayout()).build()
    )

    // Retrieve a list of scheduled meetings
    val meetings = MeetingsRepo.getMeetings()
    // Add a timeline entry for each meeting
    meetings.forEach { meeting ->
        timeline.addTimelineEntry(
            TimelineBuilders.TimelineEntry.Builder()
                .setLayout(getMeetingLayout(meeting))
                .setValidity(
                    // The tile should disappear when the meeting begins
                    // Use the version of TimeInterval that's in
                    // androidx.wear.protolayout.
                    TimelineBuilders.TimeInterval.Builder()
                        .setEndMillis(meeting.dateTimeMillis)
                        .build()
                )
                .build()
        )
    }

    val tile =
        Tile.Builder()
            .setResourcesVersion(RESOURCES_VERSION)
            .setTileTimeline(timeline.build())
            .build()
    return Futures.immediateFuture(tile)
}

Aggiornare un riquadro

Le informazioni mostrate in un riquadro potrebbero scadere dopo un po' di tempo. Ad esempio, un riquadro meteo che mostra la stessa temperatura per tutto il giorno non è preciso.

Per gestire i dati in scadenza, imposta un intervallo di aggiornamento al momento della creazione di un riquadro, che specifica per quanto tempo il riquadro è valido. Nell'esempio della scheda del meteo, puoi aggiornarne i contenuti ogni ora, come mostrato nel seguente codice di esempio:

override fun onTileRequest(
    requestParams: RequestBuilders.TileRequest
): ListenableFuture<Tile?> =
    Futures.immediateFuture(
        Tile.Builder()
            .setResourcesVersion(RESOURCES_VERSION)
            .setFreshnessIntervalMillis(60 * 60 * 1000) // 60 minutes
            .setTileTimeline(Timeline.fromLayoutElement(getWeatherLayout()))
            .build()
    )

Quando imposti un intervallo di aggiornamento, il sistema chiama onTileRequest() poco dopo il termine dell'intervallo. Se non imposti un intervallo di aggiornamento, il sistema non chiama onTileRequest().

Una scheda può scadere anche a causa di un evento esterno. Ad esempio, un utente potrebbe rimuovere una riunione dal calendario e, se la scheda non è stata aggiornata, la riunione eliminata continuerà a essere visualizzata. In questo caso, richiedi un aggiornamento da qualsiasi punto del codice dell'applicazione, come mostrato nel seguente esempio di codice:

Kotlin

fun eventDeletedCallback() {
     TileService.getUpdater(context)
             .requestUpdate(MyTileService::class.java)
}

Java

public void eventDeletedCallback() {
   TileService.getUpdater(context)
           .requestUpdate(MyTileService.class);
}

Scegli un flusso di lavoro di aggiornamento

Segui queste best practice per determinare come configurare gli aggiornamenti dei riquadri:

  • Se l'aggiornamento è prevedibile, ad esempio se riguarda l'evento successivo nel calendario dell'utente, utilizza una sequenza temporale.
  • Quando recuperi i dati della piattaforma, utilizza il binding dei dati in modo che il sistema li aggiorni automaticamente.
  • Se l'aggiornamento può essere calcolato sul dispositivo in poco tempo, ad esempio l'aggiornamento della posizione di un'immagine in un riquadro di alba, utilizza onTileRequest().

    Questa opzione è particolarmente utile quando devi generare tutte le immagini in anticipo. Se in un secondo momento dovrai generare una nuova immagine, chiama setFreshnessIntervalMillis().

  • Se esegui ripetutamente operazioni in background più intensive, ad esempio il polling per i dati meteo, utilizza WorkManager e invia gli aggiornamenti al riquadro.

  • Se l'aggiornamento avviene in risposta a un evento esterno, ad esempio l'accensione delle luci, la ricezione di un'email o l'aggiornamento di una nota, invia un messaggio Firebase Cloud Messaging (FCM) per riattivare l'app, quindi invia gli aggiornamenti al riquadro.

  • Se la procedura di sincronizzazione dei dati dei riquadri potrebbe essere costosa, svolgi i seguenti passaggi:

    1. Pianifica una sincronizzazione dei dati.
    2. Avvia un timer di 1-2 secondi.
    3. Se ricevi un aggiornamento da un'origine dati remota prima che scada il tempo, mostra il valore aggiornato dalla sincronizzazione dei dati. In caso contrario, viene mostrato un valore locale memorizzato nella cache.