simple GeoRSS parser

Basic Tutorials concerning: GUI, Views, Activites, XML, Layouts, Intents, ...

simple GeoRSS parser

Postby flowdi » Mon Feb 04, 2008 9:32 pm

GeoRSS - geotagged flickr-image parser

example usage:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. List<ContentValue> points = RSS.parseFeed("http://api.flickr.com/services/feeds/geo/?tags=ufo&lang=en-us&format=rss_200");
Parsed in 0.030 seconds, using GeSHi 1.0.8.4

(geotagged photos from flickr)

to zoom, pan and display in a map see: :src: viewtopic.php?t=464

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. public class RSS extends DefaultHandler {
  2.  
  3.         public static List parseFeed(String url) {
  4.                 SAXParserFactory spf = SAXParserFactory.newInstance();
  5.                 SAXParser sp;
  6.                 RSS handler = new RSS();
  7.                 try {
  8.                         sp = spf.newSAXParser();
  9.                         XMLReader xr = sp.getXMLReader();
  10.                         xr.setContentHandler(handler);
  11.                         xr.setErrorHandler(handler);
  12.                        
  13.                         URLConnection c = (new URL(url)).openConnection();
  14.                         c.setRequestProperty("User-Agent", "Android/m3-rc37a");
  15.                         xr.parse(new InputSource(c.getInputStream()));
  16.                        
  17.                 } catch (SAXParseException e) {
  18.                         e.printStackTrace();
  19.                 } catch (ParserConfigurationException e) {
  20.                         e.printStackTrace();
  21.                 } catch (SAXException e) {
  22.                         e.printStackTrace();
  23.                 } catch (MalformedURLException e) {
  24.                         e.printStackTrace();
  25.                 } catch (IOException e) {
  26.                         e.printStackTrace();
  27.                 }
  28.                
  29.                 return handler.result;
  30.         }
  31.  
  32.         private List result;
  33.         private ContentValues postBuffer;
  34.  
  35.         /* Efficiency is the name of the game here... */
  36.         private int mState;
  37.  
  38.         private static final int STATE_IN_ITEM = (1 << 2);
  39.         private static final int STATE_IN_ITEM_TITLE = (1 << 3);
  40.         private static final int STATE_IN_ITEM_LINK = (1 << 4);
  41.         private static final int STATE_IN_ITEM_DESC = (1 << 5);
  42.         private static final int STATE_IN_ITEM_DATE = (1 << 6);
  43.         private static final int STATE_IN_ITEM_AUTHOR = (1 << 7);
  44.         private static final int STATE_IN_TITLE = (1 << <img src="http://www.anddev.org/images/smilies/cool.png" alt="8)" title="Cool" />;
  45.         private static final int STATE_IN_ITEM_POINT = (1 << 9);
  46.  
  47.         private static HashMap<String, Integer> mStateMap;
  48.  
  49.         static
  50.         {
  51.                 mStateMap = new HashMap<String, Integer>();
  52.                 mStateMap.put("item", new Integer(STATE_IN_ITEM));
  53.                 mStateMap.put("entry", new Integer(STATE_IN_ITEM));
  54.                 mStateMap.put("title", new Integer(STATE_IN_ITEM_TITLE));
  55.                 mStateMap.put("link", new Integer(STATE_IN_ITEM_LINK));
  56.                 mStateMap.put("description", new Integer(STATE_IN_ITEM_DESC));
  57.                 mStateMap.put("content", new Integer(STATE_IN_ITEM_DESC));
  58.                 mStateMap.put("content:encoded", new Integer(STATE_IN_ITEM_DESC));
  59.                 mStateMap.put("dc:date", new Integer(STATE_IN_ITEM_DATE));
  60.                 mStateMap.put("updated", new Integer(STATE_IN_ITEM_DATE));
  61.                 mStateMap.put("pubDate", new Integer(STATE_IN_ITEM_DATE));
  62.                 mStateMap.put("dc:author", new Integer(STATE_IN_ITEM_AUTHOR));
  63.                 mStateMap.put("author", new Integer(STATE_IN_ITEM_AUTHOR));
  64.                 mStateMap.put("georss:point", new Integer(STATE_IN_ITEM_POINT));
  65.        
  66.         }
  67.  
  68.        
  69.         public RSS() {
  70.                 result = new ArrayList<Map>();
  71.         }
  72.        
  73.         public void startElement(String uri, String name, String qName,
  74.                         Attributes attrs)
  75.         {
  76.  
  77.                 Integer state = mStateMap.get(qName);
  78.  
  79.                 if (state != null)
  80.                 {
  81.                         mState |= state.intValue();
  82.  
  83.                         if (mState == STATE_IN_ITEM)
  84.                                 postBuffer = new ContentValues();
  85.                         else if ((mState & STATE_IN_ITEM) != 0 && state.intValue() == STATE_IN_ITEM_LINK)
  86.                         {
  87.                                 String href = attrs.getValue("href");
  88.  
  89.                                 if (href != null)
  90.                                         postBuffer.put("link", href);
  91.                         }
  92.                 }
  93.         }
  94.  
  95.         public void endElement(String uri, String name, String qName)
  96.         {
  97.                 Integer state = mStateMap.get(qName);
  98.  
  99.                 if (state != null)
  100.                 {
  101.                         mState &= ~(state.intValue());
  102.  
  103.                         if (state.intValue() == STATE_IN_ITEM)
  104.                         {
  105.                                 result.add(postBuffer);
  106.                         }
  107.                 }
  108.         }
  109.  
  110.         public void characters(char ch[], int start, int length)
  111.         {
  112.  
  113.                 if ((mState & STATE_IN_ITEM) == 0)
  114.                         return;
  115.  
  116.                 /*
  117.                  * We sort of pretended that mState was inclusive, but really only
  118.                  * STATE_IN_ITEM is inclusive here.  This is a goofy design, but it is
  119.                  * done to make this code a bit simpler and more efficient.
  120.                  */
  121.                 switch (mState)
  122.                 {
  123.                 case STATE_IN_ITEM | STATE_IN_ITEM_TITLE:
  124.                         postBuffer.put("title", new String(ch, start, length));
  125.                         break;
  126.                 case STATE_IN_ITEM | STATE_IN_ITEM_DESC:
  127.                         postBuffer.put("description", new String(ch, start, length));
  128.                         break;
  129.                 case STATE_IN_ITEM | STATE_IN_ITEM_LINK:
  130.                         postBuffer.put("link", new String(ch, start, length));
  131.                         break;
  132.                 case STATE_IN_ITEM | STATE_IN_ITEM_DATE:
  133.                         postBuffer.put("date", new String(ch, start, length));
  134.                         break;
  135.                 case STATE_IN_ITEM | STATE_IN_ITEM_AUTHOR:
  136.                         postBuffer.put("author", new String(ch, start, length));
  137.                         break;
  138.                 case STATE_IN_ITEM | STATE_IN_ITEM_POINT:
  139.                         String[] latlng = (new String(ch, start, length)).split(" ");
  140.                         postBuffer.put("lat", (int)(Double.valueOf(latlng[0])*1000000));
  141.                         postBuffer.put("lng", (int)(Double.valueOf(latlng[1])*1000000));
  142.                         break;
  143.                 default:
  144.                         /* Don't care... */
  145.                 }
  146.         }
  147. }
Parsed in 0.051 seconds, using GeSHi 1.0.8.4
User avatar
flowdi
Junior Developer
Junior Developer
 
Posts: 11
Joined: Sun Nov 25, 2007 6:39 pm

Top

Postby plusminus » Mon Feb 04, 2008 10:20 pm

Aw man this is really goofy (or better to say optimized ^^).
But anyway, thanks for sharing your code :).

