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
Page 2 of 2
<?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.
<?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>
Next we'll use the javax.xml.parsers.SAXParser to parse our RSS feed. Start by importing the following classes:
javax.xml.parsers.SAXParserjavax.xml.parsers.SAXParserFactoryorg.xml.sax.InputSourceorg.xml.sax.XMLReaderorg.xml.sax.helpers.DefaultHandlerRecall 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 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();
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.
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";
}
}
}
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.
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 Android.
More from JavaWorld