En este tutorial vamos a explicar como crear una aplicación que nos muestre los datos del tiempo para hoy y para mañana a partir de un fichero xml que se descarga de la página oficial de AMET.
En este tutorial aprenderás a:
- Descargar e interpretar un fichero xml desde internet
- Utilizar la clase XmlPullParseFactoy
Espero que le guste y le resulte fácil de entender. No dude en comentar.
Puede descargar si lo desea el código fuente de este proyecto.
Ayuda XmlPullFactory
Aquí podrás encontrar la ayuda oficial sobre la clase XmlPullFactory, se lo recomiendo para ampliar conocimientos y comprender mejor su funcionamiento.
Ayuda XmlPullFactory
Aquí podrás encontrar la ayuda oficial sobre la clase XmlPullFactory, se lo recomiendo para ampliar conocimientos y comprender mejor su funcionamiento.
Pasos a seguir:
1. Creamos una interfaz en la que podamos mostrar los datos que vamos a obtener del fichero xml. Un ejemplo de interfaz sería el siguiente.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <LinearLayout android:id="@+id/linearLayout2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:orientation="vertical" > <TextView android:id="@+id/textView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hoy" android:textAppearance="?android:attr/textAppearanceLarge" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/TextView04" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/estadoDelCielo" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/txtHCielo" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="right" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/TextView02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/temperaturaMaxima" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/txtHMaxima" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="right" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/temperaturaMinima" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/txtHMinima" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="right" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> </LinearLayout> </LinearLayout> <LinearLayout android:id="@+id/linearLayout1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentRight="true" android:layout_below="@+id/linearLayout2" android:layout_marginTop="100dp" android:orientation="vertical" > <TextView android:id="@+id/TextView07" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/manana" android:textAppearance="?android:attr/textAppearanceLarge" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/TextView10" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/estadoDelCielo" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/txtMCielo" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="right" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/TextView08" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/temperaturaMaxima" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/txtMMaxima" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="right" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/TextView06" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/temperaturaMinima" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/txtMMinima" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="right" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" /> </LinearLayout> </LinearLayout> </RelativeLayout>
2. Como vamos a tener que acceder a internet le damos al manifiesto el siguiente permiso para que nos permita conectarnos a internet.
<uses-permission android:name="android.permission.INTERNET"/>
3. Inicializamos los campos que vamos a utilizar en la clase de la actividad principal.
4. Creamos el método que va a leer el estado del cielo para hoy y para mañana.
5. Creamos el método que va a leer la temperatura máxima para hoy y para mañana.
6. Creamos el método que va a leer las temperaturas mínimas para hoy y para mañana.
7. Creamos el método que lee todos los datos del fichero xml obtenido de internet.
8. Finalmente creamos un método para mostrar de forma organizada todos los datos obtenidos del fichero xml.
<uses-permission android:name="android.permission.INTERNET"/>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.ACDAT.ejercicio4" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" /> <uses-permission android:name="android.permission.INTERNET"/> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".TiempoActivity" android:label="@string/title_activity_tiempo" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
3. Inicializamos los campos que vamos a utilizar en la clase de la actividad principal.
/** * Muestra el tiempo del día de hoy y el de mañana de la ciudad de Málaga * * @author José Miguel Acosta Martín * */ public class TiempoActivity extends Activity { ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // CAMPOS // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Campos gráficos private TextView txtHCielo; // Campo gráfico que muestra el estado del cielo de hoy private TextView txtHMinima; // Campo gráfico que muestra la temperatura mínima de hoy private TextView txtHMaxima; // Campo gráfico que muestra la temperatura máxima de hoy private TextView txtMCielo; // Campo gráfico que muestra el estado del cielo de mañana private TextView txtMMinima; // Campo gráfico que muestra la temperatura mínima de mañana private TextView txtMMaxima; // Campo gráfico que muestra la temperatura máxima de mañana // Otros campos private URL url; // Almacena la url del xml donde está almacenada la predicción meteorológica private String[] estadoCielo; // Almacena el estado del cielo de hoy y de mañana private String[] temperaturaMaxima; // Almacena la temperatura máxima de hoy y de mañana private String[] temperaturaMinima; // Almacena la temperatura mínima de hoy y de mañana ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // FIN CAMPOS // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4. Creamos el método que va a leer el estado del cielo para hoy y para mañana.
/** * Lee el estado del cielo para hoy y para mañaana * * @param xml Fichero xml donde se encuentra la predicción meteorológica */ public void leerEstadoCielo(XmlPullParser xml){ // CAMPOS ////////////////////////////////////////////////////////////////////////////////////////////////// int contadorDia; // Almacena la cuenta los días leidos int contadorEstadoCielo; // Almacena la cuenta de las etiquetas <estado_cielo> leiddo int evento; // Almacena el evento obtenido // FIN CAMPOS ////////////////////////////////////////////////////////////////////////////////////////////// // EJECUCIÓN /////////////////////////////////////////////////////////////////////////////////////////////// try { // Inicialización de los contadores contadorDia = 0; contadorEstadoCielo = 0; // Obtiene el evento del fichero xml evento = xml.getEventType(); // Recorre el fichero xml while(evento != XmlPullParser.END_DOCUMENT){ switch (evento) { case XmlPullParser.START_TAG: // Contabiliza los días leidos if (xml.getName().equals("dia")){ contadorDia++; } // Controla si es el día 1 if (contadorDia == 1){ // Si es el día 1 .... // Contabiliza if (xml.getName().equals("estado_cielo")){ contadorEstadoCielo++; } // Controla si es el primer estado del cielo if (contadorEstadoCielo == 1){ // Si es el primer estado del cielo ... // Almacena el contenido estadoCielo[0] = xml.getAttributeValue(1); } } // Controla si es el día 2 if (contadorDia == 2){ // Reinicia el contador contadorEstadoCielo = 0; // Contabiliza if (xml.getName().equals("estado_cielo")){ contadorEstadoCielo++; } // Controla si es el primer estado del cielo if (contadorEstadoCielo == 1){ // Si es el primer estado del cielo ... // Almacena el contenido estadoCielo[1] = xml.getAttributeValue(1); } } break; } // Avanza una posición evento = xml.next(); } } catch (XmlPullParserException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } // FIN EJECUCIÓN /////////////////////////////////////////////////////////////////////////////////////////// }
5. Creamos el método que va a leer la temperatura máxima para hoy y para mañana.
/** * Lee la temperatura máxima para hoy y para mañana * * @param xml Fichero xml donde se encuentra almacenada la predicción meteorológica */ public void leerTemperaturaMaxima(XmlPullParser xml){ // CAMPOS ////////////////////////////////////////////////////////////////////////////////////////////////// int contadorDia; // Almacena la cuenta de los días leidos int contadorTemMaxima; // Almacena la cuenta de etiqueta <maxima> boolean leido1; // Indica si se ha leido la temperatura del día 1 boolean leido2; // Indica si se ha leido la temperatuda del día 2 int evento; // Almacena el evento obtenido del fichero xml // FIN CAMPOS ////////////////////////////////////////////////////////////////////////////////////////////// // EJECUCIÓN /////////////////////////////////////////////////////////////////////////////////////////////// try { // Inicializa los contadores contadorDia = 0; contadorTemMaxima = 0; // Inicializa las banderas leido1 = false; leido2 = false; // Obtiene el evento producido evento = xml.getEventType(); // Recorre el fichero xml while(evento != XmlPullParser.END_DOCUMENT){ switch (evento) { case XmlPullParser.START_TAG: // Contabiliza el día if (xml.getName().equals("dia")){ contadorDia++; } // Controla si es el día 1 if (contadorDia == 1){ // Si es el día 1 ... // Contabiliza las etiquetas <maxima> if (xml.getName().equals("maxima")){ contadorTemMaxima++; } // Controla que sea la primera etiqueta y no se haya leido antes if (contadorTemMaxima == 1 && !leido1){ // Si es la primera y no se ha leido // Avanza y almacena la temperatura máxima xml.next(); temperaturaMaxima[0] = xml.getText(); // Indica que se ha leido la temperatura del día 1 leido1 = true; } } // Controla si es el día 2 if (contadorDia == 2){ // Si es el día 2 ... // Reinicia el contador contadorTemMaxima = 0; // Contabiliza las etiquetas <maxima> if (xml.getName().equals("maxima")){ contadorTemMaxima++; } // Controla que sea la primera etiqueta y no se haya leido antes if (contadorTemMaxima == 1 && !leido2){ // Si es la primera y no se ha leido // Avanza y almacena la temperatura máxima xml.next(); temperaturaMaxima[1] = xml.getText(); // Indica que se ha leido la temperatura del día 2 leido2 = true; } } break; } // Avanza en el fichero xml evento = xml.next(); } } catch (XmlPullParserException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } // FIN EJECUCIÓN /////////////////////////////////////////////////////////////////////////////////////////// }
6. Creamos el método que va a leer las temperaturas mínimas para hoy y para mañana.
/** * Lee las temperatuas mínimas para el día de hoy y mañana * * @param xml Fichero xml donde está almacenada la predicción meteorológica */ public void leerTemperaturaMinima(XmlPullParser xml){ // CAMPOS ////////////////////////////////////////////////////////////////////////////////////////////////// int contadorDia; // Almacena la cuenta de los días leidos int contadorTemMinima; // Almacena la cuenta de etiqueta <minima> boolean leido1; // Indica si se ha leido la temperatura del día 1 boolean leido2; // Indica si se ha leido la temperatuda del día 2 int evento; // Almacena el evento obtenido del fichero xml // FIN CAMPOS ////////////////////////////////////////////////////////////////////////////////////////////// // EJECUCIÓN /////////////////////////////////////////////////////////////////////////////////////////////// try { // Inicializa los contadores contadorDia = 0; contadorTemMinima = 0; // Inicializa las banderas leido1 = false; leido2 = false; // Obtiene el evento producido evento = xml.getEventType(); // Recorre el fichero xml while(evento != XmlPullParser.END_DOCUMENT){ switch (evento) { case XmlPullParser.START_TAG: // Contabiliza el día if (xml.getName().equals("dia")){ contadorDia++; } // Controla si es el día 1 if (contadorDia == 1){ // Si es el día 1 ... // Contabiliza las etiquetas <minima> if (xml.getName().equals("minima")){ contadorTemMinima++; } // Controla que sea la primera etiqueta y no se haya leido antes if (contadorTemMinima == 1 && !leido1){ // Si es la primera y no se ha leido // Avanza y almacena la temperatura máxima xml.next(); temperaturaMinima[0] = xml.getText(); // Indica que se ha leido la temperatura del día 1 leido1 = true; } } // Controla si es el día 2 if (contadorDia == 2){ // Si es el día 2 ... // Reinicia el contador contadorTemMinima = 0; // Contabiliza las etiquetas <minima> if (xml.getName().equals("minima")){ contadorTemMinima++; } // Controla que sea la primera etiqueta y no se haya leido antes if (contadorTemMinima == 1 && !leido2){ // Si es la primera y no se ha leido // Avanza y almacena la temperatura máxima xml.next(); temperaturaMinima[1] = xml.getText(); // Indica que se ha leido la temperatura del día 2 leido2 = true; } } break; } // Avanza en el fichero xml evento = xml.next(); } } catch (XmlPullParserException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } // FIN EJECUCIÓN /////////////////////////////////////////////////////////////////////////////////////////// }
7. Creamos el método que lee todos los datos del fichero xml obtenido de internet.
/** * Obtiene y lee los datos del fichero xml donde está almacena la predicción meteorológica */ public void leerDatos(){ // CAMPOS ///////////////////////////////////////////////////////////////////////////////////////////////// XmlPullParserFactory factory; XmlPullParser xml; // Almacena el recurso xml // FIN CAMPOS ///////////////////////////////////////////////////////////////////////////////////////////// try { // Obtiene el fichero xml y lee el estado del cielo factory = XmlPullParserFactory.newInstance(); xml = factory.newPullParser(); xml.setInput(url.openStream(), "UTF-8"); leerEstadoCielo(xml); // Obtiene el fichero xml y lee la temperatura máxima factory = XmlPullParserFactory.newInstance(); xml = factory.newPullParser(); xml.setInput(url.openStream(), "UTF-8"); leerTemperaturaMaxima(xml); // Obtiene el fichero xml y lee la temperatura mínima factory = XmlPullParserFactory.newInstance(); xml = factory.newPullParser(); xml.setInput(url.openStream(), "UTF-8"); leerTemperaturaMinima(xml); } catch (NotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (XmlPullParserException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
/** * Muestra los datos obtenidos al usuario */ public void mostrarDatos(){ // Mostrar datos hoy txtHCielo.setText(estadoCielo[0]); txtHMinima.setText(temperaturaMinima[0]); txtHMaxima.setText(temperaturaMaxima[0]); // Mostrar datos mañana txtMCielo.setText(estadoCielo[1]); txtMMinima.setText(temperaturaMinima[1]); txtMMaxima.setText(temperaturaMaxima[1]); }
FIN