Took some seconds to realize, what the hell you were doing there with the shifting and binary OR's :lol:
Idea is really cool but could be easier to understand ;)

Best Regards,
plusminus
Image
Image | Android Development Community / Tutorials
User avatar
plusminus
Site Admin
Site Admin
 
Posts: 2688
Joined: Wed Nov 14, 2007 8:37 pm
Location: Schriesheim, Germany

Postby flowdi » Tue Feb 05, 2008 5:08 pm

Hey you are really a caring admin plusminus :)
I like anddev and just wanted to contribute something back.
Your approval isn't due to me
just took the code from
http://code.google.com/p/android-rss/
and extended the georss:point
(don't understand the binary-shifting myself ;))
User avatar
flowdi
Junior Developer
Junior Developer
 
Posts: 11
Joined: Sun Nov 25, 2007 6:39 pm

Postby plusminus » Tue Feb 05, 2008 11:15 pm

Hello flowdi,
flowdi wrote:Hey you are really a caring admin plusminus :)

Doing the best I can :)
flowdi wrote:I like anddev and just wanted to contribute something back.

Taking and giving is the perfect base for good community :)
Or would you prefer others to keep their in secret ;)
flowdi wrote:Your approval isn't due to me
just took the code from
http://code.google.com/p/android-rss/
and extended the georss:point
(don't understand the binary-shifting myself ;))

Having a second look its even relatively easy to understand, and "smart" what he does.
With some comments it would be easy understand on the first look.

All status codes are a row of zeros with a single 1 in it, like 00010000 the position of the 1 depends on how far it got shifted (here it should be: "(1 << 4)"):
In startelement:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.           // convert tag-name to bit flag( like: "description" --> STATE_IN_ITEM_DESC)
  2.           Integer state = mStateMap.get(qName);
  3.  
  4.           if (state != null)
  5.           {
  6.                // Binary OR means i.e. :
  7.                // Before mState == 00000001
  8.                // mState |= 00010000  --> 00010001              
  9.                mState |= state.intValue();
Parsed in 0.034 seconds, using GeSHi 1.0.8.4

So every 1 (or Bit) is a marker, where/how_deep we are in the xml-tree, which gets compared to in the switch of the characters()-method:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.           switch (mState)
  2.           {
  3.           case STATE_IN_ITEM | STATE_IN_ITEM_TITLE:
Parsed in 0.034 seconds, using GeSHi 1.0.8.4


But in my view readability goes before such tiny performance-tweaks ;)

Regards,
plusminus
Last edited by plusminus on Wed Feb 06, 2008 5:06 pm, edited 1 time in total.
Image
Image | Android Development Community / Tutorials
User avatar
plusminus
Site Admin
Site Admin
 
Posts: 2688
Joined: Wed Nov 14, 2007 8:37 pm
Location: Schriesheim, Germany

Postby flowdi » Wed Feb 06, 2008 10:39 am

Thanks for the explanation :)
that's really tricky!
(and actually not that unreadable - at least I could modify/extend it without knowing exactly what was going on;))
User avatar
flowdi
Junior Developer
Junior Developer
 
