Java Tip: Set up an RSS feed for your Android application

Use Java's SAXParser to create an RSS feed for Android

Use Java's SAXParser to retrieve and parse an RSS feed for Android. This Java tip is for developers new to Android and includes instructions for setting up an Android development environment and a short application tutorial.

An RSS feed is an XML-formatted file used to publish periodically updated syndicated information. An RSS feed may be parsed (that is, read and formatted) using an XML parser. Java-compatible parsers used to parse XML on Android include:

  • android.content.res.XmlResourceParser is a pull parser
  • Simple API for XML (SAX) is found in the org.xml.sax package
  • Android ROME Feed Reader is Google’s RSS feed reader for Android
  • Android Feed Reader is another Google RSS/Atom feed reader for Android
  • Android-rss is a lightweight Android library for RSS 2.0 feeds

This Java tip is a step-by-step introduction to using the javax.xml.parsers.SAXParser to parse an RSS feed in XML format. SAXParser is a standard choice because it is included with the Android APIs in the Android SDK. We'll set up the development environment, create a simple Android app and feed for demonstration purposes, and then use SAXParser to format the feed for Android. While some familiarity with Java application development is assumed, this tip is suitable for developers new to Java mobile development.

Setting up the environment

Take the following steps to set up the development environment for this project:

  1. Install the Eclipse IDE.
  2. Install the Android Development Tools (ADT) plugin for Eclipse. The ADT plugin for Eclipse provides a set of extensions to develop Android applications in Eclipse.
  3. Install Android 2.3 SDK platform. Android SDK provides tools for developing Android applications.
  4. Create an Android Virtual Device and set the Target environment as Android 2.3.3. API Level 10.

The Android project

We'll create an example Android project to receive the RSS feed.

  1. In your Eclipse IDE select File-->New.
  2. In New select Android-->Android Project, then click Next.
  3. In the New Android Project window, specify a Project name (RSSFeed).
  4. Select Android Platform 2.3 API 10 for your Build Target.
  5. In Properties, specify an Application name (again, RSSFeed), and a Package name (android.rss).
  6. Select the checkbox: Create Activity, and specify the Activity class (RssFeed).
  7. Specify the minimum SDK version as 10 and click Next; or, if you've selected the Platform 3.0 API 11, then specify the minimum SDK Version as 11.

Note that an activity (Step 6) represents a user interaction. The class extending the Activity class creates a window for a UI.

The resulting Android project will consist of the following files:

  1. An activity class (RSSFeed), which extends Activity.
  2. A res/layout/main.xml file, which specifies the layout of the Android UI components.
  3. An AndroidManifest.xml file, which contains application configuration such as the package name, the main activity to launch when the Android application is started, application components, processes, permissions, and the minimum API level.

In res/layout/main.xml, specify the layout of the Android UI components. Create a LinearLayout and set android:orientation as "vertical." Our goal is to display the RSS feed as a text message, so add a TextView element for the title of the RSS feed and specify android:text as a Google RSS Feed. Add a TextView element, with id "rss" to display the RSS feed. Listing 1 shows the resulting main.xml.

Listing 1. Specifying the layout of Android UI components

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <TextView android:layout_width="fill_parent"
        android:layout_height="wrap_content" android:text="Google RSS Feed" />
    <TextView android:id="@+id/rss" android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

In AndroidManifest.xml, specify the Activity to launch as RSSFeed. To access the RSS feed from the Web on an Android device we need to enable the android.permission.INTERNET permission in AndroidManifest.xml, which allows applications to open network sockets. Add the following uses-permission element:

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

Specify the minimum Android version with the uses-sdk element. The RSSFeed activity, the intent-filter, and action are specified with the activity element and sub-elements, as shown in Listing 2.

Listing 2. AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="android.rss" android:versionCode="1" android:versionName="1.0">
    

    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".RSSFeed" android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application><uses-sdk android:minSdkVersion="10" />
    <uses-permission android:name="android.permission.INTERNET"></uses-permission>
    </manifest>

Parse the RSS feed for Android

Next we'll use the javax.xml.parsers.SAXParser to parse our RSS feed. Start by importing the following classes:

  • javax.xml.parsers.SAXParser
  • javax.xml.parsers.SAXParserFactory
  • org.xml.sax.InputSource
  • org.xml.sax.XMLReader
  • org.xml.sax.helpers.DefaultHandler

Recall that the RSSFeed class extends Activity. In the RSSFeed class, define a variable to output the RSS feed:

String rssResult = "";

The onCreate(Bundle savedInstanceState) method is invoked when the activity is started. In the onCreate method, set the user interface using the setContentView method and the layout resource:

setContentView(R.layout.main);

Next, we use the findViewById method to define the Android widget TextView object in main.xml:

TextView rss = (TextView) findViewById(R.id.rss);

Now use the the constructor for URL to specify the RSS feed URL:

URL rssUrl = new URL("http://www.javaworld.com/index.xml");

Note that the RSS feed consists of <item> elements for the feed items. Each <item> consists of title, description, link, creator, and date sub-elements.

Create the SAXParser

Create a SAXParserFactory object using the static method newInstance:

