Android RSS Reader Tutorial
Well, its now 2013, and I have updated a
version of this post - a long with a complete working application on GitHub -
you can find that here it covers Android 3.0+ so includes fragments and parsing the RSS in an AsyncTask. Of course, you can still read this post and access the code for the pre-3.0 version!
There are two core classes that I used in my RSS parsing project - The RssHandler (extendes the SAX DefaultHandler) and the Article object (I use this to store all the information about an article/item in an RSS stream.
Here I will go through the SAX Handler implementation.
First we declare global variables we will use, most of these are self-explanatory: currentArticle stores all the information about the current RSS item being processed; articleList stores a list of all items processed so far; the two counters then count the number of RSS items processed and the limit (you will want to set this to the number of articles you want to fetch, as the stream could be very big); the characters StringBuffer, we use this to accumulate the text in each simple element:
// Feed and Article objects to use for temporary storage
private Article currentArticle = new Article();
private List articleList = new ArrayList();
// Number of articles added so far
private int articlesAdded = 0;
// Number of articles to download
private static final int ARTICLES_LIMIT = 15;
//Current characters being accumulated
StringBuffer chars = new StringBuffer();
When implementing the SAX DefaultHandler you need three core methods: startElement(), endElement(), characters().
This is the startElement() method, this is called on every opening XML node (such as <item>). In our case all we want to do is reset our chars StringBuffer to be sure that the text we retrieve is always only from our current simple element
public void startElement(String uri, String localName, String qName, Attributes atts) {
chars = new StringBuffer();
}
Next we have characters() method - this is called whilst reading the text stored in a simple element - however, this is not just called once at the end of the element, but can be called several times, so we must be careful to be sure we dont process the text here as it maybe incomplete - so for now we just accumulate the text in our String Buffer, and we will process it later, when we ar sure we have all the text:
public void characters(char ch[], int start, int length) {
chars.append(new String(ch, start, length));
}
Finally we have the endElement() method - this is called when any closing XML marker is found (for example, </item>). At this point we check which element we are in and decide if we should process the contents. For example, if we have found </title> then we know we are closing the <title> simple element - we know our string buffer was reset in the startElement for <title>, and we know our characters() method has been called and collected all the text insde this element, so we can now safely use this information to set the title on our currentArticle object:
public void endElement(String uri, String localName, String qName) throws SAXException {
if (localName.equalsIgnoreCase("title"))
{
Log.d("LOGGING RSS XML", "Setting article title: " + chars.toString());
currentArticle.setTitle(chars.toString());
}
else if (localName.equalsIgnoreCase("description"))
{
Log.d("LOGGING RSS XML", "Setting article description: " + chars.toString());
currentArticle.setDescription(chars.toString());
}
else if (localName.equalsIgnoreCase("pubDate"))
{
Log.d("LOGGING RSS XML", "Setting article published date: " + chars.toString());
currentArticle.setPubDate(chars.toString());
}
else if (localName.equalsIgnoreCase("encoded"))
{
Log.d("LOGGING RSS XML", "Setting article content: " + chars.toString());
currentArticle.setEncodedContent(chars.toString());
}
else if (localName.equalsIgnoreCase("item"))
{
}
else if (localName.equalsIgnoreCase("link"))
{
try {
Log.d("LOGGING RSS XML", "Setting article link url: " + chars.toString());
currentArticle.setUrl(new URL(chars.toString()));
} catch (MalformedURLException e) {
Log.e("RSA Error", e.getMessage());
}
}
// Check if looking for article, and if article is complete
if (localName.equalsIgnoreCase("item")) {
articleList.add(currentArticle);
currentArticle = new Article();
// Lets check if we've hit our limit on number of articles
articlesAdded++;
if (articlesAdded >= ARTICLES_LIMIT)
{
throw new SAXException();
}
}
This Handler will allow us to parse an RSS stream and create a list of Article objects for later processing. As mentioned earlier,
the entire Android project can be downloaded here (its an eclipse project) where you can see the entire of this class and the rest of the code plugged together as a very simple RSS reader
0 comments: