lunes, 4 de febrero de 2013

Lector de noticia RSS

Introducción:

En este tutorial vamos a explicar como hacer un lector sencillo de noticas rss.

La aplicación se conectará a internet y se descargará el archivo rss en donde se  encuentra las noticias, la aplicación mostrará los títulos de la noticias y permitirá mediante un clik obtener más información de la noticia, como la descripción, la fecha y la dirección.

Espero que os guste y le resulte fácil de comprender. No dude en comentar.

¡ Saludos!



Enlaces de interés:

Código Fuente
Puede descargar si lo desea el código fuente de este proyecto.



Pasos a seguir:

1. Crea la actividad principal donde se mostrará la lista de los títulos de la noticias.


<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" > <ListView android:id="@+id/listvUltimasNoticias" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" > </ListView> </RelativeLayout>



2. Crear la segunda actividad donde se mostrará de forma más detallada la noticia.


<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/ScrollView1" android:layout_width="match_parent" android:layout_height="match_parent" > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/titulo" android:textAppearance="?android:attr/textAppearanceLarge" /> <TextView android:id="@+id/txtTitulo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Medium Text" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/textView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/descripcion" android:textAppearance="?android:attr/textAppearanceLarge" /> <TextView android:id="@+id/txtDescripcion" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Medium Text" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/txtFecha" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Small Text" android:textAppearance="?android:attr/textAppearanceSmall" /> <TextView android:id="@+id/txtLink" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Small Text" android:textAppearance="?android:attr/textAppearanceSmall" /> </LinearLayout> </ScrollView>


4. Creamos la clase modelo de noticia que utilizaremos luego para poder guardar las noticias en un arrayList.

