Esporre i dati a complicazioni

Le app dei fornitori di dati espongono le informazioni alle compliche dei quadranti, fornendo campi che contengono testo, stringhe, immagini e numeri.

Un servizio del fornitore di dati estende ComplicationProviderService per fornire informazioni utili direttamente a un quadrante.

Crea un progetto del fornitore di dati

Per creare un progetto in Android Studio per l'app del tuo fornitore di dati, procedi nel seguente modo:

  1. Fai clic su File > Nuovo > Nuovo progetto.
  2. Nella finestra Modello di progetto, fai clic sulla scheda Wear OS, seleziona Nessuna attività e fai clic su Avanti.
  3. Nella finestra Configura il tuo progetto, assegna un nome al progetto, compila le informazioni standard e fai clic su Fine.
  4. Android Studio crea un progetto con un modulo dell'app per il tuo fornitore di dati. Per maggiori informazioni sui progetti in Android Studio, consulta Creare un progetto.
  5. Avvia l'app del tuo fornitore di dati creando una nuova classe che estenda BroadcastReceiver. Lo scopo di questa classe è ascoltare le richieste di aggiornamento delle complicazioni dal sistema Wear OS. Inoltre, crea una nuova classe che estenda ComplicationProviderService per fornire i dati come richiesto dalle complicazioni appropriate. Per saperne di più, consulta:

    Nota: l'aggiunta di un'attività per il fornitore di dati è facoltativa. Ad esempio, potresti volere un'attività che venga avviata solo quando l'utente tocca una complicazione.

Implementare un metodo per le richieste di aggiornamento

Quando sono necessari dati relativi alle complicazioni, il sistema Wear OS invia richieste di aggiornamento al tuo fornitore di dati. Le richieste vengono ricevute dal tuo BroadcastReceiver. Per rispondere alle richieste di aggiornamento, il fornitore di dati deve implementare il metodo onComplicationUpdate() della classe ComplicationProviderService.

Il sistema Wear OS chiama onComplicationUpdate() quando ha bisogno dei dati del provider, ad esempio quando una complicazione che utilizza il provider diventa attiva o quando passa un periodo di tempo fisso. Passa un oggetto ComplicationManager come parametro a onComplicationUpdate, che viene utilizzato per inviare i dati al sistema.

Nota: quando l'app del tuo fornitore di dati fornisce dati, il quadrante riceve i valori non elaborati che invii per poter trarre le informazioni.

Il seguente snippet di codice mostra un'implementazione di esempio del metodo onComplicationUpdate:

Kotlin

override fun onComplicationUpdate(
    complicationId: Int, dataType: Int, complicationManager: ComplicationManager) {

    Log.d(TAG, "onComplicationUpdate() id: $complicationId")

    // Used to create a unique key to use with SharedPreferences for this complication.
    val thisProvider = ComponentName(this, javaClass)

    // Retrieves your data; in this case, grabs an incrementing number from SharedPrefs.
    val preferences = getSharedPreferences(ComplicationTapBroadcastReceiver.COMPLICATION_PROVIDER_PREFERENCES_FILE_KEY, 0)

    val number = preferences.getInt(
            ComplicationTapBroadcastReceiver.getPreferenceKey(
                    thisProvider, complicationId),
                    0)
    val numberText = String.format(Locale.getDefault(), "%d!", number)

    var complicationData: ComplicationData? = null

    when (dataType) {
        ComplicationData.TYPE_SHORT_TEXT -> complicationData = ComplicationData.Builder(ComplicationData.TYPE_SHORT_TEXT)
                .setShortText(ComplicationText.plainText(numberText))
                .build()
        else -> if (Log.isLoggable(TAG, Log.WARN)) {
                    Log.w(TAG, "Unexpected complication type $dataType")
                }
    }

    if (complicationData != null) {
        complicationManager.updateComplicationData(complicationId, complicationData)
    } else {
        // If no data is sent, we still need to inform the ComplicationManager, so
        // the update job can finish and the wake lock isn't held any longer.
        complicationManager.noUpdateRequired(complicationId)
    }
}

Java