SAXParserFactory factory = SAXParserFactory.newInstance();

Create a SAXParser using the newSAXParser method:

SAXParser saxParser = factory.newSAXParser();

Obtain an XMLReader from the SAXParser using the getXMLReader method:

XMLReader xmlReader = saxParser.getXMLReader();

Handling SAX2 events

Next, we need to create a DefaultHandler to handle SAX2 events. SAX2 events are XML-parsing events such as the start and end of a document/element, and character data. For the DefaultHandler, first create a private class RSSHandler that extends the DefaultHandler class. Define the implementation for the event handler methods startElement and characters. Each feed item is contained in an <item> element. In the startElement method, if the localName is "item" add the localName to the rssResult String:

rssResult = rssResult + localName + ": ";

In the characters method, add the character data to the rssResult String. Use the replaceAll method to remove all extra spaces in the RSS feed:

String cdata = new String(ch, start, length);
    if (item == true)
    rssResult = rssResult +(cdata.trim()).replaceAll("\\s+", " ")+"\t";

In the onCreate method, create an RSSHandler object:

RSSHandler rssHandler = new RSSHandler();

Set the RSSHandler as a content handler on the XMLReader object using the setContentHandler method:

xmlReader.setContentHandler(rssHandler);

Create an InputSource object from the URL for the RSS feed. Open the URL stream using the openStream method:

InputSource inputSource = new InputSource(rssUrl.openStream());

Parse the InputSource using the parse method of the XMLReader object:

xmlReader.parse(inputSource);

Set the rssResult String generated from the RSS feed on the TextView element:

rss.setText(rssResult);

And with that, we're done. The complete Activity class RSSFeed is shown in Listing 3.

Listing 3. RSSFeed

package android.rss;

import android.app.Activity;
import android.os.Bundle;
import java.util.Stack;
import android.widget.TextView;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.util.StringTokenizer;

import java.net.MalformedURLException;
import java.net.URL;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import java.io.IOException;
import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class RSSFeed extends Activity {
    /** Called when the activity is first created. */
    String rssResult = "";
    boolean item = false;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        TextView rss = (TextView) findViewById(R.id.rss);
        try {
            URL rssUrl = new URL("http://www.javaworld.com/index.xml");
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser saxParser = factory.newSAXParser();
            XMLReader xmlReader = saxParser.getXMLReader();
            RSSHandler rssHandler = new RSSHandler();
            xmlReader.setContentHandler(rssHandler);
            InputSource inputSource = new InputSource(rssUrl.openStream());
            xmlReader.parse(inputSource);

        } catch (IOException e) {rss.setText(e.getMessage());
        } catch (SAXException e) {rss.setText(e.getMessage());
        } catch (ParserConfigurationException e) {rss.setText(e.getMessage());
        }

        rss.setText(rssResult);
    }
    /**public String removeSpaces(String s) {
          StringTokenizer st = new StringTokenizer(s," ",false);
          String t="";
          while (st.hasMoreElements()) t += st.nextElement();
          return t;
        }*/
    private class RSSHandler extends DefaultHandler {

        public void startElement(String uri, String localName, String qName,
                Attributes attrs) throws SAXException {
            if (localName.equals("item"))
                item = true;

            if (!localName.equals("item") && item == true)
                rssResult = rssResult + localName + ": ";

        }

        public void endElement(String namespaceURI, String localName,
                String qName) throws SAXException {

        }

        public void characters(char[] ch, int start, int length)
                throws SAXException {
            String cdata = new String(ch, start, length);
            if (item == true)
                rssResult = rssResult +(cdata.trim()).replaceAll("\\s+", " ")+"\t";

        }

    }
}

Running the Android application

Now let's see what happens when we run the Android application. First, right-click on the RSSFeed application in your Eclipse IDE and select Run As-->Android Application.

Your results will vary slightly based on configuration: If you've configured Android Platform 11 and API 3.0, then Platform 11 AVD will start up. If you've selected Android platform 10 and API 2.3, then platform 10 AVD will start. Either way, the RSSFeed application should be shown as deployed on the correct Android device.

Now click on the RSSFeed application to display the RSS feed, which should appear as shown in Figure 1.

Figure 1. RSS feed display for an Android device

In conclusion

In this Java tip you learned how to set up an RSS feed on Android using SAXParser, which comes bundled with the Android SDK. You can modify this application for any RSS feed by changing the RSS URL. We also did a simple exercise in formatting the RSS feed by removing extra spaces between listed articles.

Deepak Vohra is a Sun Certified Java Programmer, Sun Certified Web Component Developer, and has previously published articles on XML Journal, Java Developer's Journal, WebLogic Journal, and Java.net.

Learn more about this topic

Learn more about Android.

More from JavaWorld

  • Check out JavaWorld's Mobile Java research zone for more articles like this one.
  • See the JavaWorld Site Map for a complete listing of research centers focused on client-side, enterprise, and core Java development tools and topics.
  • JavaWorld's Java Technology Insider is a podcast series that lets you learn from Java technology experts on your way to work.
Join the discussion
Be the first to comment on this article. Our Commenting Policies
See more