RSS Demon

From Mobile Application Design
Revision as of 04:08, 8 February 2007 by 67.101.148.212 (talk)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search
/**
 * RSS Demon
 * a modified version of my XMLDemon example uses kXML2 to parse RSS feeds
 * 
 * NOTE: Uses techniques and code from Tommi Laukkanen's RSS Reader - http://www.substanceofcode.com
 * copyleft Michael Sharon 2006
 */

package my; 

import java.io.*;
import java.util.Vector;

import org.kxml2.io.*;
import org.xmlpull.v1.*;

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.io.*;

public class RSSDemon extends MIDlet implements CommandListener {

	//add any RSS feed here
	
	//NY Times Music Feed
	static final String rssFeedURL = "http://www.nytimes.com/services/xml/rss/nyt/Music.xml";
	
	//BBC News Feed
	//static final String rssFeedURL = "http://newsrss.bbc.co.uk/rss/newsonline_world_edition/front_page/rss.xml";	
	
	//An empty feed which will cause an error
	//static final String rssFeedURL = "http://uberthings.com/teaching/mobile_application_design/7/empty.xml";
	
	//BBC
	//The title of your RSS feed
	static final String TITLE = "NY Times Music";

	//Vector stores a variable number of items from the feed
	Vector foundItems = new Vector();
	
	//Holds all our items
	List itemList = new List(TITLE, Choice.IMPLICIT);
	
	TextBox textBox = new TextBox("", "", 256, TextField.ANY);
	
	Display display;

	Command backCmd = new Command("Back", Command.BACK, 0);

	public void startApp() {
		
		//get a reference to the display object
		display = Display.getDisplay(this);
		
		//set up listeners and commands
		itemList.setCommandListener(this);
		textBox.setCommandListener(this);
		textBox.addCommand(backCmd);
		
		//show the list of items
		display.setCurrent(itemList);
		
		//create a new thread and start it
		new ReadThread().start();
	}

	public void pauseApp() {
	}

	public void commandAction(Command c, Displayable d) {

		if (c == List.SELECT_COMMAND) {

			//retrieve the specific item that we have selected
			String text = (String) foundItems.elementAt(itemList.getSelectedIndex());

			if (textBox.getMaxSize() < text.length())
				textBox.setMaxSize(text.length());

			textBox.setString(text);
			display.setCurrent(textBox);
		} else if (c == backCmd)
			display.setCurrent(itemList);
	}

	public void destroyApp(boolean really) {
	}
	
	class ReadThread extends Thread {

		public void run() {
			try {
				HttpConnection httpConnection = (HttpConnection) Connector.open(rssFeedURL);
				
				KXmlParser parser = new KXmlParser();

				System.out.println("Grabbing XML and parsing");
				parser.setInput(new InputStreamReader(httpConnection.openInputStream()));
				
				System.out.println("looking for first tag");

				/** <?xml...*/
		        parser.nextTag();

		        //ignore other tags, wait for <item> tag
		        parser.require(parser.START_TAG, null, null);
		        while(!"item".equals(parser.getName()) ){
		            /** Check if document doesn't include any item tags */
		            if( parser.next() == parser.END_DOCUMENT )
		                throw new IOException("No items in RSS feed!");
		        }			
				
		        /** Parse <item> tags */
		        do {
		        readItem(parser);     
		        } while("item".equals(parser.getName()));

			} catch (Exception e) {
				e.printStackTrace();
				foundItems.addElement(e.toString());
				itemList.append("Error", null);
			}
		}

		// Read a story and append it to the list
		void readItem(KXmlParser parser)
			throws IOException, XmlPullParserException {

			 parser.require(parser.START_TAG, null, null);

			 String title = null;
			 String description = null;

		            // Handles one <item> tag at a time
		            while (parser.nextTag() != parser.END_TAG) {
		                parser.require(parser.START_TAG, null, null);
		                String name = parser.getName();
		                String text = parser.nextText();
		                
		                //replace HTML entities
		                text = replace(text, "ä", "‰");
		                text = replace(text, "ö", "ˆ");
		                text = replace(text, "√§", "‰");
		                text = replace(text, "√∂", "ˆ");
		                
		                // Save item property values
		                if (name.equals("title")) {
		                    title = text;
		                }
		                else if (name.equals("description")) {
		                    description = text;
		                }

		                parser.require(parser.END_TAG, null, name);
		            }
		            
		            // Debugging information
		            System.out.println ("Title:       " + title);
		            System.out.println ("Description: " + description);

		            if (title != null) {
						foundItems.addElement(""+description);
						itemList.append(title, null);
					}
		            
		            parser.nextTag();
		}
	}

	  /* Replace all instances of a String in a String.
     *   @param  s  String to alter.
     *   @param  f  String to look for.
     *   @param  r  String to replace it with, or null to just remove it.
     */  
    public static String replace( String s, String f, String r )
    {
       if (s == null)  return s;
       if (f == null)  return s;
       if (r == null)  r = "";

       int index01 = s.indexOf( f );
       while (index01 != -1)
       {
          s = s.substring(0,index01) + r + s.substring(index01+f.length());
          index01 += r.length();
          index01 = s.indexOf( f, index01 );
       }
       return s;
    }  
    
}