@Override
public void onComplicationUpdate(
       int complicationId, int dataType, ComplicationManager complicationManager) {

   Log.d(TAG, "onComplicationUpdate() id: " + complicationId);

   // Used to create a unique key to use with SharedPreferences for this complication.
   ComponentName thisProvider = new ComponentName(this, getClass());

   // Retrieves your data; in this case, grabs an incrementing number from SharedPrefs.
   SharedPreferences preferences =
     getSharedPreferences( ComplicationTapBroadcastReceiver.COMPLICATION_PROVIDER_PREFERENCES_FILE_KEY, 0);

   int number =
           preferences.getInt(
                   ComplicationTapBroadcastReceiver.getPreferenceKey(
                           thisProvider, complicationId),
                   0);
   String numberText = String.format(Locale.getDefault(), "%d!", number);

   ComplicationData complicationData = null;

   switch (dataType) {
       case ComplicationData.TYPE_SHORT_TEXT:
           complicationData =
                   new ComplicationData.Builder(ComplicationData.TYPE_SHORT_TEXT)
                           .setShortText(ComplicationText.plainText(numberText))
                           .build();
           break;
       default:
           if (Log.isLoggable(TAG, Log.WARN)) {
               Log.w(TAG, "Unexpected complication type " + dataType);
           }
   }

   if (complicationData != null) {
       complicationManager.updateComplicationData(complicationId, complicationData);

   } else {
       // If no data is sent, we still need to inform the ComplicationManager, so
       // the update job can finish and the wake lock isn't held any longer.
       complicationManager.noUpdateRequired(complicationId);
   }
}

Dichiarazioni e autorizzazioni del file manifest

Le app dei fornitori di dati devono includere dichiarazioni specifiche nel file manifest dell'app per essere trattate come fornitori di dati da parte del sistema Android. Questa sezione illustra le impostazioni richieste per le app del fornitore di dati.

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

Inoltre, includi un attributo android:icon nell'elemento service che fornisce un'icona bianca a un solo colore. Per le icone consigliamo di utilizzare disegni vettoriali. L'icona rappresenta il provider e viene visualizzata nel selettore dei provider.

Ecco un esempio:

<service
    android:name=".provider.IncrementingNumberComplicationProviderService"
    android:icon="@drawable/icn_complications"
    android:label="@string/complications_provider_incrementing_number"
    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>
</service>

Specifica gli elementi dei metadati

Nel file manifest, includi i metadati per specificare i tipi supportati, il periodo di aggiornamento e l'azione di configurazione, come mostrato nell'esempio seguente:

<meta-data
    android:name="android.support.wearable.complications.SUPPORTED_TYPES"
    android:value="RANGED_VALUE,SHORT_TEXT,LONG_TEXT" />

<meta-data
    android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS"
    android:value="300" />

Quando il fornitore di dati delle complicazioni è attivo, UPDATE_PERIOD_SECONDS specifica la frequenza con cui vuoi che il sistema verifichi la disponibilità di aggiornamenti dei dati. Se le informazioni mostrate nella complicazione non devono essere aggiornate in base a una pianificazione regolare, 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), ossia il periodo di aggiornamento minimo applicato dal sistema, per preservare la durata della batteria del dispositivo. Inoltre, tieni presente che le richieste di aggiornamento avvengono con minore frequenza quando il dispositivo è in modalità Ambient o non viene indossato.

Per maggiori dettagli sull'invio degli aggiornamenti, consulta le chiavi elencate per la classe ComplicationProviderService nella documentazione di riferimento per le API Wear OS.

Aggiungi un'attività di configurazione

Se necessario, un provider può includere un'attività di configurazione che viene mostrata all'utente quando sceglie un fornitore di dati. Per includere l'attività di configurazione, includi un elemento di metadati nella dichiarazione del servizio del provider nel file manifest con la seguente chiave:

<meta-data
    android:name="android.support.wearable.complications.PROVIDER_CONFIG_ACTION"
    android:value="PROVIDER_CONFIG_ACTION"/>

Il valore può essere qualsiasi azione.

