• 30 hours
  • Medium

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 1/13/20

TP : Récupérez une image géolocalisée depuis une montre connectée !

Log in or subscribe for free to enjoy all this course has to offer!

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 ! :pirate:

É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 à :

Layout pour la montre connectée
Layout pour la montre connectée

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 !!! :lol:

Résultat des deux interfaces
Résultat des deux interfaces
Example of certificate of achievement
Example of certificate of achievement