Applicazioni di rete: un RSS reader

5 luglio 2017

Le applicazioni che svilupperemo in ambito mobile saranno quasi sempre dotate di accesso ad Internet: per consultare notizie, per informarsi sul tempo atmosferico, per leggere le email, per rimanere in contatto con i proprio amici attraverso i social network o effettuare chiamate VoIP per risparmiare sulle telefonate.

In questa lezione vedremo come creare un’applicazione d’esempio che accede ad Internet, implementando un semplice lettore di feed RSS (Really Simple Syndication).

Per accedere ai servizi di rete su un device Android dobbiamo avere i permessi appropriati. Una app Android infatti può utilizzare la maggior parte dei servizi di rete solo se nel proprio file di configurazioni AndroidManifest.xml vi sono le appropriate impostazioni.

La prima cosa che facciamo dunque è modificare il file AndroidManifest.xml della nostra applicazione d’esempio aggiungendo i permessi per l’utilizzo di Internet:

<uses-permission android:name="android.permission.INTERNET" />

L’implementazione del lettore di RSS è divisa in due Activity diverse: la prima (RSS.java) è quella in cui impostiamo il feed da leggere e il layout principale, la seconda (RSSItem.java) è quella che genera la lista di elementi pubblicati nel feed con il relativo layout.

Vediamo in dettaglio il codice della prima Activity RSS.java:

package html.it.examples.com;

import android.app.Activity;
import android.os.Bundle;
import java.util.ArrayList;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class RSS extends Activity  {
    
    String feedUrl = "";
    ListView rssListView = null;
    ArrayList<RSSItem> RSSItems = new ArrayList<RSSItem>();
    ArrayAdapter<RSSItem> array_adapter = null;
    
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.rssmain);
        
        feedUrl = "http://feeds.feedburner.com/Blogrammazione/";
        
        refreshRSSList();
        
        rssListView = (ListView) findViewById(R.id.rssListView);
        
        array_adapter = new ArrayAdapter<RSSItem>(this, R.layout.list_item, RSSItems);
        rssListView.setAdapter(array_adapter);
        
        refreshRSSList();
    }
    
    private void refreshRSSList() {
        
        ArrayList<RSSItem> newItems = RSSItem.getRSSItems(feedUrl);
        RSSItems.clear();
        RSSItems.addAll(newItems);
        
    }
    
}

Inizialmente definiamo nella classe alcune variabili:

String feedUrl = "";
ListView rssListView = null;
ArrayList<RSSItem> RSSItems = new ArrayList<RSSItem>();
ArrayAdapter<RSSItem> array_adapter = null;

La variabile feedUrl di tipo stringa ci servirà per memorizzare l’URL del feed da leggere; rssListView è la variabile che contiene il riferimento alla ListView, posizionata nel layout XML, che ospiterà le informazioni acquisite; RSSItems è una struttura di tipo ArrayList che conterrà la lista degli elementi del feed (ognuno caratterizzato da un titolo, una descrizione, una data di pubblicazione e un link); array_adapter è una variabile che conterrà un oggetto di tipo ArrayAdapter che, come vedremo più in dettaglio tra qualche istante, permette di legare degli oggetti anche di tipo arbitrario contenuti in un array con un determinato layout più o meno complesso.

All’interno del metodo principale dell’Activity onCreate(), impostiamo il feed che leggeremo, richiamiamo il metodo refreshRSSList() e creiamo l’Array Adapter passando come parametri il contesto attuale (mediante il riferimento this), il file descrittore XML per il layout della lista (R.layout.list_item) ed infine il riferimento che conterrà la lista di oggetti RSSItem:

feedUrl = "http://feeds.feedburner.com/Blogrammazione/";

refressRssList();

rssListView = (ListView) findViewById(R.id.rssListView);

array_adapter = new ArrayAdapter<RSSItem>(this, R.layout.list_item, RSSItems);
rssListView.setAdapter(array_adapter);

refreshRSSList();

La funzione refreshRSSList recupera e aggiorna la lista di item letti dal feed e aggiunge questi elementi all’ArrayList che contiene tutte le voci del feed:

private void refreshRSSList() {
    
    ArrayList<RSSItem> newItems = RSSItem.getRSSItems(feedUrl);
    RSSItems.clear();
    RSSItems.addAll(newItems);
    
}

Il file XML che descrive il layout di questa Activity è davvero molto semplice, visto che contiene solo una ListView:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
		android:layout_width="fill_parent" android:layout_height="fill_parent"
		android:orientation="vertical">

	<ListView android:id="@+id/rssListView" android:layout_width="fill_parent"
			android:layout_height="wrap_content" />
</LinearLayout>

La seconda Activity, RSSItem.java, legge ogni elemento del feed e costruisce la lista di item che vengono visualizzati nella precedente RSS.java:

package html.it.examples.com;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public class RSSItem {
    
    private String title;
    private String description;
    private Date date;
    private String link;
    
    public RSSItem(String title, String description, Date pubDate, String link) {
        this.title          = title;
        this.description = description;
        this.date           = pubDate;
        this.link         = link;
    }
    
    public String getTitle() {
        return title;
    }
    
    public void setTitle(String title) {
        this.title = title;
    }
    
    public String getDescription() {
        return description;
    }
    
    public void setDescription(String description) {
        this.description = description;
    }
    
    public Date getPubDate() {
        return date;
    }
    
    public void setPubDate(Date pubDate) {
        this.date = pubDate;
    }
    
    public String getLink() {
        return link;
    }
    
    public void setLink(String link) {
        this.link = link;
    }
    
    @Override
    public String toString() {
        
        SimpleDateFormat sdf = new SimpleDateFormat("hh:mm - MM/dd/yy");
        
        String result = getTitle() + "   ( " + sdf.format(this.getPubDate()) + " )";
        return result;
    }
    
    public static ArrayList<RSSItem> getRSSItems(String feedUrl) {
        
        ArrayList<RSSItem> rssItems = new ArrayList<RSSItem>();
        
        try {
            
            URL url = new URL(feedUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            
            if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
                InputStream is = conn.getInputStream();
                
                DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                DocumentBuilder db = dbf.newDocumentBuilder();
                
                
                Document document = db.parse(is);
                Element element = document.getDocumentElement();
                
                
                NodeList nodeList = element.getElementsByTagName("item");
                
                if (nodeList.getLength() > 0) {
                    for (int i = 0; i < nodeList.getLength(); i++) {
                        
                        Element entry = (Element) nodeList.item(i);
                        Element _titleE       = (Element)entry.getElementsByTagName("title").item(0);
                        Element _descriptionE = (Element)entry.getElementsByTagName("description").item(0);
                        Element _pubDateE       = (Element) entry.getElementsByTagName("pubDate").item(0);
                        Element _linkE           = (Element) entry.getElementsByTagName("link").item(0);
                        String _title           = _titleE.getFirstChild().getNodeValue();
                        String _description   = _descriptionE.getFirstChild().getNodeValue();
                        Date _pubDate           = new Date(_pubDateE.getFirstChild().getNodeValue());
                        String _link           = _linkE.getFirstChild().getNodeValue();
                        
                        RSSItem rssItem = new RSSItem(_title, _description, _pubDate, _link);
                        
                        rssItems.add(rssItem);
                        
                    }
                }
                
            }
            
            } catch (Exception e) {
            
            e.printStackTrace();
            
        }
        
        return rssItems;
    }
}

Questa Activity genera gli item dell’RSS impostato precedentemente: ogni oggetto RSSItem ha un titolo, una descrizione, una data di pubblicazione e un link; per ogni attributo sono inoltre disponibili i classici metodi setter e getter.

Il cuore dell’Activity è il metodo getRSSItem(): qui apriamo una connessione URL con il server e recuperiamo i dati dell’RSS. Se la connessione è andata a buon fine allora utilizziamo il DocumentBuilderFactory e il DocumentBuilder per effettuare il parsing dell’XML:

URL url = new URL(feedUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();

if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
    InputStream is = conn.getInputStream();
    
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder();
    
    Document document = db.parse(is);
    Element element = document.getDocumentElement();

Con il metodo getElementsByTagName() della classe Element recuperiamo tutti gli elementi item contenuti nell’RSS (corrispondenti ai tag <item></item> nei dati XML) e li salviamo in un oggetto di tipo NodeList. Effettuiamo un ciclo for su tutti i nodi dell’oggetto NodeList creando un oggetto RSSItem per ogni elemento presente, recuperiamo le informazioni dell’item (titolo, descrizione, data di pubblicazione e link) e lo aggiungiamo all’ArrayList:

NodeList nodeList = element.getElementsByTagName("item");

if   ( nodeList.getLength() > 0 )  {
    for ( int i = 0; i < nodeList.getLength(); i++ ) {
        
        Element entry = (Element) nodeList.item(i);
        Element _titleE       = (Element)entry.getElementsByTagName("title").item(0);
        Element _descriptionE = (Element)entry.getElementsByTagName("description").item(0);
        Element _pubDateE       = (Element) entry.getElementsByTagName("pubDate").item(0);
        Element _linkE           = (Element) entry.getElementsByTagName("link").item(0);
        String _title           = _titleE.getFirstChild().getNodeValue();
        String _description   = _descriptionE.getFirstChild().getNodeValue();
        Date _pubDate           = new Date(_pubDateE.getFirstChild().getNodeValue());
        String _link           = _linkE.getFirstChild().getNodeValue();
        
        RSSItem rssItem = new RSSItem(_title, _description, _pubDate, _link);
        
        rssItems.add(rssItem);
        
    }
}

Infine viene restituito l’oggetto ArrayList con tutti gli item del feed RSS analizzati e memorizzati.

Anche il file XML che descrive il layout da utilizzare per ogni item dell’RSS è molto semplice:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
		android:layout_width="fill_parent"
		android:layout_height="fill_parent"
		android:padding="10dp"
		android:textSize="13sp"
		android:autoLink="all" >
</TextView>

Utilizziamo solo una TextView per la visualizzazione dei dati di ogni item dell’RSS. A questo proposito possiamo notare che abbiamo sovrascritto il metodo toString() per gli oggetti RSSItem, in modo che la stampa di un elemento di questo tipo permetta di visualizzarne il titolo e la data di pubblicazione, come mostrato nella figura seguente:

Figura 22: L'applicazione che legge i feed RSS

Tutte le lezioni

1 ... 76 77 78 ... 85

Se vuoi aggiornamenti su Applicazioni di rete: un RSS reader inserisci la tua e-mail nel box qui sotto:
Tags:
 
X
Se vuoi aggiornamenti su Applicazioni di rete: un RSS reader

inserisci la tua e-mail nel box qui sotto:

Ho letto e acconsento l'informativa sulla privacy

Acconsento al trattamento di cui al punto 3 dell'informativa sulla privacy