Quindi, crea l'attività di configurazione con un filtro per intent per quell'azione. L'attività di configurazione deve risiedere nello stesso pacchetto del provider. L'attività di configurazione deve restituire RESULT_OK o RESULT_CANCELED per indicare al sistema se il provider deve essere impostato.

Quadranti sicuri specificati dal fornitore

I fornitori possono specificare determinati quadranti come "sicuri" per ricevere i loro dati. Viene utilizzato solo quando un quadrante tenta di utilizzare il fornitore come predefinito e il fornitore considera attendibile l'app del quadrante.

Per dichiarare sicuri i quadranti, il fornitore aggiunge i metadati con una chiave di android.support.wearable.complications.SAFE_WATCH_FACES. Il valore dei metadati è un elenco separato da virgole di nomi di componenti WatchFaceService, come se fosse chiamato ComponentName.flattenToString(), o di nomi di pacchetti dell'app, nel qual caso ogni quadrante all'interno di un'app specificata è considerato sicuro. Lo spazio vuoto nell'elenco dei valori viene ignorato. Ecco alcuni esempi:

<meta-data
       android:name="android.support.wearable.complications.SAFE_WATCH_FACES"
       android:value="
          com.app.watchface/com.app.watchface.MyWatchFaceService,
          com.anotherapp.anotherwatchface/com.something.WatchFaceService,
          com.something.text"/>

Fornire immagini protette dal burn-in

Su schermi a rischio di burn-in, è consigliabile evitare blocchi di colore in modalità Ambient. Se le icone o le immagini includono blocchi di colore in tinta unita, puoi fornire anche una versione protetta dal burn-in.

Quando fornisci un'icona utilizzando ComplicationData.Builder#setIcon, includi una versione protetta dal burn-in utilizzando ComplicationData.Builder#setBurnInProtectionIcon.

Quando fornisci un'immagine utilizzando ComplicationData.Builder#setSmallImage, includi una versione protetta dal burn-in utilizzando ComplicationData.Builder#setBurnInProtectionSmallImage.

Utilizzare gli aggiornamenti push

In alternativa a specificare un intervallo di aggiornamento costante e diverso da zero per una complicazione nel manifest dell'app, puoi utilizzare un'istanza di ComplicationDataSourceUpdateRequester per richiedere gli aggiornamenti in modo dinamico. Per richiedere un aggiornamento dei contenuti visibili all'utente della complicazione, chiama requestUpdate().

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

Fornisci valori dinamici

A partire da Wear OS 4, alcune complicazioni possono mostrare valori che vengono aggiornati più spesso in base ai valori disponibili direttamente sulla piattaforma. Per fornire questa funzionalità nelle complicazioni, usa i campi ComplicationData che accettano valori dinamici. La piattaforma valuta e aggiorna spesso questi valori, senza che sia necessario eseguire il provider di complicazioni.

I campi di esempio includono il campo del valore dinamico di GoalProgressComplicationData e DynamicComplicationText, che possono essere utilizzati in qualsiasi campo ComplicationText. Questi valori dinamici sono basati sulla libreria androidx.wear.protolayout.expression.

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

Fornisci valori dipendenti dal tempo

Per alcune complicazioni è necessario visualizzare un valore relativo all'ora attuale. Gli esempi includono la data corrente, l'ora alla prossima riunione o l'ora in un altro fuso orario.

Non aggiornare una complicazione ogni secondo o minuto per mantenere aggiornati questi valori. Specifica invece i valori relativi alla data o all'ora correnti utilizzando il testo dipendente dal tempo. Puoi utilizzare gli strumenti di creazione nella classe ComplicationText per creare questi valori dipendenti dal tempo.

Frequenza di aggiornamento delle complicazioni

Potresti voler aggiornare rapidamente le complicazioni. Tuttavia, ciò potrebbe influire sulla durata della batteria del dispositivo. Puoi scegliere di utilizzare un' API per le richieste di complicazioni con privilegi che consente di aggiornare più frequentemente complicazioni specifiche. Tuttavia, l'uso di questa API deve essere consentito dal produttore dell'orologio. Ogni produttore di orologi decide quali complicazioni possono essere aggiornate a una velocità più elevata di quanto generalmente consentito.