Android RSS Reader Tutorial

1:33 PM , , 37 Comments

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

37 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. Thanx for the article. It was very helpful. How can I make the list clickable? For example when I click on the feed it'll open webview with the web page.

    ReplyDelete
  3. Hi.This is a nice tutorial and I also downloaded your code. It works fine.
    I am trying to read yahoo weather rss with the help of your code. Yahoo have an img tag inside the description tag. How can I read the img tag inside the description tag?? Can you plz help me.

    ReplyDelete
  4. This comment has been removed by the author.

    ReplyDelete
  5. Hello, I'm having the same problem Md.Rezaul Hoque, downloaded the code you provided but I am not able to read the images. The code worked but instead of pictures appears a small square of green. Could you help me?
    My email is leonelgda@gmail.com (could then edit this post to remove my email)
    I thank you for your attention!

    ReplyDelete
  6. hey guys, i have posted another post on the topic, hopefully this answers your questions you had!

    ReplyDelete
  7. hello...thanks for posting this android aap...but i too downloaded the source code and executed. but am having a problem...images are not accessing into the screen...
    please suggest me how to get the images into my activity screen...N how to run the aap correctly...
    thank you...

    ReplyDelete
  8. Hmmm, I downloaded the .zip file, imported the project but it wont build? It's full of errors.... I imported as android project into eclipse, it comes up fine in the navigator and looks like other projects i've built using tutorials (ones i've done step by step, i've never downlaoded a project before). I have the sdk and the eclipse android plugin... I don't understand, any help would be greatly appreciated. Thank you

    ReplyDelete
  9. Hi Ed, what errors are you seeing? which version of the SDK/Eclipse are you using?

    ReplyDelete
  10. Thanks for the reply, I got the project to build by specifying android.jar and then shift + control + O so it runs now but the feed doesn't load in the emulator, just a black screen. the feed still exists as I checked the url myself. Any idea? using sdk version 8 on an emulator running 8

    ReplyDelete
  11. i get this error i console:
    ActivityManager: Warning: Activity not started, its current task has been brought to the front

    ReplyDelete
  12. Ok, it seems the app was left running. After closing the one instance of it the error went away but still blank screen.

    ReplyDelete
  13. Ok, I will check the app - will update when i find something

    ReplyDelete
  14. I don't understand why it seems to work for others. It builds and pushes to the phone and the emulator but just doesn't display anything... hmmm

    ReplyDelete
  15. Not had a chance to investigate fully yet Ed, but have you tried changing the hardcoded feed that I use in the example?

    On my previous blog, in the comments, one of the posters experienced a similar issue to what you are describing and they changed the URL and it worked (the link to the comments is: http://automateddeveloper.blogspot.com/2010/08/android-and-rss.html#comments - but its basically the blog directly below this one!

    ReplyDelete
  16. Yes. After changing the feed it worked. Thank you. I am now tinkering with it but having problems with every textView redraw redrawing everything (like buttons)

    ReplyDelete
  17. Hmmm, let me try to explain this better. I want a list of buttons on the left in a vertical linear layout, with the textView with the data to the right of the buttons. The problem is that every time it repopulates the textView it redraws everything so I end up with a set of buttons for each article.

    ReplyDelete
  18. Never mind, I got it. I had to setContentView to R.layout.main, this allowed me to make changes.

    Thank you very much, this has been a very informative experience

    ReplyDelete
  19. Hi there,

    Seems I can't build the app unfortunately, the errors I'm getting are in RssListAdapter.java.

    View rowView = inflater.inflate(R.layout.image_text_layout, null);
    It is saying that image_text_layout cannot be resolved or is not a field.

    Also, TextView textView = (TextView) rowView.findViewById(R.id.job_text); under "R.id.job_text" has the same error.

    Thanks in advance for any input

    ReplyDelete
  20. Hi Mike,

    Which Android version are you using? can you check that your project (in eclipse), in /res/layout there exists image_text_layout.xml?

    ReplyDelete
  21. I have posted a new update with images - the source code is also updated to be downloaded.. http://automateddeveloper.blogspot.com/2011/05/android-rss-reader-20.html

    ReplyDelete
  22. Thanks for the post. This is very helpful to me.

    ReplyDelete
  23. using tumblr rss got bug ><"
    how to fix it?

    ReplyDelete
  24. This is one of the knowledgeable post.I like your blog details.I like your blog tips.Good.
    Android app developers

    ReplyDelete
  25. Nice tutorial! Of all the RSS feed apps I tried, less than half worked, and yours worked the best. I was able to use your utility to build an essential part of the app I'm working on! Thanks a ton!

    ReplyDelete
  26. This was wonderfully helpful. Thank you very much.

    I'm pretty new to Android development. The one aspect I can't figure out based on your tutorial is how to access the attributes in a way that they can be used in an onItemClickListener in RssActivity for presenting the information in AlertDialogs.

    Would you have any suggestions?

    ReplyDelete
  27. E/RSS Handler SAX(497): org.xml.sax.SAXException

    and all listview items show "JSON Exception"

    ReplyDelete
  28. Buddy ,.. i do really really need help trying to get the feeds from some website..to my android app in eclipse.

    ReplyDelete
  29. Hey there, guess im unburying this thread, but hey, the tut is awesome, and the app works (almost) great..

    On both your original feed and the one i tried to input there are rows with missing from the feed. I mean they are blank spaces on the app, and it just goes forward to the next .

    The ones that are displayed, are awesome, but i've tried and tried to check where the fault is, but cant find it.. Could you help me on this ?

    Thanks

    ReplyDelete
  30. I have been trying to modify your github repository of RSS FeedReader (very nice, by the way) to exclude the media:title type="html" tag contents . The titles in the feed I am looking at (from stuffilikenet.wordpress.com) look like this: title>Nanoparticulate Treatment of Autoimmunitiesstuffilikenet</media:title

    I freely admit that I know little of Android development, JAVA, or even programming at all. Your complete application I thought would make an excellent intellectual autopsy from which to learn the basics. Sadly, my brain's not up to snuff here.
    Can you offer me a hint about how to modify the JSON object construction to exclude the one tag's contents and use the other? I really am at a loss (several hours gone...do not feel it exactly as a loss of time, because I did clarify my question).

    Whether or not you can spare me time to answer, I appreciate the code nonetheless. Thank you.

    ReplyDelete
  31. I should add (always read the preview when offered) the code as written uses the media:title type="html" tag contents. I hope that was obvious, but I'm sleep-deprived.

    ReplyDelete
  32. Hello, thanks for this post.
    I have been able to get the code work for a lot of feeds except mine:
    http://www.punchng.com/feed

    I keep getting the following error:
    org.apache.harmony.xml.expatparser&parseexception: at line 14, column 2

    PLEASE HELP!!!
    what am i doing wrong?

    ReplyDelete
  33. I'm getting the following errors:

    ArticleDetailActivity > Line 7 > The import android.support cannot be resolved

    ArticleDetailActivity > Line 8 > The import android.support cannot be resolved

    ArticleDetailActivity > Line 11 > FragmentActivity cannot be resolved to a type

    ArticleDetailActivity > Line 15 > FragmentActivity cannot be resolved to a type

    and a BUNCH more.



    ReplyDelete
  34. when i put my rss feed xml file link :
    http://www.pokerlistings.com/feed/news

    i got following error

    org.apache.harmony.xml.ExpatParser$ParseException: At line 1, column 0: no element found

    Number of articles 0

    ReplyDelete
  35. Great blog! We offer affordable yet professional bespoke websiteApp Developer Leeds and software solutions to businesses in the Leeds area and throughout the UK.

    ReplyDelete
  36. This comment has been removed by a blog administrator.

    ReplyDelete
  37. hello,following your tutorial i have this error:

    E/RSS ERROR﹕ Error loading RSS Feed Stream >> null //android.os.NetworkOnMainThreadExcepti

    please help

    ReplyDelete