Esporre i dati a complicazioni

Le origini dati delle complicazioni espongono informazioni alle complicazioni del quadrante, fornendo testo, immagini e numeri che il quadrante può visualizzare.

Un servizio di origine dati estende SuspendingComplicationDataSourceService per fornire informazioni utili direttamente a un quadrante.

Per iniziare

Aggiungi la seguente dipendenza al modulo dell'app:

dependencies {
  implementiation("androidx.wear.watchface:watchface-complications-data-source-ktx:1.2.1")
}

Crea il servizio di origine dati

Quando sono necessari i dati della complicazione, il sistema Wear OS invia richieste di aggiornamento all'origine dati. Per rispondere alle richieste di aggiornamento, l'origine dati deve implementare il metodo onComplicationRequest() della classe SuspendingComplicationDataSourceService.

Il sistema Wear OS chiama onComplicationRequest() quando ha bisogno di dati dalla tua origine, ad esempio quando una complicazione che utilizza l'origine dati diventa attiva o quando trascorre un periodo di tempo fisso.

Nota:quando l'origine dati fornisce i dati, il quadrante riceve i valori non elaborati. Il quadrante è responsabile della formattazione dei dati per la visualizzazione.

Il seguente snippet di codice mostra un'implementazione di esempio:

class MyComplicationDataSourceService : SuspendingComplicationDataSourceService() {
    override suspend fun onComplicationRequest(request: ComplicationRequest): ComplicationData? {
        // Retrieve the latest info for inclusion in the data.
        val text = getLatestData()
        return shortTextComplicationData(text)
    }

    override fun getPreviewData(type: ComplicationType): ComplicationData? {
        return shortTextComplicationData("Event 1")
    }

    private fun shortTextComplicationData(text: String) =
        ShortTextComplicationData.Builder(
            text = PlainComplicationText.Builder(text).build(),
            contentDescription = PlainComplicationText.Builder(text).build()
        )
            // Add further optional details here such as icon, tap action, and title.
            .build()

    // ...
}

Dichiarazioni e autorizzazioni del manifest

Le origini dati devono includere dichiarazioni specifiche nel manifest dell'app per essere trattate come un'origine dati dal sistema Android. Questa sezione spiega le impostazioni richieste per le origini dati.

Nel manifest dell'app, dichiara il servizio e aggiungi un filtro per intent di azione di richiesta di aggiornamento. Il manifest deve anche proteggere il servizio aggiungendo l'autorizzazione BIND_COMPLICATION_PROVIDER per garantire che solo il sistema Wear OS possa associarsi ai servizi del fornitore.

Includi anche un attributo android:icon nell'elemento service che fornisce un'icona bianca monocromatica. Consigliamo di utilizzare risorse grafiche vettoriali per le icone. L'icona rappresenta l'origine dati e viene mostrata nel selettore di complicazioni.

Ecco un esempio:

<service
    android:name=".snippets.complication.MyComplicationDataSourceService"
    android:exported="true"
    android:label="@string/my_complication_service_label"
    android:icon="@drawable/complication_icon"
    android:permission="com.google.android.wearable.permission.BIND_COMPLICATION_PROVIDER">
    <intent-filter>
        <action android:name="android.support.wearable.complications.ACTION_COMPLICATION_UPDATE_REQUEST" />
    </intent-filter>

    <!-- Supported types should be comma-separated e.g. SHORT_TEXT,SMALL_IMAGE -->
    <meta-data
        android:name="android.support.wearable.complications.SUPPORTED_TYPES"
        android:value="SHORT_TEXT" />
    <meta-data
        android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS"
        android:value="300" />

    <!--
        Optionally, the complication can be configured by the user by specifying a
        configuration activity.
    -->
    <meta-data
        android:name="android.support.wearable.complications.PROVIDER_CONFIG_ACTION"
        android:value="MY_CONFIG_ACTION" />

</service>

Elementi dei metadati

Nel file manifest, nota i seguenti elementi di metadati:

  • android:name="android.support.wearable.complications.SUPPORTED_TYPES": Specifica i tipi di dati delle complicazioni supportati dall'origine dati.
  • android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS": Specifica la frequenza con cui il sistema deve verificare la disponibilità di aggiornamenti dei dati.

Quando l'origine dati dei dati della complicazione è attiva, UPDATE_PERIOD_SECONDS specifica la frequenza con cui vuoi che il sistema controlli gli aggiornamenti dei dati. Se le informazioni mostrate nella complicazione non devono essere aggiornate regolarmente, ad esempio quando utilizzi gli aggiornamenti push, imposta questo valore su 0.

Se non imposti UPDATE_PERIOD_SECONDS su 0, devi utilizzare un valore di almeno 300 (5 minuti), che è il periodo di aggiornamento minimo applicato dal sistema, per preservare la durata della batteria del dispositivo. Inoltre, tieni presente che le richieste di aggiornamento sono meno frequenti quando il dispositivo è in modalità Ambient o non è indossato.

Aggiungere un'attività di configurazione

Se necessario, un'origine dati può includere un'attività di configurazione che viene mostrata all'utente quando sceglie quell'origine dati specifica dal selettore di complicazioni. Ad esempio, un'origine dati dell'orologio mondiale potrebbe avere un'attività di configurazione che consente all'utente di scegliere la città o il fuso orario da visualizzare.