Posts: 11
Joined: Sun Nov 25, 2007 6:39 pm

Postby plusminus » Wed Feb 06, 2008 5:06 pm

Yes, with comments it would have been 100x easier to understand ^^

Regards,
plusminus
Image
Image | Android Development Community / Tutorials
User avatar
plusminus
Site Admin
Site Admin
 
Posts: 2688
Joined: Wed Nov 14, 2007 8:37 pm
Location: Schriesheim, Germany

Top

Postby bluefloyd8 » Sun Feb 10, 2008 10:57 am

Geez! I wrote my own parser (using SAX) for GeoRss and made my own list view. Why couldnt I have seen this earlier and saved myself some work!!

This is actually one of the things I sort of expected Android to come with by default. Seems to me that GeoRss is going to become very popular in Android applications.
User avatar
bluefloyd8
Experienced Developer
Experienced Developer
 
Posts: 70
Joined: Tue Jan 22, 2008 3:57 am
Location: Indiana, USA

Postby plusminus » Sun Feb 10, 2008 12:56 pm

You should probably check anddev even more often :D

Regards,
plusminus
Image
Image | Android Development Community / Tutorials
User avatar
plusminus
Site Admin
Site Admin
 
Posts: 2688
Joined: Wed Nov 14, 2007 8:37 pm
Location: Schriesheim, Germany

Top

Return to Novice Tutorials

Who is online

Users browsing this forum: Yahoo [Bot] and 6 guests