Droidcon 2014 – Android Wear

Une superbe conférence de Mario Viviani, simple et efficace pour comprendre rapidement comment utiliser l’API Wear de Google.
Lorsqu’on veut faire communiquer un smartphone et un « wearable », c’est à dire une montre, un bandeau de mesure du pouls etc, il y’a deux classes essentielles:

DataItem

Comme son nom l’indique, cette classe peut contenir des données (jusqu’à 100kb)et fonctionne sur le principe très simple de la réplication. On crée un objet sur le smartphone et il se synchronise sur le wearable. Le tout avec un simple listener, qui permet de savoir quand le nouveau contenu est disponible.
En quelques lignes…
Il faut tout d’abord initialiser le GoogleApiClient, qui va se connecter à Google Services pour faire la connexion:

mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(Wearable.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();

Il est important de bien faire attention à appeler mGoogleApiClient.start() et mGoogleApiClient.stop() dans les méthodes onStart() et onStop() de nos contextes.

Puis, d’écrire, côté émetteur:

    //On crée une requête basée sur un path et une valeur
    PutDataMapRequest dataMap = PutDataMapRequest.create("/count");
    dataMap.getDataMap().putInt(COUNT_KEY, count++);
    PutDataRequest request = dataMap.asPutDataRequest();
    // On indique à l'API Wear que notre DataItem que l'on a wrappé 
    // dans une PutDataMapRequest est prêt à être synchronisé
    PendingResult<DataApi.DataItemResult> pendingResult = 
        Wearable.DataApi.putDataItem(mGoogleApiClient, request);

Côté récepteur:

@Override
public void onDataChanged(DataEventBuffer dataEvents) {
    //On écoute simplement les événements "onDataChanged" 
    for (DataEvent event : dataEvents) {
        //selon le type d'événement reçu, on traite
        if (event.getType() == DataEvent.TYPE_DELETED) {
            Log.d(TAG, "DataItem deleted: " + event.getDataItem().getUri());
        } else if (event.getType() == DataEvent.TYPE_CHANGED) {
             Log.d(TAG, "DataItem changed: " + event.getDataItem().getUri());
        }
    }
}

Les Messages

De la même façon, pour envoyer un message, on a besoin d’initialiser le GoogleApiClient. Généralement, on veut envoyer le message à une Node, c’est à dire un wearable. Pour récupérer la liste des objets connectés, on peut appeler cette méthode utilitaire:

private Collection<String> getNodes() {
    HashSet <String>results= new HashSet<String>();
    NodeApi.GetConnectedNodesResult nodes = 
        Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await();
    for (Node node : nodes.getNodes()) {
        results.add(node.getId());
    }
    return results;
}

Puis il suffit d’envoyer le message!

...
byte[] message = new String("Hello Oxiane!").getBytes();

SendMessageResult result = Wearable.MessageApi
    .sendMessage(mGoogleApiClient, node, "path_defini_pour_mon_message", message).await();

if (!result.getStatus().isSuccess()) {
    Log.e(TAG, "ERROR: failed to send Message: " + result.getStatus());
}
...

Une petite précision pour compliqué ce qui semble un peu trop facile: la méthode sendMessage est synchrone! Elle ne retourne pas avant d’avoir envoyé le message.

Côté récepteur, on n’a plus qu’à implémenter la méthode onMessageReceived:

@Override
public void onMessageReceived(MessageEvent messageEvent) {
    if (messageEvent.getPath().equals("path_defini_pour_mon_message")) {
       //j'ai reçu mon message! 
    }
}

Pour terminer, Mario nous a présenté une petite librairie de sa conception qui facilite encore plus l’utilisation de l’API wear. Sans avoir pu la tester moi-même,