Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

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

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

  • Print
  • Feedback

Page 2 of 2

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.

About the author

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.

  • Print
  • Feedback

Resources

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.