Créer votre première carte dans Wear OS

1. Introduction

montre animée, l'utilisateur balaie le cadran jusqu'à la première carte qui représente une prévision, puis jusqu'à la carte d'un minuteur, et revient en arrière

Les cartes Wear OS permettent d'accéder facilement aux informations et aux actions dont les utilisateurs ont besoin pour effectuer une tâche. Il suffit de balayer l'écran à partir du cadran pour consulter les dernières prévisions ou lancer un minuteur.

Une carte s'exécute dans l'interface utilisateur du système au lieu de s'exécuter dans son propre conteneur d'application. Nous utilisons un service pour décrire la mise en page et le contenu de cette carte. L'UI du système affiche ensuite la carte si nécessaire.

Objectifs de l'atelier

35a459b77a2c9d52.png

Vous créerez une carte qui affichera les conversations récentes pour une application de chat. À partir de cette surface, l'utilisateur pourra effectuer directement l'une des trois tâches courantes suivantes :

  • Ouvrir une conversation
  • Rechercher une conversation
  • Écrire un nouveau message

Points abordés

Dans cet atelier de programmation, vous apprendrez à écrire votre propre carte Wear OS, ce qui comprend les tâches suivantes :

  • Créer un élément TileService
  • Tester une carte sur un appareil
  • Prévisualiser l'interface utilisateur d'une carte dans Android Studio
  • Développer l'interface utilisateur d'une carte
  • Ajouter des images
  • Gérer les interactions

Conditions préalables

  • Connaissances de base du langage Kotlin

2. Configuration

Au cours de cette étape, vous configurerez votre environnement et téléchargerez le projet de démarrage.

Ce dont vous avez besoin

  • Android Studio Dolphin (2021.3.1) ou version ultérieure
  • Appareil ou émulateur Wear OS

Si vous ne savez pas comment utiliser Wear OS, nous vous recommandons de lire ce guide rapide avant de commencer. Il contient des instructions pour configurer un émulateur Wear OS et décrit comment naviguer dans le système.

Télécharger le code

Si git est installé, vous pouvez simplement exécuter la commande ci-dessous pour cloner le code à partir de ce dépôt. Pour vérifier s'il est installé, saisissez git –version dans le terminal ou la ligne de commande, et assurez-vous qu'il fonctionne correctement.

git clone https://github.com/android/codelab-wear-tiles.git
cd wear-tiles

Si vous n'avez pas git, cliquez sur le bouton ci-dessous pour télécharger l'ensemble du code de cet atelier de programmation :

Télécharger le fichier ZIP

Ouvrir un projet dans Android Studio

Dans la fenêtre "Bienvenue dans Android Studio", sélectionnez c01826594f360d94.png Ouvrir un projet existant ouFichier > Ouvrir, puis sélectionnez le dossier [Emplacement de téléchargement].

3. Créer une carte de base

Le point d'entrée d'une carte est le service de cartes. Au cours de cette étape, vous allez enregistrer un service de cartes et définir une mise en page de carte.

HelloWorldTileService

Une classe qui implémente TileService doit spécifier deux fonctions :

  • onResourcesRequest(requestParams: ResourcesRequest): ListenableFuture<Resources>
  • onTileRequest(requestParams: TileRequest): ListenableFuture<Tile>

La première mappe les ID de chaîne par rapport à une ressource image. C'est là que les ressources image que nous utiliserons dans la carte sont fournies.

La seconde renvoie la description d'une carte, y compris sa mise en page. C'est là que nous définirons la mise en page d'une carte et la manière dont les données y sont liées.

Ouvrez HelloWorldTileService.kt à partir du module start. Toutes les modifications que vous allez apporter seront incluses dans ce module. Si vous voulez voir le résultat de cet atelier de programmation, il existe également un module finished.

HelloWorldTileService complète CoroutinesTileService, un wrapper compatible avec la coroutine Kotlin issu de la bibliothèque Horologist Tiles. Horologist est un groupe de bibliothèques Google visant à fournir aux développeurs Wear OS des fonctionnalités complémentaires qui sont couramment plébiscitées, mais qui ne sont pas encore disponibles dans Jetpack.

CoroutinesTileService fournit deux fonctions de suspension, qui sont des versions de coroutine des fonctions de TileService :

  • suspend resourcesRequest(requestParams: ResourcesRequest): Resources
  • suspend tileRequest(requestParams: TileRequest): Tile

Pour en savoir plus sur les coroutines, consultez la documentation sur les coroutines Kotlin sur Android.

HelloWorldTileService n'est pas encore terminé. Nous devons enregistrer le service dans notre fichier manifeste et fournir également une implémentation pour tileLayout.

Enregistrer le service de cartes

Il est nécessaire d'enregistrer le service de cartes dans le fichier manifeste pour que le système le reconnaisse. Une fois enregistré, il apparaît dans la liste des cartes que l'utilisateur peut ajouter.

Ajoutez <service> dans l'élément <application> :

start/src/main/AndroidManifest.xml

<service
    android:name="com.example.wear.tiles.hello.HelloWorldTileService"
    android:icon="@drawable/ic_waving_hand_24"
    android:label="@string/hello_tile_label"
    android:description="@string/hello_tile_description"
    android:exported="true"
    android:permission="com.google.android.wearable.permission.BIND_TILE_PROVIDER">

    <intent-filter>
        <action android:name="androidx.wear.tiles.action.BIND_TILE_PROVIDER" />
    </intent-filter>

    <!-- The tile preview shown when configuring tiles on your phone -->
    <meta-data
        android:name="androidx.wear.tiles.PREVIEW"
        android:resource="@drawable/tile_hello" />
</service>

L'icône et le libellé sont utilisés (comme des espaces réservés) lors du chargement initial de la carte ou en cas d'erreur lors du chargement. Les métadonnées à la fin définissent une image d'aperçu qui s'affiche dans le carrousel lorsque l'utilisateur ajoute une carte.

Définir la mise en page de la carte

HelloWorldTileService possède une fonction appelée tileLayout avec l'élément TODO() comme corps. Nous allons maintenant remplacer cela par une implémentation dans laquelle nous définirons la mise en page de la carte et associerons des données :

start/src/main/java/com/example/wear/tiles/hello/HelloWorldTileService.kt

private fun tileLayout(): LayoutElement {
    val text = getString(R.string.hello_tile_body)
    return LayoutElementBuilders.Box.Builder()
        .setVerticalAlignment(LayoutElementBuilders.VERTICAL_ALIGN_CENTER)
        .setWidth(DimensionBuilders.expand())
        .setHeight(DimensionBuilders.expand())
        .addContent(
            LayoutElementBuilders.Text.Builder()
                .setText(text)
                .build()
        )
        .build()
}

Nous créons un élément Text et le définissons dans un élément Box afin de pouvoir effectuer un alignement de base.

Et voilà notre première carte Wear OS créée. Installons cette carte et voyons ce à quoi elle ressemble.

4. Tester votre carte sur un appareil

Une fois le module de démarrage sélectionné dans le menu déroulant de la configuration d'exécution, vous pouvez installer l'application (module start) sur votre appareil ou dans un émulateur, puis installer manuellement la carte, comme le ferait un utilisateur.

À la place, nous allons utiliser Direct Surface Launch, une fonctionnalité ajoutée avec Android Studio Dolphin, qui permet de créer une configuration d'exécution afin de lancer la carte directement depuis Android Studio. Sélectionnez "Modifier les configurations" dans le menu déroulant du panneau supérieur.

Menu déroulant de modification de la configuration dans le panneau supérieur d'Android Studio. L'option "Modifier les configurations" est mise en surbrillance.

Cliquez sur le bouton "Ajouter une configuration", puis sélectionnez "Carte Wear OS". Ajoutez un nom descriptif, puis sélectionnez le module Tiles_Code_Lab.start et la carte HelloWorldTileService.

Appuyez sur "OK" pour terminer.

Menu de modification de la configuration avec une carte Wear OS appelée HelloTile en cours de configuration.

Direct Surface Launch permet de tester rapidement les cartes dans un émulateur Wear OS ou sur un appareil physique. Testez-le par vous-même en exécutant "HelloTile". Une capture d'écran semblable à celle ci-dessous devrait s'afficher.

Montre ronde indiquant que l'heure est venue de créer une carte en texte blanc sur fond noir

5. Créer une carte de messages

Montre ronde avec cinq boutons ronds disposés en pyramide de type 2x3. Les 1er et 3e boutons affichent des initiales en violet, les 2e et 4e images affichent des photos de profil, et le dernier bouton est une icône de recherche. Sous les boutons, un chip compact violet affiche le texte "New" (Nouveau) en noir.