Il file manifest di esempio include un elemento meta-data con la chiave PROVIDER_CONFIG_ACTION. Il valore di questo elemento è l'azione utilizzata per avviare l'attività di configurazione.

Crea l'attività di configurazione e aggiungi un filtro per intent che corrisponda all'azione nel file manifest.

<intent-filter>
    <action android:name="MY_CONFIG_ACTION" />
    <category android:name="android.support.wearable.complications.category.PROVIDER_CONFIG" />
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

L'attività può ottenere i dettagli dello spazio della complicazione che sta configurando dall'intent all'interno del metodo onCreate() dell'attività:

// Keys defined on ComplicationDataSourceService
val id = intent.getIntExtra(EXTRA_CONFIG_COMPLICATION_ID, -1)
val type = intent.getIntExtra(EXTRA_CONFIG_COMPLICATION_TYPE, -1)
val source = intent.getStringExtra(EXTRA_CONFIG_DATA_SOURCE_COMPONENT)

L'attività di configurazione deve trovarsi nello stesso pacchetto del provider. L'attività di configurazione deve restituire RESULT_OK o RESULT_CANCELED per indicare al sistema se l'origine dati deve essere impostata:

setResult(RESULT_OK) // Or RESULT_CANCELED to cancel configuration
finish()

Utilizzare gli aggiornamenti push

In alternativa a specificare un intervallo di aggiornamento nel manifest dell'app, puoi utilizzare un'istanza di ComplicationDataSourceUpdateRequester per avviare gli aggiornamenti in modo dinamico. Per richiedere un aggiornamento, chiama il numero requestUpdate().

Attenzione:per preservare la durata della batteria del dispositivo, non chiamare requestUpdate() dalla tua istanza di ComplicationDataSourceUpdateRequester più spesso di una volta ogni 5 minuti in media.

Fornire valori dipendenti dal tempo

Alcune complicazioni devono mostrare un valore relativo all'ora corrente. Ad esempio, la data corrente, il tempo che manca alla prossima riunione o l'ora in un altro fuso orario.

Non aggiornare una complicazione ogni secondo o minuto per mantenere aggiornati i valori. Specifica invece i valori in relazione alla data o all'ora corrente utilizzando testo dipendente dal tempo. Le seguenti classi consentono di creare questi valori dipendenti dal tempo:

Dati degli Spostamenti

Per le origini dati delle complicazioni che forniscono una sequenza di valori in orari predefiniti, utilizza SuspendingTimelineComplicationDataSourceService.

Un esempio è un'origine dati "prossimo evento" di un'app di calendario: anziché dover eseguire regolarmente il polling dell'origine dati per il prossimo evento, l'origine dati può fornire una cronologia degli eventi una sola volta, quindi può avviare gli aggiornamenti se il calendario cambia. In questo modo si riduce il carico sul sistema e la complicazione mostra l'evento corretto in modo tempestivo:

class MyTimelineComplicationDataSourceService : SuspendingTimelineComplicationDataSourceService() {
    override suspend fun onComplicationRequest(request: ComplicationRequest): ComplicationDataTimeline? {
        if (request.complicationType != ComplicationType.SHORT_TEXT) {
            return ComplicationDataTimeline(
                defaultComplicationData = NoDataComplicationData(),
                timelineEntries = emptyList()
            )
        }
        // Retrieve list of events from your own datasource / database.
        val events = getCalendarEvents()
        return ComplicationDataTimeline(
            defaultComplicationData = shortTextComplicationData("No event"),
            timelineEntries = events.map {
                TimelineEntry(
                    validity = TimeInterval(it.start, it.end),
                    complicationData = shortTextComplicationData(it.name)
                )
            }
        )
    }

    override fun getPreviewData(type: ComplicationType): ComplicationData? {
        return shortTextComplicationData("Event 1")
    }

    private fun shortTextComplicationData(text: String) =
        ShortTextComplicationData.Builder(
            text = PlainComplicationText.Builder(text).build(),
            contentDescription = PlainComplicationText.Builder(text).build()
        )
            // Add further optional details here such as icon, tap action, title etc
            .build()

    // ...
}

Il comportamento di SuspendingTimelineComplicationDataSourceService è il seguente:

  • Quando l'ora corrente rientra nell'ora di inizio e di fine di una voce nella cronologia, il quadrante utilizza quel valore.
  • Quando l'ora attuale non rientra in nessuna voce della cronologia, viene utilizzato il valore predefinito. Ad esempio, nell'app di calendario, potrebbe essere "Nessun evento".
  • Se l'ora attuale rientra in più eventi, viene utilizzato l'evento più breve.

Fornire valori dinamici

A partire da Wear OS 4, alcune complicazioni possono visualizzare valori che vengono aggiornati più frequentemente in base ai valori disponibili direttamente per la piattaforma. Per fornire questa funzionalità nelle complicazioni, utilizza i campi ComplicationData che accettano valori dinamici. La piattaforma valuta e aggiorna questi valori di frequente, senza richiedere l'esecuzione del fornitore di complicazioni.

I campi di esempio includono GoalProgressComplicationData's dynamic value field e DynamicComplicationText, che possono essere utilizzati in qualsiasi ComplicationText campo. Questi valori dinamici si basano sulla libreria androidx.wear.protolayout.expression.

In determinate situazioni, la piattaforma non può valutare i valori dinamici: