Saturday, October 16, 2010

A simple RSS reader, using Android's org.xml.sax package.

In the last article, "Read XML Resources in Android, using XmlResourceParser: XML parsing interface", Android application read XML resource inside application. In the current article, a external XML will be read using Android SAX APIs.

The source of XML is "http://androidword.blogspot.com/feeds/posts/default", which is RSS feed of my blog.

SAX is the Simple API for XML, originally a Java-only API. SAX was the first widely adopted API for XML in Java, and is a “de facto” standard. The current version is SAX 2.0.1, and there are versions for several programming language environments other than Java.

org.xml.sax is a Android's package provides the core SAX APIs.

In order to make it simple, only the contents under "title" tag will be retrieved and appended as a string.


To allow the Android application, "android.permission.INTERNET" have to be granted to the application. Modify AndroidManifest.xml



<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.exercise.AndroidRssReader"
    android:versionCode="1"
    android:versionName="1.0">
  <application android:icon="@drawable/icon" android:label="@string/app_name">
      <activity android:name=".AndroidRssReader"
                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="4" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>


Modify main.xml to add a TextView to display the result.
<?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="@string/hello" />
<ScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:id="@+id/result" />
</ScrollView>
</LinearLayout>


Java source code.
package com.exercise.AndroidRssReader;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

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

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class AndroidRssReader extends Activity {

String streamTitle = "";

  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
    
      TextView result = (TextView)findViewById(R.id.result);
    
      try {
  URL rssUrl = new URL("http://androidword.blogspot.com/feeds/posts/default");
  SAXParserFactory mySAXParserFactory = SAXParserFactory.newInstance();
  SAXParser mySAXParser = mySAXParserFactory.newSAXParser();
  XMLReader myXMLReader = mySAXParser.getXMLReader();
  RSSHandler myRSSHandler = new RSSHandler();
  myXMLReader.setContentHandler(myRSSHandler);
  InputSource myInputSource = new InputSource(rssUrl.openStream());
  myXMLReader.parse(myInputSource);
 
  result.setText(streamTitle);
 
 } catch (MalformedURLException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
  result.setText("Cannot connect RSS!");
 } catch (ParserConfigurationException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
  result.setText("Cannot connect RSS!");
 } catch (SAXException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
  result.setText("Cannot connect RSS!");
 } catch (IOException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
  result.setText("Cannot connect RSS!");
 }
    
    
  }

  private class RSSHandler extends DefaultHandler
  {
   final int stateUnknown = 0;
   final int stateTitle = 1;
   int state = stateUnknown;
  
   int numberOfTitle = 0;
   String strTitle = "";
   String strElement = "";
  
 @Override
 public void startDocument() throws SAXException {
  // TODO Auto-generated method stub
  strTitle = "--- Start Document ---\n";
 }

 @Override
 public void endDocument() throws SAXException {
  // TODO Auto-generated method stub
  strTitle += "--- End Document ---";
  streamTitle = "Number Of Title: " + String.valueOf(numberOfTitle) + "\n"
     + strTitle;
 }

 @Override
 public void startElement(String uri, String localName, String qName,
   Attributes attributes) throws SAXException {
  // TODO Auto-generated method stub
  if (localName.equalsIgnoreCase("title"))
  {
   state = stateTitle;
   strElement = "Title: ";
   numberOfTitle++;
  }
  else
  {
   state = stateUnknown;
  }
 }

 @Override
 public void endElement(String uri, String localName, String qName)
   throws SAXException {
  // TODO Auto-generated method stub
  if (localName.equalsIgnoreCase("title"))
  {
   strTitle += strElement + "\n";
  }
  state = stateUnknown;
 }

 @Override
 public void characters(char[] ch, int start, int length)
   throws SAXException {
  // TODO Auto-generated method stub
  String strCharacters = new String(ch, start, length);
  if (state == stateTitle)
  {
   strElement += strCharacters;
  }
 }
  
  }
}



Your Ad Here