La carte de messages que nous allons créer s'apparente davantage à une carte réelle. Contrairement à l'exemple HelloWorld, celui-ci charge les données à partir d'un dépôt local, extrait les images à afficher à partir du réseau et gère les interactions pour ouvrir l'application, directement à partir de la carte.

MessagingTileService

MessagingTileService complète la classe CoroutinesTileService que nous avons vue précédemment.

La principale différence entre cet exemple et l'exemple précédent est que nous observons désormais des données provenant du dépôt et que nous récupérons également les données image à partir du réseau.

Pour toute tâche potentiellement longue (appels réseau, par exemple), il serait plus approprié d'utiliser un outil comme WorkManager, car les fonctions des services de carte ont des délais d'attente relativement courts. Cet atelier de programmation ne couvre pas l'utilisation de WorkManager. Pour en savoir plus, consultez cet atelier de programmation.

MessagingTileRenderer

MessagingTileRenderer complète la classe TileRenderer (autre abstraction de la bibliothèque Horologist Tiles). Il est totalement synchrone. Autrement dit, l'état est transmis aux fonctions du moteur de rendu, ce qui facilite l'utilisation dans les tests et les aperçus Android Studio.

À l'étape suivante, nous verrons comment ajouter des aperçus Android Studio pour des cartes.

6. Ajouter des fonctions d'aperçu

Vous pouvez afficher un aperçu de l'interface utilisateur d'une carte dans Android Studio avec TileLayoutPreview (et similaire) à partir de la bibliothèque Horologist Tiles. Cette approche permet de raccourcir la boucle de rétroaction lors du développement de l'interface utilisateur, ce qui accélère considérablement l'itération.

Nous utiliserons les outils de Jetpack Compose pour afficher cet aperçu. C'est pourquoi l'annotation @Composable s'affiche sur la fonction d'aperçu ci-dessous. Vous pouvez vous familiariser davantage avec les aperçus modulables si vous le souhaitez. Toutefois, vous n'avez pas besoin de suivre cet atelier de programmation.

Ajoutez un aperçu modulable pour MessagingTileRenderer à la fin du fichier.

start/src/main/java/com/example/wear/tiles/messaging/tile/MessagingTileRenderer.kt

@WearDevicePreview
@Composable
fun MessagingTileRendererPreview() {
    TileLayoutPreview(
        state = MessagingTileState(MessagingRepo.knownContacts),
        resourceState = emptyMap(),
        renderer = MessagingTileRenderer(LocalContext.current)
    )
}

Notez que la fonction modulable utilise TileLayoutPreview. Il n'est pas possible d'afficher directement un aperçu de la mise en page des cartes.

Utilisez la vue d'écran partagé pour afficher un aperçu de la carte :

Vue d'écran partagé d'Android Studio avec aperçu du code à gauche et image de la carte à droite.

Nous transmettons des données artificielles dans MessagingTileState et nous n'avons pas (encore) d'état de ressource. Nous pouvons donc transmettre une map vide.

À l'étape suivante, nous utiliserons Tiles Material pour mettre à jour la mise en page.

7. Ajouter Tiles Material

Tiles Material propose des composants et des mises en page prédéfinis qui vous permettent de créer des cartes utilisant les dernières consignes Material Design pour Wear OS.

Ajoutez la dépendance Tiles Material au fichier build.gradle :

start/build.gradle

implementation "androidx.wear.tiles:tiles-material:$tilesVersion"

Selon la complexité de votre conception, il peut être utile de localiser au même endroit le code de mise en page avec le moteur de rendu, en utilisant des fonctions de niveau supérieur dans le même fichier pour encapsuler une unité logique de l'interface utilisateur.

Ajoutez le code du bouton en bas du fichier de moteur de rendu, ainsi que l'aperçu :

start/src/main/java/MessagingTileRenderer.kt

private fun searchLayout(
    context: Context,
    clickable: ModifiersBuilders.Clickable,
) = Button.Builder(context, clickable)
    .setContentDescription(context.getString(R.string.tile_messaging_search))
    .setIconContent(MessagingTileRenderer.ID_IC_SEARCH)
    .setButtonColors(ButtonColors.secondaryButtonColors(MessagingTileTheme.colors))
    .build()

@IconSizePreview
@Composable
private fun SearchButtonPreview() {
    LayoutElementPreview(
        searchLayout(
            context = LocalContext.current,
            clickable = emptyClickable
        )
    ) {
        addIdToImageMapping(
            MessagingTileRenderer.ID_IC_SEARCH,
            drawableResToImageResource(R.drawable.ic_search_24)
        )
    }
}

