Développement sur Android Wear et Interaction avec les google play services

Android-Wear

Nous avons vu dans l'article synchronisation entre un téléphone android et une android wear  que l'envoi des notifications était le moyen le plus simple d'interagir entre le téléphone et la montre.
Cependant, le design des notifications est simple et peu personnalisable. La seconde solution consiste donc à créer sa propre application dédiée à la montre et de communiquer grâce aux Google play services.

Développement d’une application dédiée à la montre

Etant donné la taille de l'écran par rapport à une montre, il est nécessaire de repenser complètement le design de l'application. En effet, sur une Android Wear, l'application doit contenir le minimum d'informations, lisibles en un coup d'œil et contextuelles (https://developer.android.com/training/wearables/apps/index.html ). Ainsi, une application qui est développée sur téléphone ne permet pas de répondre à ces trois critères.

Pour développer une application sur Android Wear, il suffit simplement de créer un projet ou un module Wear sous Android studio.

projetWear

Ensuite Android studio nous génère la hiérarchie du projet suivante :

hiérarchie d'un projet Android Wear

hiérarchie d'un projet Android Wear

Comme vous pouvez le remarquer cette hiérarchie est semblable au projet Android classique. Il y a un dossier source avec des fichiers java, un dossier ressource contenant plusieurs sous-dossier tels que le sous-dossier layout, drawable. Un nouveau groupement de ressource apparaît, c'est le dossier mipmap. Ce dossier regroupe les différentes icônes du projet.

De plus dans ce projet, la bibliothèque d'UI pour montre est directement incluse dans le projet. Ainsi, il est possible de générer un fichier de layout préfixé par rect_ pour design les montres rectangulaires et par round_ pour les montres arrondies. Ainsi, on peut réaliser une application visible en un coup d'œil pour n'importe quel type de montre.

Bien sûr, il est possible d'intégrer cette bibliothèque dans la liste des dépendances gradle dans le fichier build.gradle :

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.google.android.support:wearable:1.1.0'
    compile 'com.google.android.gms:play-services-wearable:6.5.87'
}

Le reste du développement Android Wear est similaire à celui du développement Android classique.

Une fois votre application Android Wear créée, nous pouvons passer à la seconde partie de cet article qui est la communication entre le téléphone Android et la montre.

La communication entre le téléphone et la montre via les google play services

La communication entre une application sur la montre Android et un téléphone Android peut se faire grâce aux google play service et plus particulièrement à trois API incluses dans ces services:

  • Une qui permet de connaitre tous les nœuds connectés à un appareil. Ainsi, on peut connaître des informations complémentaires sur les appareils qui sont connectés.
  • MessageAPI qui permet d'envoyer des informations courtes à tous les nœuds sans forcement savoir s'il a bien reçu le message.
  • DataAPI qui permet d'envoyer des informations (string, images, ...) sous la forme d'une map, c'est-à-dire d'un ensemble de clés-valeurs. De plus, grâce à cette API, il est possible d'envoyer ces données de manière asynchrone et de savoir si elles ont été bien reçues par les nœuds.

Ainsi pour implémenter ces trois API (attention les trois ne sont pas obligatoires, vous pouvez très bien implémenter seulement la DataAPI) il faut d'abord inclure la dépendance com.google.android.gms:play-services-wearable dans la liste des dépendances gradle.

Nous allons maintenant commencer à développer l'échange des communications entre le téléphone et la montre. Pour cela, on commence par enregistrer les appareils sur un nœud, ensuite nous allons envoyer des informations puis nous allons recevoir ces informations.

Enregistrement sur un nœud

Pour cela, on utilise le googleAPIClient qui fournit un builder. Sur ce builder, on précise que l'api Wearable, et on enregistre deux listenners: un pour la connexion réussie et un autre pour l'échec de la connexion.

public class MyService extends Service implements GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener{
    @Override
    public void onCreate() {
        super.onCreate();
        GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(Wearable.API) 
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();
        mGoogleApiClient.connect();
    }

    @Override
    public void onConnected(Bundle bundle) {
        // Connection du GoogleAPiClient Succeed
    }

    @Override
    public void onConnectionSuspended(int i) {
        // Connection du GoogleAPiClient Suspended

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        // Connection du GoogleAPiClient failed

    }
}

Une fois le client Google connecté sur chaque appareil, on peut envoyer et recevoir facilement des messages ou des données aux autres.

Envoi de messages et de données

Parmi les trois API du google play services, la MessageAPI permet d'envoyer des messages synchrones et la dataAPI permet d'envoyer des données de façon asynchrone. Nous allons donc voir comment on peut envoyer des données grâce à ces deux API.

