La plupart des applications météo populaires sur Google Play sont remplies d'annonces, nécessitent trop d'autorisations ou incluent des fonctionnalités que la plupart d'entre nous n'utilisons jamais. Ce ne serait pas génial si vous pouviez créer votre propre application météo à partir de zéro?
Dans ce tutoriel, je vais vous montrer comment. Notre application aura une interface utilisateur simple et minimaliste, montrant à l'utilisateur exactement ce dont ils ont besoin de savoir sur les conditions météorologiques actuelles. Commençons.
Ce tutoriel vous apprendra à créer une application météo à partir de rien, mais vous pouvez également utiliser l'un des modèles d'application météo Android sur Envato Market..
Par exemple, Weminder fournit une interface utilisateur simple et claire et toutes les fonctionnalités essentielles d'une application météo, de sorte que vous puissiez ensuite la personnaliser pour vos propres besoins..
Modèle d'application météo Weminder sur le marché EnvatoOu, si vous voulez quelque chose d'unique et de personnalisé, rendez-vous dans Envato Studio pour consulter la sélection de services de développement d'applications mobiles et d'applications qui y sont proposés.
Avant de continuer, vérifiez que vous avez configuré les éléments suivants:
Je vais appeler cette application SimpleWeather, mais n'hésitez pas à lui donner le nom de votre choix. Entrez un nom de package unique, définissez le SDK minimum requis sur Android 2.2, et définissez le SDK cible sur Android 4.4. Vous pouvez laisser le thème à Holo Dark.
Cette application aura seulement un Activité
et il sera basé sur la Activité vide modèle comme indiqué ci-dessous.
Nomme le Activité
MétéoActivité. Nous allons utiliser un Fragment
à l'intérieur de cette Activité
. La mise en page associée à la Activité
est activity_weather.xml. La mise en page associée à la Fragment
est fragment_weather.xml.
Copie weathericons-regular-webfont.ttf à votre projet actifs / polices répertoire et le renommer en weather.ttf.
La seule autorisation nécessaire à cette application est android.permission.INTERNET
.
Pour que ce tutoriel reste simple, nous allons seulement supporter portrait mode. le activité
Le noeud du manifeste devrait ressembler à ceci:
Il n'y a pas grand chose à changer dans activity_weather.xml. Il devrait déjà avoir un FrameLayout
. Ajouter une propriété supplémentaire pour changer la couleur du Contexte
à # FF0099CC
.
modifier fragment_weather.xml en ajoutant cinq Affichage
balises pour afficher les informations suivantes:
Utiliser un Disposition relative
organiser les vues de texte. Vous pouvez ajuster le taille du texte
pour convenir à divers appareils.
Ce fichier contient les chaînes utilisées dans notre application ainsi que les codes de caractères Unicode que nous utiliserons pour restituer les icônes météo. L'application pourra afficher huit types de conditions météorologiques différents. Si vous voulez en gérer plus, référez-vous à cette aide-mémoire. Ajouter ce qui suit à values / strings.xml:
Météo simple Changer de ville 11111 & # xf00d; & # xf02e; & # xf014; & # xf013; & # xf019; & # xf01b; & # xf01e; & # xf01c; Désolé, aucune donnée météorologique trouvée.
L'utilisateur doit pouvoir choisir la ville dont il veut voir le temps. modifier menu / weather.xml et ajouter un article pour cette option.
Maintenant que tous les fichiers XML sont prêts à être utilisés, passons à autre chose et interrogons l'API OpenWeatherMap pour récupérer les données météorologiques..
Nous pouvons obtenir les détails météorologiques actuels de toutes les villes au format JSON à l'aide de l'API OpenWeatherMap. Dans la chaîne de requête, nous passons le nom de la ville et le système métrique dans lequel les résultats doivent être en.
Par exemple, pour obtenir les informations météorologiques actuelles de Canberra, en utilisant le système métrique, nous envoyons une demande à http://api.openweathermap.org/data/2.5/weather?q=Canberra&units=metric.
La réponse que nous recevons de l'API ressemble à ceci:
"base": "stations cmc", "nuages": "tous": 90, "cod": 200, "coord": "lat": -35.28, "lon": 149.13, "dt" : 1404390600, "id": 2172517, "principal": "humidité": 100, "pression": 1023, "temp": -1, "temp_max": -1, "temp_min": -1, "nom ":" Canberra "," sys ": " pays ":" AU "," message ": 0.313," lever du soleil ": 1404335563," coucher du soleil ": 1404370965," météo ": [" description ":" couvert " nuages "," icône ":" 04n "," id ": 804," principal ":" Nuages "]," vent ": " deg ": 305.004," vitesse ": 1.07
Créez une nouvelle classe Java et nommez-la. RemoteFetch.java. Cette classe est chargée d'extraire les données météorologiques de l'API OpenWeatherMap.
Nous utilisons le HttpURLConnection
classe pour faire la demande à distance. L’API OpenWeatherMap attend la clé d’API dans un en-tête HTTP nommé x-api-key
. Ceci est spécifié dans notre demande en utilisant le setRequestProperty
méthode.
Nous utilisons un BufferedReader
lire la réponse de l'API dans un StringBuffer
. Lorsque nous avons la réponse complète, nous le convertissons en un JSONObject
objet.
Comme vous pouvez le constater dans la réponse ci-dessus, les données JSON contiennent un champ nommé la morue
. Sa valeur est 200
si la demande a abouti. Nous utilisons cette valeur pour vérifier si la réponse JSON contient ou non les informations météorologiques actuelles..
le RemoteFetch.java la classe devrait ressembler à ceci:
package ah.hathi.simpleweather; importer java.io.BufferedReader; importer java.io.InputStreamReader; importer java.net.HttpURLConnection; importer java.net.URL; import org.json.JSONObject; importer android.content.Context; importer android.util.Log; Classe publique RemoteFetch Chaîne statique privée finale String OPEN_WEATHER_MAP_API = "http://api.openweathermap.org/data/2.5/weather?q=%s&units=metric"; JSONObject statique public getJSON (contexte de contexte, chaîne de ville) try URL url = nouvelle URL (String.format (OPEN_WEATHER_MAP_API, ville)); HttpURLConnection connection = (HttpURLConnection) url.openConnection (); connection.addRequestProperty ("x-api-key", context.getString (R.string.open_weather_maps_app_id)); BufferedReader reader = new BufferedReader (new InputStreamReader (connection.getInputStream ())); StringBuffer json = new StringBuffer (1024); Chaîne; while ((tmp = reader.readLine ())! = null) json.append (tmp) .append ("\ n"); lecteur.close (); JSONObject data = new JSONObject (json.toString ()); // Cette valeur sera 404 si la demande n'a pas été // réussie si (data.getInt ("cod")! = 200) return null; renvoyer des données; catch (Exception e) return null;
L'utilisateur ne devrait pas avoir à spécifier le nom de la ville chaque fois qu'il souhaite utiliser l'application. L’application doit se rappeler de la dernière ville à laquelle l’utilisateur était intéressé. Nous le faisons en utilisant Préférences partagées
. Cependant, au lieu d’accéder directement à ces préférences depuis notre Activité
classe, il est préférable de créer une classe séparée à cet effet.
Créez une nouvelle classe Java et nommez-la. CityPreference.java. Pour stocker et récupérer le nom de la ville, créez deux méthodes. setCity
et getCity
. le Préférences partagées
l'objet est initialisé dans le constructeur. le CityPreference.java la classe devrait ressembler à ceci:
package ah.hathi.simpleweather; importer android.app.Activity; importer android.content.SharedPreferences; classe publique CityPreference SharedPreferences prefs; public CityPreference (Activité d'activité) prefs = activity.getPreferences (Activity.MODE_PRIVATE); // Si l'utilisateur n'a pas encore choisi de ville, retourne // Sydney comme ville par défaut String getCity () return prefs.getString ("city", "Sydney, AU"); void setCity (Ville de chaîne) prefs.edit (). putString ("ville", ville) .commit ();
Créez une nouvelle classe Java et nommez-la. MétéoFragment.java. Ce fragment utilise fragment_weather.xml comme sa mise en page. Déclarer les cinq Affichage
objets et les initialiser dans le onCreateView
méthode. Déclarer un nouveau Police de caractères
objet nommé WeatherFont
. le TypeFace
l'objet pointe sur la police Web que vous avez téléchargée et stockée dans le actifs / polices dossier.
Nous allons utiliser un outil séparé Fil
extraire de manière asynchrone des données à partir de l’API OpenWeatherMap. Nous ne pouvons pas mettre à jour l'interface utilisateur à partir d'un tel fil d'arrière-plan. Nous avons donc besoin d'un Gestionnaire
objet, que nous initialisons dans le constructeur du MétéoFragment
classe.
classe publique WeatherFragment étend Fragment Typeface weatherFont; TextView cityField; TextView updatedField; TextView detailsField; TextView currentTemperatureField; TextView weatherIcon; Gestionnaire de manutention; public WeatherFragment () handler = new Handler (); @Override public View onCreateView (inflateur LayoutInflater, conteneur ViewGroup, Bundle savedInstanceState) View rootView = inflater.inflate (R.layout.fragment_weather, conteneur, false); cityField = (TextView) rootView.findViewById (R.id.city_field); updatedField = (TextView) rootView.findViewById (R.id.updated_field); detailsField = (TextView) rootView.findViewById (R.id.details_field); currentTemperatureField = (TextView) rootView.findViewById (R.id.current_temperature_field); weatherIcon = (TextView) rootView.findViewById (R.id.weather_icon); weatherIcon.setTypeface (weatherFont); retourne rootView;
Initialiser le WeatherFont
objet en appelant createFromAsset
sur le Police de caractères
classe. Nous invoquons aussi le updateWeatherData
méthode en onCreate
.
@Override public void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); weatherFont = Typeface.createFromAsset (getActivity (). getAssets (), "fonts / weather.ttf"); updateWeatherData (nouvelle CityPreference (getActivity ()). getCity ());
Dans updateWeatherData
, nous commençons un nouveau fil et appelons getJSON
sur le RemoteFetch
classe. Si la valeur renvoyée par getJSON
est nul
, nous affichons un message d'erreur à l'utilisateur. Si ce n'est pas le cas, nous invoquons le renderWeather
méthode.
Seul le principal Fil
est autorisé à mettre à jour l'interface utilisateur d'une application Android. Appel Pain grillé
ou renderWeather
directement à partir du thread d'arrière-plan conduirait à une erreur d'exécution. C’est pourquoi nous appelons ces méthodes en utilisant le gestionnaire
de poster
méthode.
private void updateWeatherData (ville de chaîne finale) new Thread () public void run () final JSONObject json = RemoteFetch.getJSON (getActivity (), city); if (json == null) handler.post (new Runnable () public void run ()) (Toast.makeText (getActivity (), getActivity (), .Activity (). getString (R.string.place_not_found), Toast.LENGTH_LONG) .show ();); else handler.post (new Runnable () public void run () renderWeather (json);); .début();
le renderWeather
méthode utilise les données JSON pour mettre à jour le Affichage
objets. le Météo
Le noeud de la réponse JSON est un tableau de données. Dans ce tutoriel, nous n'utiliserons que le premier élément du tableau de données météorologiques.
renderWeather (JSONObject json) try cityField.setText (json.getString ("name"). toUpperCase (Locale.US) + "," + json.getJSONObject ("sys"). getString ("pays") ; JSONObject details = json.getJSONArray ("météo"). GetJSONObject (0); JSONObject main = json.getJSONObject ("main"); detailsField.setText (details.getString ("description"). toUpperCase (Locale.US) + "\ n" + "Humidity:" + main.getString ("humidité ") +"% "+" \ n "+" Pression : "+ main.getString (" pression ") +" hPa "); currentTemperatureField.setText (String.format ("%. 2f", main.getDouble ("temp")) + ""); DateFormat df = DateFormat.getDateTimeInstance (); String updatedOn = df.format (new Date (json.getLong ("dt") * 1000)); updatedField.setText ("Dernière mise à jour:" + updatedOn); setWeatherIcon (details.getInt ("id"), json.getJSONObject ("sys"). getLong ("sunrise") * 1000, json.getJSONObject ("sys"). getLong ("sunset") * 1000); catch (Exception e) Log.e ("SimpleWeather", "Un ou plusieurs champs introuvables dans les données JSON");
À la fin de renderWeather
méthode, nous invoquons setWeatherIcon
avec le identifiant
de la météo actuelle ainsi que les heures de lever et de coucher du soleil. Définir l’icône météo est un peu délicat, car l’API OpenWeatherMap prend en charge davantage de conditions météorologiques que la police Web que nous utilisons. Heureusement, les identifiants météo suivent un modèle, sur lequel vous pouvez en savoir plus sur le site OpenWeatherMap..
Voici comment associer un identifiant météo à une icône:
R.string.weather_thunder
pour cesR.string.weather_drizzle
pour cesR.string.weather_rain
pour euxNous utilisons les heures de lever et de coucher du soleil pour afficher le soleil ou la lune, en fonction de l'heure du jour et uniquement si le temps est clair..
void privé setWeatherIcon (int actualId, long lever de soleil, long coucher de soleil) int id = actualId / 100; Icône de chaîne = ""; if (actualId == 800) long currentTime = new Date (). getTime (); if (currentTime> = sunrise && currentTimeBien sûr, vous pouvez gérer plus de conditions météorologiques en ajoutant plus
Cas
déclarations à lacommutateur
déclaration dusetWeatherIcon
méthode.Enfin, ajoutez un
changer la ville
méthode au fragment pour permettre à l'utilisateur de mettre à jour la ville actuelle. lechanger la ville
méthode ne sera appelée à partir de la principaleActivité
classe.public void changeCity (String city) updateWeatherData (city);12. Modifier l'activité
Au cours de la configuration du projet, Eclipse a rempli MétéoActivité.java avec un code passe-partout. Remplacer l'implémentation par défaut du
onCreate
méthode avec celle ci-dessous dans laquelle nous utilisons leMétéoFragment
. leonCreate
méthode devrait ressembler à ceci:@Override protected void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_weather); if (savedInstanceState == null) getSupportFragmentManager (). beginTransaction () .add (R.id.container, new WeatherFragment ()) .commit ();Ensuite, éditez le
onOptionsItemSelected
méthode et gérer la seule option de menu que nous avons. Tout ce que vous avez à faire ici est d’invoquer leshowInputDialog
méthode.dans le
showInputDialog
méthode, nous utilisonsAlertDialog.Builder
créer unDialogue
objet qui invite l'utilisateur à entrer le nom d'une ville. Cette information est transmise auchanger la ville
méthode, qui stocke le nom de la ville en utilisant leCityPreference
classe et appelle leFragment
dechanger la ville
méthode.@Override public boolean onOptionsItemSelected (élément MenuItem) if (item.getItemId () == R.id.change_city) showInputDialog (); return false; private void showInputDialog () AlertDialog.Builder builder = new AlertDialog.Builder (this); builder.setTitle ("Changer de ville"); Final EditText input = new EditText (this); input.setInputType (InputType.TYPE_CLASS_TEXT); builder.setView (entrée); builder.setPositiveButton ("Go", nouveau DialogInterface.OnClickListener () @Override public void onClick (dialogue DialogInterface, entier qui) changeCity (input.getText (). toString ());); builder.show (); public void changeCity (Ville de la chaîne) WeatherFragment wf = (WeatherFragment) getSupportFragmentManager () .findFragmentById (R.id.container); wf.changeCity (ville); nouvelle CityPreference (this) .setCity (ville);Votre application météo est maintenant prête. Construisez le projet et déployez-le sur un périphérique Android pour le tester..
Conclusion
Vous avez maintenant une application météo entièrement fonctionnelle. N'hésitez pas à explorer l'API OpenWeatherMap pour améliorer davantage votre application. Vous pouvez également utiliser davantage d'icônes météo, car nous n'en utilisons actuellement qu'un petit sous-ensemble..