Avant de passer à l'activité notée, nous vous proposons dans ce chapitre de réaliser une application sur montre connectée qui récupère une image géolocalisée depuis Flickr. Cela vous permettra de vous entraîner avec toutes les notions vues dans cette partie et d'attaquer l'activité notée en toute sérénité. Le fonctionnement sera le suivant :
la montre connectée envoie un message au téléphone pour demander l'image ;
le téléphone se géolocalise, puis fait une requête vers Flickr pour récupérer l'image ;
l'image récupérée est envoyée à la montre connectée pour affichage.
On voit que ce fonctionnement est un peu compliqué car il y a beaucoup de messages à mettre en œuvre, dont un qui contient une image. L'avantage d'un tel procédé est que le téléphone peut réaliser des traitements sur l'image, avant de les transmettre à la montre (par exemple rétrécir l'image). Allez, c'est parti !
Étape 1: Création des layouts
Générez un nouveau projet Android Studio comportant deux applications, une pour le téléphone, l'autre pour la montre.
Créez l'interface graphique minimale suivante pour la montre connectée :
Un LinearLayout comportant
un TextView pour afficher un texte introductif ;
un bouton "Get an image !" ;
(optionnel) une ProgressBar que l'on fera apparaître pendant que la requête s'exécute ;
un ImageView pour l'image qu'il faudra afficher à la fin.
À ce stade, votre layout va ressembler à :

Créez ensuite l'interface graphique du côté du mobile :
un TextView expliquant que l'on visualise l'image à envoyer sur cet écran ;
un ImageView qui permettra d'afficher l'image reçue.
On obtient quelque chose du genre :
Étape 2 : Requête de la montre au téléphone
Dans cette étape, la montre va envoyer un message au téléphone pour que celui-ci se mette à télécharger l'image.
Envoi du message
Ce message utiliser MessageClient
pour envoyer un message au téléphone :
MessageClient clientMessage = Wearable.getMessageClient(this);
clientMessage.sendMessage(node.getId(),"I need a local image of a monument !", null);
Dans cet envoi de message, seul le "path" (qui vaut ici "I need a local image of a monument !") est important et on n'a pas besoin de mettre des données en troisième argument. Avec ce "path" on pourra filtrer le message côté mobile.
Mais avant de pouvoir envoyer un message, il faut identifier l'id du node correspondant à la montre. Comme vu dans le cours, il faut chercher les noeuds à l'aide du CapabilityClient
:
CapabilityClient capabilityClient = Wearable.getCapabilityClient(this);
Task<Map<String, CapabilityInfo>> capabilitiesTask =
capabilityClient.getAllCapabilities(CapabilityClient.FILTER_REACHABLE);
capabilitiesTask.addOnSuccessListener(
...
);
Réalisez l'envoi du message dans le bouton de la montre connectée.
Réception du message
Du côté du mobile, votre activité va filtrer les messages reçus. Pour ce faire, implémenter l'interface MessageClient.OnMessageReceivedListener
:
public class MainActivity extends AppCompatActivity implements MessageClient.OnMessageReceivedListener {
Dans la méthode onPostResume()
, ajoutez l'écouteur :
Wearable.getMessageClient(this).addListener(this);
Enfin, dans la méthode onMessageReceived()
:
@Override
public void onMessageReceived(@NonNull MessageEvent messageEvent) {
Log.d("CIO", "Message received: " + messageEvent.getPath());
...
}
Et surtout, ne pas oublier de déclarer une capability "my_capability" dans le fichier res/values/wear.xml afin que le téléphone notifie la montre de cette capacité.
Vous devriez voir arriver le message depuis la montre connectée quand vous appuyez sur votre bouton.
Étape 3: récupération d'une image géolocalisée
En vous inspirant du code du TP de la partie précédente (chapitre 4), vous pouvez recoder une requête vers Flickr pour récupérer une image dépendant de votre géolocalisation. Pour ce faire, il faut :
avoir les permissions pour se géolocaliser ;
réaliser une requête vers Flickr pour obtenir un objet JSON répertoriant des images ;
choisir une des images et la télécharger.
Une fois l'image BitMap récupérée, affichez-la dans l'ImageView
du téléphone mobile.
Étape 4: transfert de l'image à la montre
Dans cette étape, nous allons transférer l'image comme un asset à la montre connectée. Pour se faire, nous allons utiliser, comme vu en cours, un objet DataClient
.
Envoi de l'image
Dans votre activité principale du mobile, créez et stockez l'objet DataClient
:
private DataClient dataClient;
protected void onCreate(Bundle savedInstanceState) {
...
dataClient = Wearable.getDataClient(this);
}
Puis, à l'endroit où votre BitMap
a été téléchargée, nous allons créer le requête pour envoyer l'image :
Asset asset = toAsset(bitmap);
PutDataMapRequest dataMap = PutDataMapRequest.create("/image");
dataMap.getDataMap().putAsset("my_image", asset);
dataMap.getDataMap().putLong("time", new Date().getTime());
PutDataRequest request = dataMap.asPutDataRequest();
request.setUrgent();
Log.i("CIO", "Preparing task...");
Task<DataItem> dataItemTask = dataClient.putDataItem(request);
dataItemTask.addOnSuccessListener(new OnSuccessListener<DataItem>() {
@Override
public void onSuccess(DataItem dataItem) {
Log.i("CIO", "Sent image: " + dataItem);
}
});
Réception de l'image
Du côté de votre application de montre connectée, votre activité principale va implémenter DataClient.OnDataChangedListener
:
public class MainActivity extends WearableActivity implements DataClient.OnDataChangedListener
Cela implique d'enregistrer un écouteur pour les événements de donnée :
@Override
protected void onResume() {
super.onResume();
Wearable.getDataClient(this).addListener(this);
}
Implémenter alors la méthode qui récupère l'image :
@Override
public void onDataChanged(@NonNull DataEventBuffer dataEvents) {
Log.i("CIO", "Data changed !");
for (DataEvent event : dataEvents) {
if (event.getType() == DataEvent.TYPE_CHANGED) {
String path = event.getDataItem().getUri().getPath();
Log.i("CIO", " - Path: " + path);
Map<String, DataItemAsset> assets = event.getDataItem().getAssets();
DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem());
Asset asset = dataMapItem.getDataMap()
.getAsset("my_image");
// Load image from asset HERE !
} else {
Log.i("CIO", " - Event type unknown !");
}
}
}
Enfin, en vous inspirant de la classe interne LoadBitmapAsyncTask récupérez l'objet BitMap associé à votre asset et mettez à jour l'ImageView de la montre connectée.
Testez votre application...
Success !!!