LayoutElementPreview est semblable à TileLayoutPreview, mais est destiné à des composants individuels tels qu'un bouton, un chip ou un libellé. Le lambda final tout à la fin nous permet de spécifier le mappage de l'ID de ressource (avec les ressources image). Ici, nous mappons ID_IC_SEARCH avec la ressource image illustrant un bouton de recherche.

La vue d'écran partagé offre un aperçu du bouton de recherche :

Ensemble d'aperçus empilés verticalement, avec une carte en haut et un bouton d'icône de recherche en dessous.

Nous pouvons procéder de la même manière pour créer la mise en page des contacts :

start/src/main/java/com/example/wear/tiles/messaging/tile/MessagingTileRenderer.kt

private fun contactLayout(
    context: Context,
    contact: Contact,
    clickable: ModifiersBuilders.Clickable,
) = Button.Builder(context, clickable)
    .setContentDescription(contact.name)
    .apply {
        if (contact.avatarUrl != null) {
            setImageContent(contact.imageResourceId())
        } else {
            setTextContent(contact.initials)
            setButtonColors(ButtonColors.secondaryButtonColors(MessagingTileTheme.colors))
        }
    }
    .build()

Tiles Material ne se limite pas aux composants. Au lieu d'utiliser une série de colonnes et de lignes imbriquées, nous pouvons utiliser les mises en page de Tiles Material pour obtenir rapidement l'aspect souhaité.

Ici, nous pouvons utiliser PrimaryLayout et MultiButtonLayout pour organiser quatre contacts et le bouton de recherche. Mettez à jour la fonction messagingTileLayout() dans MessagingTileRenderer avec les mises en page suivantes :

start/src/main/java/com/example/wear/tiles/messaging/tile/MessagingTileRenderer.kt

private fun messagingTileLayout(
    context: Context,
    deviceParameters: DeviceParametersBuilders.DeviceParameters,
    state: MessagingTileState
) = PrimaryLayout.Builder(deviceParameters)
    .setContent(
        MultiButtonLayout.Builder()
            .apply {
                // In a PrimaryLayout with a compact chip at the bottom, we can fit 5 buttons.
                // We're only taking the first 4 contacts so that we can fit a Search button too.
                state.contacts.take(4).forEach { contact ->
                    addButtonContent(
                        contactLayout(
                            context = context,
                            contact = contact,
                            clickable = emptyClickable
                        )
                    )
                }
            }
            .addButtonContent(searchLayout(context, emptyClickable))
            .build()
    )
    .build()

Aperçu d'une carte avec cinq boutons dans une pyramide de type 2x3. Les deuxième et troisième boutons sont des cercles bleus indiquant des images manquantes.

MultiButtonLayout accepte jusqu'à sept boutons et les dispose automatiquement en les espaçant de manière appropriée. Ajoutons également le chip "New" (Nouveau) dans PrimaryLayout, au niveau du compilateur PrimaryLayout dans la fonction messagingTileLayout() :

start/src/main/java/com/example/wear/tiles/messaging/tile/MessagingTileRenderer.kt

.setPrimaryChipContent(
    CompactChip.Builder(
        /* context = */ context,
        /* text = */ context.getString(R.string.tile_messaging_create_new),
        /* clickable = */ emptyClickable,
        /* deviceParameters = */ deviceParameters
    )
        .setChipColors(ChipColors.primaryChipColors(MessagingTileTheme.colors))
        .build()
)

Aperçu d'une carte avec cinq boutons et chip compact en dessous qui contient le texte "New" (Nouveau)

À l'étape suivante, nous allons résoudre le problème d'images manquantes.

8. Ajouter des images

L'affichage d'une image locale sur une carte est une tâche simple : il suffit de créer un mappage avec l'image à partir d'un ID de chaîne (que vous utilisez dans la mise en page), en utilisant la fonction utile Horologist Tiles pour charger le drawable et le convertir en ressource image. Un exemple est disponible dans SearchButtonPreview :

start/src/main/java/com/example/wear/tiles/messaging/tile/MessagingTileRenderer.kt

addIdToImageMapping(
    ID_IC_SEARCH,
    drawableResToImageResource(R.drawable.ic_search_24)
)

Pour la carte de messages, nous devons également charger des images depuis le réseau (et pas uniquement des ressources locales). Pour cela, nous utiliserons Coil, un chargeur d'images basé sur les coroutines Kotlin.

Le code requis est déjà écrit :

start/src/main/java/com/example/wear/tiles/messaging/tile/MessagingTileService.kt

override suspend fun resourcesRequest(requestParams: ResourcesRequest): Resources {
    val avatars = imageLoader.fetchAvatarsFromNetwork(
        context = this@MessagingTileService,
        requestParams = requestParams,
        tileState = latestTileState()
    )
    return renderer.produceRequestedResources(avatars, requestParams)
}

Étant donné que le moteur de rendu des cartes est entièrement synchrone, le service de cartes extrait les bitmaps à partir du réseau. Comme mentionné précédemment, en fonction de la taille de l'image, il peut être plus approprié d'utiliser WorkManager afin de récupérer les images à l'avance. Toutefois, pour cet atelier de programmation, nous les récupérerons directement.

Nous transmettons la map avatars (Contact à Bitmap) au moteur de rendu en tant qu'"état" pour les ressources. Le moteur de rendu peut désormais convertir ces bitmaps en ressources image pour les cartes.

Ce code est déjà écrit :

start/src/main/java/com/example/wear/tiles/messaging/tile/MessagingTileRenderer.kt

override fun ResourceBuilders.Resources.Builder.produceRequestedResources(
    resourceState: Map<Contact, Bitmap>,
    deviceParameters: DeviceParametersBuilders.DeviceParameters,
    resourceIds: MutableList<String>
) {
    addIdToImageMapping(
        ID_IC_SEARCH,
        drawableResToImageResource(R.drawable.ic_search_24)
    )

    resourceState.forEach { (contact, bitmap) ->
        addIdToImageMapping(
            /* id = */ contact.imageResourceId(),
            /* image = */ bitmap.toImageResource()
        )
    }
}

Si le service récupère les bitmaps et que le moteur de rendu les convertit en ressources image, pourquoi la carte n'affiche-t-elle pas les images ?

Les images s'affichent. Si vous exécutez la carte sur un appareil (avec accès à Internet), les images devraient se charger. Le problème se situe uniquement dans notre aperçu, car nous transmettons toujours un élément emptyMap() pour resourceState.

Dans la carte réelle, nous récupérons les bitmaps à partir du réseau et les mappons avec les différents contacts. Toutefois, pour les aperçus et les tests, nous n'avons pas du tout besoin d'appeler le réseau.

Mettez à jour MessagingTileRendererPreview() afin de fournir des bitmaps aux deux contacts qui en ont besoin :

start/src/main/java/com/example/wear/tiles/messaging/tile/MessagingTileRenderer.kt

@WearDevicePreview
@Composable
fun MessagingTileRendererPreview() {
    val state = MessagingTileState(MessagingRepo.knownContacts)
    val context = LocalContext.current
    TileLayoutPreview(
        state = state,
        resourceState = mapOf(
            state.contacts[1] to (context.getDrawable(R.drawable.ali) as BitmapDrawable).bitmap,
            state.contacts[2] to (context.getDrawable(R.drawable.taylor) as BitmapDrawable).bitmap,
        ),
        renderer = MessagingTileRenderer(context)
    )
}

À présent, si nous actualisons l'aperçu, les images devraient s'afficher :

Aperçu d'une carte avec cinq boutons, cette fois-ci avec des photos à la place des deux boutons bleus

À l'étape suivante, nous traiterons les clics sur chacun des éléments.

9. Gérer les interactions

Les raccourcis vers les parcours utilisateur les plus importants sont l'un des principaux atouts d'une carte. À ne pas confondre avec le lanceur d'applications, qui ouvre simplement l'application ! Dans le cas présent, nous avons l'espace nécessaire pour fournir des raccourcis contextuels sur un écran spécifique de votre application.

Jusqu'à présent, nous avons utilisé emptyClickable pour le chip et chacun des boutons. Cette approche convient pour les aperçus, qui ne sont pas interactifs, mais voyons comment ajouter des actions correspondant aux éléments.

Deux compilateurs de la classe "ActionBuilders" définissent des actions cliquables : LoadAction et LaunchAction.

LoadAction

Un élément LoadAction peut être utilisé si vous souhaitez exécuter la logique dans le service de cartes lorsque l'utilisateur clique sur un élément, par exemple en incrémentant un compteur.

.setClickable(
    Clickable.Builder()
        .setId(ID_CLICK_INCREMENT_COUNTER)
        .setOnClick(ActionBuilders.LoadAction.Builder().build())
        .build()
    )
)

