Prévisions météo, orienté objet
Cahier des charges
Réaliser une application "météo" complète.
- L'application se lance avec un message et un picto d'attente.
- Dès que possible, l'application tente de récupérer la position du terminal et d'envoyer une requete au web-service de WWO.
- Au retour, elle affiche le resultat.
- Pendant qu'elle est active, elle recoit régulièrement une mise à jour de la position et relance une requete au web-service.
Un peu d'anglais :
- Weather : Météo
- Forecast : prévision
- Forecaster : prévisionniste
- To mock : imiter, parodier
- To listen : écouter
- listener : auditeur
Découpage technique de la version finale :
Principe :
- La MainActivity crée un Forecaster concret, le LocationForecasterAdapter et ForecastDisplay.
- La MainActivity inscrit le LocationForecasterAdapter au system-service de localisation.
- La MainActivity inscrit le ForecastDisplay au Forecaster.
- Le LocationForecasterAdapter est notifié d'un changement de position du téléphone : il passe la nouvelle position au forecaster.
- Le forecaster construit un forecast (grave à l'utilisation du WS par exemple), et notifie le ForecastDisplay que la prévision est prête.
- Le ForecastDisplay affiche alors la prévision.
Etapes
Nous allons réaliser cette application complète en 3 étapes.
- Version 1.0 : Pas de géoloc réelle, pas d'appel au WS.
- Version 1.1 : Géolocalisation réelle, pas d'appel au WS
- Version 1.2 : Géolocalisation réelle, WS WorldWeatherOnline
Version 1.0
Mise en place
- Créer un nouveau projet Android dans Eclipse, avec une activity "MainActivity".
- Ajouter les images "cloudy.png", "rainy.png" et "sunny.png" dans le dossier res/drawable-mdpi.
Forecast et son interface
- Créer la classe Forecast d'après la description du modèle.
- Créer l'interface ForecastListener d'après la description du modèle.
Forecaster et première implémentation concrète
- Créer l'interface Forecaster d'après la description du modèle.
- Créer la classe MockForecaster d'après la description du modèle.
- MockForecaster : Implémenter la méthode setForecastListener en définissant la propriété listener avec l'argument passé.
- MockForecaster : Implémenter la méthode makeForecast en créant un objet Forecast avec des valeurs arbitraires.
- MockForecaster : Finaliser la méthode makeForecast en appelant le listener avec la prévision créee.
Affichage d'une prévision
- Créer la classe ForecastDisplay d'après la description du modèle.
- ForecastDisplay : implémenter la méthode forecastReady pour mettre à jour l'affichage à partir de la prévision reçue.
Préparation du layout
- Modifier le layout de l'activity pour qu'il soit composé d'un LinearLayout vertical
- Ajouter dans le LinearLayout : un TextView qui représentera le nom de la ville (affiché en gros !)
- Ajouter dans le LinearLayout : une ImageView qui représentera le picto
- Ajouter dans le LinearLayout : un TextView qui représentera la température
- Ajouter dans le LinearLayout : un TextView qui représentera le commentaire de la prévision
- Tous ces éléments doivent avoir un attribut "id", car ils devront être manipulé plus tard en Java
Assemblage dans l'activity
- Dans la méthode onCreate, instancier un objet ForecastDisplay.
- Définir chacunes de ses propriétés (cityLabel, ...) avec les éléments d'affichage correspondants, récupérés depuis le layout (findViewById...)
- Instancier un objet MockForecaster, et lui passer l'instance de ForecastDisplay en tant que listener.
- Appeller la méthode "makeForecast" avec des valeurs quelquonques.
La premiere version est testable !
Quelques questions :
- Y a t'il besoin d'ajouter des "permissions" au manifest à ce niveau la ? pourquoi ?
- Retracez (sur papier) le cheminement des appels, depuis l'appel à "makeForecast" jusqu'a l'affichage à l'écran.
- Pour chaque classe et interface présente dans cette version (6 éléments), décrivez son rôle en un phrase.
Version 1.1
On ajoute la vraie géolocalisation.
Mise en place
- Dupliquer le projet pour garder une trace de la version précédente.
- Ajouter l'image "wait.jpg" à côté des autres images.
- Ajouter les permissions : ACCESS_COARSE_LOCATION et ACCESS_FINE_LOCATION au manifest
- Modifier l'imageView pour qu'elle affiche l'image "wait" au lancement de l'application.
La classe LocationForecasterAdapter
- Créer la classe LocationForecasterAdapter d'après la description du modèle.
- Implémenter la méthode onLocationChange pour qu'elle passe les informations de la géolocalisation à son Forecaster
- Ajouter des Log.d("geoloc", "message")" sur chaque méthode pour suivre le déroulement des évenements.
Assemblage dans l'activity
- Ajouter à la MainActivity un membre de type LocationForecasterAdapter.
- Dans le onCreate, instancier ce LocationForecasterAdapter, et passer le Forecaster existant à cet objet.
- Ajouter à la MainActivity un membre de type LocationManager
- Dans le onCreate, utiliser la méthode getSystemService pour récuperer le LocationManager
- Implémenter les méthodes void onResume() et void onPause() dans la MainActivity
- Dans la méthode onResume, inscrire le LocationForecastAdapter pour qu'il soit notifié des changements de position GPS et NETWORK (requestLocationUpdates...)
- Dans la méthode onPause, désinscrire le LocationForecastAdapter (removeUpdates...)
C'est déja fini !?
Quelques questions :
- Retracez (sur papier) le cheminement des appels, depuis l'appel à "makeForecast" jusqu'a l'affichage à l'écran.
- Pour chaque classe et interface présente dans cette version (7 éléments), décrivez son rôle en un phrase.
Version 1.2
On ajoute la vraie prévision de WorldWeatherOnline.
Mise en place
- Dupliquer le projet pour garder une trace de la version précédente.
- Ajouter les permissions : INTENET au manifest
Un peu de sérieux : WorldWeatherOnlineForecaster
- Créer la classe WorldWeatherOnlineForecaster d'après la description du modèle.
- Implémenter la méthode setForecastListener, exactement comme pour le Mock.
- Implémenter la méthode makeForecast : d'abord l'appel au Web-service, puis le traitement du JSON (facile !)
- ... d'abord construire une requette HTTP, l'envoyer, et récuperer la réponse...
- ...traiter le JSON pour extraire toutes les valeurs pour construire une instance de Forecast. Déterminer la ressource d'image et le commentaire selon le code reçu.
- Dans le onCreate de l'activity, remplacer l'instance de MockForecaster par une instance de WorldWeatherForecaster
Annexe :
Afficher un texte en gros :
Dans le layout, sur le TextView concerné, ajouter la propriété :
android:textAppearance="?android:attr/textAppearanceLarge"
Gérer les images dans les "resources"
Les images (et bien d'autres choses) sont identifiés par des ressources "int" qui pointent vers le vrai fichier d'image.
Récuperer une image existante (qui se trouve dans res/drawable***/monfichier.png)
monImageView.setImageResource(R.drawable.monfichier);
ou...
int pointeurVersMonImage = R.drawable.monfichier; monImageView.setImageResource(pointeurVersMonImage);
S'inscrire pour être notifié des changements de position GPS et NETWORK :
AAAAA.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, BBBBB); AAAAA.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, BBBBB); //remplacez AAAAA par le "system-service" correspondant à la géolocalisation //remplacez BBBBB par n'importe qu'elle instance, pourvu qu'elle soit de type LocationListener...
Se désinscrire des changements de positions :
AAAAA.removeUpdates(BBBBB);
Les codes du webservice WorldWeatherOnline :
Attention, à ces codes que l'on récupere dans le rétour du WS, on doit faire correspondre la ressource correspondante dans notre projet (R.drawable.????)
- 113 : image "sunny.png" et commentaire "Soleil"
- 116 ou 119 : image "cloudy.png" et commentaire "Nuageux"
- tous les autres codes : image "rainy.ong" et commentaire "vous devriez demenager dans le sud"