package com.ACDAT.ejercicio6.Noticia; import java.io.Serializable; @SuppressWarnings("serial") public class Noticia implements Serializable{ ////////////////////////////////////////////////////////////////////////// // CAMPOS // ////////////////////////////////////////////////////////////////////////// private String titutlo; private String descripcion; private String fechaPublicacion; private String url; ////////////////////////////////////////////////////////////////////////// // CAMPOS // ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // CONSTRUCTOR // ////////////////////////////////////////////////////////////////////////// public Noticia(String titutlo, String descripcion, String fechaPublicacion, String url) { this.titutlo = titutlo; this.descripcion = descripcion; this.fechaPublicacion = fechaPublicacion; this.url = url; } ////////////////////////////////////////////////////////////////////////// // FIN CONSTRUCTOR // ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // PROPIEDADES // ////////////////////////////////////////////////////////////////////////// public String getTitutlo() { return titutlo; } public String getDescripcion() { return descripcion; } public String getFechaPublicacion() { return fechaPublicacion; } public String getUrl() { return url; } ////////////////////////////////////////////////////////////////////////// // FIN PROPIEDADES // ////////////////////////////////////////////////////////////////////////// }


5. Declaramos los campos que vamos a utilizar en la primera actividad donde se van a mostrar los títulos de las noticas.

/** * Muestra la últimas noticias del canal rss * * @author José Miguel Acosta Martín * */ public class UltimasNoticiasActivity extends Activity { //////////////////////////////////////////////////////////////////////////////////////// // CAMPOS // //////////////////////////////////////////////////////////////////////////////////////// // Campos gráficos private ListView listvNoticias; // Campo gráfico que muestra una lista con noticias // Otros campos private URL url; // Almacena la url desde donde se descarga el rss private ArrayList<Noticia> noticias; // Almacena las noticias leidas del fichero xml private String[] titulos; // Almacena los títutlos de las noticias //////////////////////////////////////////////////////////////////////////////////////// // FIN CAMPOS // ////////////////////////////////////////////////////////////////////////////////////////

6. Iniciamos los campos en el método onCreate() además de programas los eventos que vallamos a utilizar.

/** * Al iniciar la actividad */ @SuppressLint({ "NewApi", "NewApi", "NewApi" }) @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_ultimas_noticias); // INICIALIZACIÓN DE CAMPOS ///////////////////////////////////////////////////////////////////// // Inicialización de campos gráficos listvNoticias = (ListView) findViewById(R.id.listvUltimasNoticias); // Inicialización de otros campos noticias = new ArrayList<Noticia>(); // FIN INICIALIZACIÓN DE CAMPOS ////////////////////////////////////////////////////////////////// // Permisos para acceder a internet StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); // Inicializa la url desde donde se obtiene el fichero xml try { url = new URL("http://ep00.epimg.net/rss/tags/ultimas_noticias.xml"); leerDatos(); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } // Crea el adaptador con los titulos de noticias ArrayAdapter adaptador = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,titulos); // Establece el adaptador listvNoticias.setAdapter(adaptador); ///////////////////////////////////////////////////////////////////////////////////////////////// // EVENTOS // ///////////////////////////////////////////////////////////////////////////////////////////////// listvNoticias.setOnItemClickListener(new OnItemClickListener() { /** * Muestra la noticia seleccionada */ public void onItemClick(AdapterView<?> adaptador, View vista, int posicion, long arg3) { // Crea un intent con la noticia y la envía a NoticiaActivity para mostrarla Intent intent = new Intent (UltimasNoticiasActivity.this, NoticiaActivity.class); intent.putExtra("NOTICIA", noticias.get(posicion)); startActivity(intent); } }); ///////////////////////////////////////////////////////////////////////////////////////////////// // FIN EVENTOS // ///////////////////////////////////////////////////////////////////////////////////////////////// }



7. Y para terminar con esta clase creamos el método leerDatos() que es el método más importante de la aplicación pues será la que se descargue los datos de internet y las almacene.

/** * Lee los datos del fichero xml */ public void leerDatos(){ // CAMPOS //////////////////////////////////////////////////////////////// XmlPullParserFactory factory; XmlPullParser xml; // Almacena el fichero xml int evento; // Almacena el evento producido boolean title; // Almacena si se ha leido el título boolean link; // Almacena si se ha leido el link boolean pubDate; // Almacena si se ha leido la fecha de publicación boolean contentEncoded; // Almacena si se ha leido el contenido ArrayList<String> titles; // Almacena los títutlos de la noticias ArrayList<String> links; // Almacena los links de las noticias ArrayList<String> pubDates; // Almacena las fechas de publicación de las noticias ArrayList<String> contentEncodeds; // Almacena el contenido de las noticias int contador; // Controla que no salga los dos primeros titulos // FIN CAMPOS ///////////////////////////////////////////////////////////// // EJECUCIÓN ////////////////////////////////////////////////////////////// // Inicializa los arrays titles = new ArrayList<String>(); links = new ArrayList<String>(); pubDates = new ArrayList<String>(); contentEncodeds = new ArrayList<String>(); // Inicializa el contador contador = 0; // Inicializa los valores booleanos title = false; link = false; pubDate = false; contentEncoded = false; try { // Obtiene el fichero xml factory = XmlPullParserFactory.newInstance(); xml = factory.newPullParser(); xml.setInput(url.openStream(),"UTF-8"); // Obtiene el evento producido evento = xml.getEventType(); // Recorre el fichero xl while (evento != XmlPullParser.END_DOCUMENT){ switch (evento) { case XmlPullParser.START_TAG: if (xml.getName().equals("title")){ // Incrementa el contador de titulos contador++; // Controla que no aparezca los dos primeros títulos if (contador > 2){ title = true; } } if (xml.getName().equals("link")){ link = true; } if (xml.getName().equals("pubDate")){ pubDate = true; } if (xml.getName().equals("content:encoded")){ contentEncoded = true; } break; case XmlPullParser.TEXT: if (title){ titles.add(xml.getText()); } if (link){ links.add(xml.getText()); } if (pubDate){ pubDates.add(xml.getText()); } if (contentEncoded){ contentEncodeds.add(xml.getText()); } break; case XmlPullParser.END_TAG: if (xml.getName().equals("title")){ title = false; } if (xml.getName().equals("link")){ link = false; } if (xml.getName().equals("pubDate")){ pubDate = false; } if (xml.getName().equals("content:encoded")){ contentEncoded = false; } break; } evento = xml.next(); } // Almacena la noticias//////////////////////////////////////////////////////////////////////////////////// // Inicializa el array de titulos de noticias titulos = new String[contentEncodeds.size()]; // Recorre el contenido for (int i = 0; i < contentEncodeds.size(); i++) { // Almacena las noticas noticias.add(new Noticia(titles.get(i), contentEncodeds.get(i), pubDates.get(i), links.get(i))); // Almacena el titutlo de las noticas titulos[i] = titles.get(i); } //////////////////////////////////////////////////////////////////////////////////////////////////////////// } catch (XmlPullParserException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } // FIN EJECUCIÓN ////////////////////////////////////////////////////////////// }


8. Declaramos los campos que vamos a utilizar en la clase de la segunda actividad donde se mostrarán los datos.

//////////////////////////////////////////////////////////////////////////////////////// // CAMPOS // //////////////////////////////////////////////////////////////////////////////////////// private TextView txtTitulo; // Campo gráfico que muestra el títutlo private TextView txtDescripcion; // Campo gráfico que muestra la descripción private TextView txtFecha; // Campo gráfico que muestra la fecha private TextView txtLink; // Campo gráfico que muestra el link //////////////////////////////////////////////////////////////////////////////////////// // CAMPOS // ////////////////////////////////////////////////////////////////////////////////////////


9. Iniciamos los campos en el método onCreate y realizamos las operaciones que necesitemos para mostrar los datos, ponemos la firma de los métodos.

/** * Al iniciar la actividad */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_noticia); // INICIALIZACIÓN CAMPOS /////////////////////////////////////////////////////// // Inicialización de campos gráficos txtTitulo = (TextView) findViewById(R.id.txtTitulo); txtDescripcion = (TextView) findViewById(R.id.txtDescripcion); txtFecha = (TextView) findViewById(R.id.txtFecha); txtLink = (TextView) findViewById(R.id.txtLink); // FIN INICIALIZACIÓN CAMPOS /////////////////////////////////////////////////// // Obtiene la noticia y la muestra obtenerNoticia(); }



10. Creamos un método por simplicidad para obtener los datos de la noticia y mostrarla al usuario.

/** * Obtiene la noticia y la muestra */ public void obtenerNoticia(){ // Recibe el intent con la noticia Intent intent = getIntent(); Noticia noticia = (Noticia) intent.getSerializableExtra("NOTICIA"); // Muestra el contenido de la noticia txtTitulo.setText(noticia.getTitutlo()); txtDescripcion.setText(noticia.getDescripcion()); txtFecha.setText(noticia.getFechaPublicacion()); txtLink.setText(noticia.getUrl()); }


FIN


4 comentarios:

  1. Me parece brutal el como está explicare... gracias por compartirlo...

    ResponderEliminar
  2. Hola, oye me sale error cuando intento abrir un rss :S! pablo.otayza1@gmail.com me ayudas?

    ResponderEliminar
  3. Hola muy buen tuto, me viene de perlas
    estado intentando poner la imagen de la noticia en miniatura pero no lo consigo.. si sabes como hacerlo y me lo facilitaras me arias un favor
    Gracias, ;)

    ResponderEliminar