Fournir des données aux complications

Les sources de données de complications affichent des informations sur les complications du cadran, ainsi que du texte, des images et des chiffres que le cadran peut afficher.

Un service de source de données étend SuspendingComplicationDataSourceService afin de fournir des informations utiles directement à un cadran.

Premiers pas

Ajoutez la dépendance suivante au module de votre application :

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

Créer le service de source de données

Lorsque des données de complication sont nécessaires, le système Wear OS envoie des demandes de mise à jour à votre source de données. Pour répondre à ces demandes, votre source de données doit implémenter la méthode onComplicationRequest() de la classe SuspendingComplicationDataSourceService.

Le système Wear OS appelle onComplicationRequest() lorsqu'il a besoin des données de votre source, par exemple lorsqu'une complication utilisant cette source de données devient active ou après un certain temps.

Remarque : Lorsque votre source de données fournit des données, le cadran reçoit les valeurs brutes. Le cadran est chargé de mettre en forme les données pour l'affichage.

L'extrait de code suivant présente un exemple d'implémentation :

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

    // ...
}

Déclarations et autorisations du fichier manifeste

Les sources de données doivent inclure des déclarations spécifiques dans leur fichier manifeste afin que le système Android puisse les traiter en tant que source de données. Cette section décrit les paramètres requis pour les sources de données.

Dans le fichier manifeste de votre application, définissez le service et ajoutez un filtre d'intent de demande de mise à jour. Le fichier manifeste doit également protéger le service en ajoutant l'autorisation BIND_COMPLICATION_PROVIDER pour garantir que seul le système Wear OS peut être lié aux services du fournisseur.

Incluez également un attribut android:icon dans l'élément service qui fournit une icône blanche d'une seule couleur. Nous vous recommandons d'utiliser des drawables vectoriels pour les icônes. Cette icône représente la source de données et s'affiche dans le sélecteur de complications.

Exemple :

<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, for example: "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, specify a configuration activity, where the user can configure your complication. -->
    <meta-data
        android:name="android.support.wearable.complications.PROVIDER_CONFIG_ACTION"
        android:value="MY_CONFIG_ACTION" />

</service>

Éléments de métadonnées

Dans votre fichier manifeste, notez les éléments de métadonnées suivants :

  • android:name="android.support.wearable.complications.SUPPORTED_TYPES" : Spécifie les types de données de complication compatibles avec la source de données.
  • android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS" : Indique la fréquence à laquelle le système doit rechercher des mises à jour des données.

Lorsque votre source de données de complication est active, UPDATE_PERIOD_SECONDS indique la fréquence à laquelle vous souhaitez que le système recherche les mises à jour des données. Si les informations affichées dans la complication ne requièrent pas de mises à jour régulières, par exemple lorsque vous utilisez des mises à jour push, définissez cette valeur sur 0.

Si vous ne définissez pas UPDATE_PERIOD_SECONDS sur 0, vous devez utiliser une valeur d'au moins 300 (5 minutes), qui correspond à la période de mise à jour minimale imposée par le système, afin de préserver l'autonomie de la batterie de l'appareil. En outre, sachez que les demandes de mise à jour peuvent se produire moins souvent lorsque l'appareil est en mode veille ou lorsqu'il n'est pas porté.

Ajouter une activité de configuration

Si nécessaire, une source de données peut inclure une activité de configuration qui lui est présentée lorsqu'il choisit cette source de données dans le sélecteur de complications. Par exemple, une source de données d'horloge universelle peut comporter une activité de configuration qui permet à l'utilisateur de choisir la ville ou le fuseau horaire à afficher.

L'exemple de fichier manifeste inclut un élément meta-data avec la clé PROVIDER_CONFIG_ACTION. La valeur de cet élément correspond à l'action utilisée pour lancer l'activité de configuration.

Créez l'activité de configuration et ajoutez-y un filtre d'intent correspondant à l'action dans votre fichier manifeste.

<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'activité peut obtenir des informations sur l'emplacement de complication qu'elle configure à partir de l'intent dans la méthode onCreate() de l'activité :

// 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'activité de configuration doit se trouver dans le même package que le fournisseur. L'activité de configuration doit renvoyer RESULT_OK ou RESULT_CANCELED pour indiquer au système si la source de données doit être définie :

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

Utiliser les mises à jour push

Au lieu d'indiquer un intervalle de mise à jour dans le fichier manifeste de votre application, vous pouvez utiliser une instance de ComplicationDataSourceUpdateRequester pour lancer des mises à jour de manière dynamique. Pour demander une mise à jour, appelez requestUpdate().

Attention : Pour préserver l'autonomie de la batterie de l'appareil, n'appelez pas requestUpdate() plus souvent que toutes les cinq minutes en moyenne à partir de l'instance de ComplicationDataSourceUpdateRequester.

Indiquer des valeurs temporelles

Certaines complications doivent afficher une valeur correspondant à l'heure actuelle. Par exemple : la date actuelle, l'heure avant la prochaine réunion ou l'heure dans un autre fuseau horaire.

Ne mettez pas à jour une complication toutes les secondes ou toutes les minutes pour maintenir ces valeurs à jour. Précisez plutôt des valeurs en lien avec la date ou l'heure actuelle à l'aide d'un texte dépendant de l'heure. Les classes suivantes vous permettent de créer ces valeurs temporelles :

Données de Vos trajets

Pour les sources de données de complication qui fournissent une séquence de valeurs à des moments prédéfinis, utilisez SuspendingTimelineComplicationDataSourceService.

Par exemple, une source de données "prochain événement" d'une application d'agenda : Au lieu que le système ait à interroger régulièrement la source de données pour le prochain événement, la source de données peut fournir une chronologie des événements une seule fois, puis la source de données peut lancer des mises à jour si l'agenda change. Cela minimise la charge sur le système et permet à la complication d'afficher l'événement correct en temps voulu :

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

    // ...
}

Le comportement de SuspendingTimelineComplicationDataSourceService est le suivant :

  • Lorsque l'heure actuelle se situe entre l'heure de début et l'heure de fin d'une entrée dans la chronologie, le cadran utilise cette valeur.
  • Lorsque l'heure actuelle ne correspond à aucune entrée de la chronologie, la valeur par défaut est utilisée. Par exemple, dans l'application Agenda, cela peut être "Aucun événement".
  • Si l'heure actuelle se situe dans plusieurs événements, l'événement le plus court est utilisé.

Fournir des valeurs dynamiques

À partir de Wear OS 4, certaines complications peuvent afficher des valeurs qui s'actualisent plus fréquemment en fonction des valeurs disponibles directement sur la plate-forme. Pour offrir cette possibilité dans vos complications, utilisez les champs ComplicationData qui acceptent les valeurs dynamiques. La plate-forme évalue et met à jour ces valeurs fréquemment, sans exiger que le fournisseur de complications s'exécute.

Par exemple, le champ de valeur dynamique de GoalProgressComplicationData et DynamicComplicationText peuvent être utilisés dans n'importe quel champ ComplicationText. Ces valeurs dynamiques sont basées sur la bibliothèque androidx.wear.protolayout.expression.

Dans certaines situations, la plate-forme ne peut pas évaluer les valeurs dynamiques :