L'API messageAPI fournit une fonction sendMessage() qui permet d'envoyer un message court sur tous les nœuds. Cette fonction prend en charge :

  • Le GoogleAPI Client
  • Une chaîne de caractères représentant l’identifiant d’un nœud existant
  • Une chaîne de caractères représentant le chemin du message
  • Un tableau de bytes représentant les données à envoyer

Le code suivant permet d’envoyer un message du téléphone vers la montre afin de démarrer l’activité principale sans données à l’intérieur.

Wearable.MessageApi.sendMessage(mGoogleApiClient, "blabla", "/start-activity", new byte[0]);

La DataApi fournit aussi une fonction putDataItem() qui permet d'envoyer un objet DataMapRequest qui contient un Uri (c'est-à-dire un chemin vers une ressource) et une map qui représente la ressource.

La dataAPI permet aussi de savoir si les données ont bien été reçues grâce à un resultCallback.

Le code suivant crée une DataMapRequest avec le chemin /update-song et avec les données de la nouvelle chanson.

public void sendInfo(Song song){
    PutDataMapRequest dataMap = PutDataMapRequest.create("/update-song");
    dataMap.getDataMap().putString("Titre",song.getTitle());
    dataMap.getDataMap().putString("Album", song.getAlbum());
    dataMap.getDataMap().putString("Artiste", song.getArtist());
    Wearable.DataApi.putDataItem(mGoogleApiClient, dataMap.asPutDataRequest()).
                setResultCallback(new ResultCallback() {
                    @Override
                    public void onResult(DataApi.DataItemResult dataItemResult) {
                            Log.d("Service", "Sending data was successful: " + dataItemResult.getStatus()
                            .isSuccess());
                     }
           });
    }
}

Maintenant que nous avons envoyé les données, nous allons voir comment recevoir ces données.

Réception des données

Afin d’éviter de perdre des données et des messages, il est conseillé d’utiliser des services qui permettront d’ouvrir l’application lorsqu’elle est en tâche de fond ou même complètement fermée. De plus, Google a développé un service nommé WearableListenerService. Ce service implémente déjà les interfaces nécessaires à la réception de données.

En effet, pour traiter les données, il faut ajouter Listenner pour chaque API et utiliser et implémenter des fonctions permettant de les traiter.

Le code ci dessous permet d’ajouter les Listenners lorsque le GoogleAPIClient est connecté

@Override
public void onConnected(Bundle bundle) {
     // Connection du GoogleAPiClient Succeed
    Wearable.MessageApi.addListener(mGoogleApiClient, this);
    Wearable.DataApi.addListener(mGoogleApiClient, this);
}

Une fois les listenner ajoutés, il suffit de définir les actions à réaliser en fonction des données reçues. Ces actions sont définies :

  • Soit dans la méthode onMessageReceived(MessageEvent messageEvent) pour les messages envoyés
  • Soit dans la méthode onDataChanged(DataEventBuffer dataEvents) pour les données reçues

On peut alors traiter les événements reçus. Un messageEvent contient un chemin et un tableau de bytes et un DataEventBuffer est un ensemble d'événements ; il faut donc traiter tous les événements et regarder leur URI pour extraire la bonne DataMap.

Le code ci-dessous parcourt tous les événements et traite uniquement ceux qui ont l’URI udapte-song.

public void onDataChanged(DataEventBuffer dataEvents) {
        Log.d(TAG, "onDataChanged(): " + dataEvents);
        final List events = FreezableUtils.freezeIterable(dataEvents);
        dataEvents.close();
        for (DataEvent event : events) {
            String path = event.getDataItem().getUri().getPath();
            if ("update-song".equals(path)) {
                DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem());
                TextView txTitle = (TextView) findViewById(R.id.title);
                TextView txAlbum = (TextView) findViewById(R.id.album);
                TextView txArtiste = (TextView) findViewById(R.id.artist);
                txTitle.setText(dataMapItem.getDataMap().getString("Titre"));
                txAlbum.setText(dataMapItem.getDataMap().getString("Album"));
                txArtiste.setText(dataMapItem.getDataMap().getString("Artiste"));
            }
        }
}

Conclusion

A travers cet article, nous avons vu comment créer une application Android Wear et la faire communiquer avec un téléphone et cela grâce aux google play services. Ainsi la montre peut envoyer et recevoir n'importe quel type de données (images, chaîne de caractères, ... ).
Vous pouvez maintenant construire des applications mobiles compatibles avec une autre application Wear.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.