Lorsque vous cliquez dessus, onTileRequest est appelé dans votre service (tileRequest dans CoroutinesTileService). Il s'agit donc d'une bonne occasion d'actualiser l'interface utilisateur de la carte :

override suspend fun tileRequest(requestParams: TileRequest): Tile {
    if (requestParams.state.lastClickableId == ID_CLICK_INCREMENT_COUNTER) {
        // increment counter
    }
    // return an updated tile
}

LaunchAction

L'élément LaunchAction peut être utilisé pour lancer une activité. Dans MessagingTileRenderer, mettons à jour le bouton cliquable pour la recherche.

Le bouton de recherche est défini par la fonction searchLayout() dans MessagingTileRenderer. Un élément Clickable est déjà utilisé comme paramètre, mais jusqu'à présent, nous avons transmis emptyClickable, une implémentation non opérationnelle qui ne fait rien lorsque l'utilisateur clique sur le bouton.

Mettons à jour messagingTileLayout() afin qu'il transmette une action de clic réelle. Ajoutez le paramètre searchButtonClickable et transmettez-le à searchLayout() :

start/src/main/java/com/example/wear/tiles/messaging/tile/MessagingTileRenderer.kt

private fun messagingTileLayout(
    context: Context,
    deviceParameters: DeviceParametersBuilders.DeviceParameters,
    state: MessagingTileState,
    searchButtonClickable: ModifiersBuilders.Clickable
...
    .addButtonContent(searchLayout(context, searchButtonClickable))

Nous devons également mettre à jour renderTile, où nous appelons messagingTileLayout, car nous venons d'ajouter un nouveau paramètre (searchButtonClickable). Nous utiliserons la fonction launchActivityClickable() pour créer un élément cliquable, en transmettant l'ActionBuilder openSearch() comme action :

start/src/main/java/com/example/wear/tiles/messaging/tile/MessagingTileRenderer.kt

override fun renderTile(
    state: MessagingTileState,
    deviceParameters: DeviceParametersBuilders.DeviceParameters
): LayoutElementBuilders.LayoutElement {
    return messagingTileLayout(
        context = context,
        deviceParameters = deviceParameters,
        state = state,
        searchButtonClickable = launchActivityClickable("search_button", openSearch())
    )
}

Ouvrez launchActivityClickable pour voir ces fonctions (déjà définies) à l'œuvre :

start/src/main/java/com/example/wear/tiles/messaging/tile/ClickableActions.kt

internal fun launchActivityClickable(
    clickableId: String,
    androidActivity: ActionBuilders.AndroidActivity
) = ModifiersBuilders.Clickable.Builder()
    .setId(clickableId)
    .setOnClick(
        ActionBuilders.LaunchAction.Builder()
            .setAndroidActivity(androidActivity)
            .build()
    )
    .build()

Cet élément est très semblable à LoadAction, la principale différence étant que nous appelons setAndroidActivity. Le même fichier contient plusieurs exemples ActionBuilder.AndroidActivity.

Pour openSearch, que nous utilisons pour cet élément cliquable, nous appelons setMessagingActivity et nous transmettons un extra de type "chaîne" afin d'identifier quel clic a eu lieu sur le bouton.

start/src/main/java/com/example/wear/tiles/messaging/tile/ClickableActions.kt

internal fun openSearch() = ActionBuilders.AndroidActivity.Builder()
    .setMessagingActivity()
    .addKeyToExtraMapping(
        MainActivity.EXTRA_JOURNEY,
        ActionBuilders.stringExtra(MainActivity.EXTRA_JOURNEY_SEARCH)
    )
    .build()

...

internal fun ActionBuilders.AndroidActivity.Builder.setMessagingActivity(): ActionBuilders.AndroidActivity.Builder {
    return setPackageName("com.example.wear.tiles")
        .setClassName("com.example.wear.tiles.messaging.MainActivity")
}

Exécutez la carte, puis cliquez sur le bouton de recherche. Il devrait ouvrir MainActivity et afficher du texte pour confirmer que l'utilisateur a cliqué sur le bouton de recherche.

L'ajout d'actions pour les autres éléments est similaire. ClickableActions contient les fonctions dont vous avez besoin. Si vous avez besoin d'aide, consultez la section MessagingTileRenderer du module finished.

10. Félicitations

Félicitations ! Vous avez appris à créer une carte pour Wear OS.

Et maintenant ?

Pour en savoir plus, consultez les implémentations Golden Tiles sur GitHub et le guide des cartes Wear OS.