【问题标题】:How to Build a RSS reader for Android?如何为 Android 构建一个 RSS 阅读器?
【发布时间】:2011-05-23 07:10:11
【问题描述】:

我是 android 新手,我正在尝试为 Android 构建一个 RSS 阅读器。我已经构建了所有的类和 XML 文件,但它没有提供所需的输出。它只是显示消息 No RSS feed available.

请有人建议我应该怎么做。

这是我从教程中获取并尝试操作的代码-

public final String RSSFEEDOFCHOICE = "http://blog.01synergy.com/feed/";

public final String tag = "RSSReader";
private RSSFeed feed = null;

/** Called when the activity is first created. */

public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    setContentView(R.layout.main);

    // go get our feed!
    feed = getFeed(RSSFEEDOFCHOICE);

    // display UI
    UpdateDisplay();

}


private RSSFeed getFeed(String urlToRssFeed)
{
    try
    {
        // setup the url
       URL url = new URL(urlToRssFeed);

       // create the factory
       SAXParserFactory factory = SAXParserFactory.newInstance();
       // create a parser
       SAXParser parser = factory.newSAXParser();

       // create the reader (scanner)
       XMLReader xmlreader = parser.getXMLReader();
       // instantiate our handler
       RSSHandler theRssHandler = new RSSHandler();
       // assign our handler
       xmlreader.setContentHandler(theRssHandler);
       // get our data via the url class
       InputSource is = new InputSource(url.openStream());
       // perform the synchronous parse           
       xmlreader.parse(is);
       // get the results - should be a fully populated RSSFeed instance, or null on error
       return theRssHandler.getFeed();
    }
    catch (Exception ee)
    {
        // if we have a problem, simply return null
        return null;
    }
}
public boolean onCreateOptionsMenu(Menu menu) 
{
    super.onCreateOptionsMenu(menu);

    menu.add(0,0,0, "Choose RSS Feed");
    menu.add(0,1,0, "Refresh");
    Log.i(tag,"onCreateOptionsMenu");
    return true;
}

public boolean onOptionsItemSelected(Menu item){
    switch (((View) item).getId()) {
    case 0:

        Log.i(tag,"Set RSS Feed");
        return true;
    case 1:
        Log.i(tag,"Refreshing RSS Feed");
        return true;
    }
    return false;
}


private void UpdateDisplay()
{
    TextView feedtitle = (TextView) findViewById(R.id.feedtitle);
    TextView feedpubdate = (TextView) findViewById(R.id.feedpubdate);
    ListView itemlist = (ListView) findViewById(R.id.itemlist);


    if (feed == null)
    {
        feedtitle.setText("No RSS Feed Available");
        return;
    }

    feedtitle.setText(feed.getTitle());
    feedpubdate.setText(feed.getPubDate());

    ArrayAdapter<RSSItem> adapter = new ArrayAdapter<RSSItem>(this,android.R.layout.simple_list_item_1,feed.getAllItems());

    itemlist.setAdapter(adapter);

    itemlist.setOnItemClickListener(this);

    itemlist.setSelection(0);

}


 public void onItemClick(AdapterView parent, View v, int position, long id)
 {
     Log.i(tag,"item clicked! [" + feed.getItem(position).getTitle() + "]");

     Intent itemintent = new Intent(this,ShowDescription.class);

     Bundle b = new Bundle();
     b.putString("title", feed.getItem(position).getTitle());
     b.putString("description", feed.getItem(position).getDescription());
     b.putString("link", feed.getItem(position).getLink());
     b.putString("pubdate", feed.getItem(position).getPubDate());

     itemintent.putExtra("android.intent.extra.INTENT", b);

     startSubActivity(itemintent,0);
 }


private void startSubActivity(Intent itemintent, int i) {
    // TODO Auto-generated method stub

}

}

【问题讨论】:

  • 您的问题很难回答,但如果您愿意,可以看看这些code.google.com/p/android-rss
  • 您能否发布您的代码。
  • 您好,如果您可以提供代码,那么我可以找出您代码中的问题
  • 感谢所有人的帮助。我更改了我的提要网站,现在它显示提要,但不是单击列表视图中的列表项时的描述。

标签: android rss-reader


【解决方案1】:

这是我第一个使用 RSS 阅读器的方法,它没有那么动态,并且有样板代码,但对我自己来说效果很好。

用法:

RssParser parser = new RssParser(feedUrl);
Log.i("LOG", "Description: " + parser.getItem(3).description); //4th item's description

类:

package com.uncocoder.course.app.feed_reader;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
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.util.Log;


public class RssParser extends DefaultHandler {

    private StringBuilder   content;
    private boolean         inChannel;
    private boolean         inImage;
    private boolean         inItem;

    private ArrayList<Item> items   = new ArrayList<Item>();
    private Channel         channel = new Channel();

    private Item            lastItem;


    public RssParser(String url) {
        try {
            SAXParserFactory spf = SAXParserFactory.newInstance();
            SAXParser sp = spf.newSAXParser();
            XMLReader xr = sp.getXMLReader();
            URL sourceUrl = new URL(url);
            xr.setContentHandler(this);
            xr.parse(new InputSource(sourceUrl.openStream()));
        }
        catch (ParserConfigurationException e) {
            e.printStackTrace();
        }
        catch (SAXException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }


    public class Item {

        public String title;
        public String description;
        public String link;
        public String category;
        public String pubDate;
        public String guid;
    }


    public class Channel {

        public String title;
        public String description;
        public String link;
        public String lastBuildDate;
        public String generator;
        public String imageUrl;
        public String imageTitle;
        public String imageLink;
        public String imageWidth;
        public String imageHeight;
        public String imageDescription;
        public String language;
        public String copyright;
        public String pubDate;
        public String category;
        public String ttl;
    }


    @Override
    public void startDocument() throws SAXException {
        Log.i("LOG", "StartDocument");
    }


    @Override
    public void endDocument() throws SAXException {
        Log.i("LOG", "EndDocument");
    }


    @Override
    public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
        if (localName.equalsIgnoreCase("image")) {
            inImage = true;
        }

        if (localName.equalsIgnoreCase("channel")) {
            inChannel = true;
        }

        if (localName.equalsIgnoreCase("item")) {
            lastItem = new Item();
            items.add(lastItem);
            inItem = true;
        }

        content = new StringBuilder();
    }


    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if (localName.equalsIgnoreCase("image")) {
            inImage = false;
        }

        if (localName.equalsIgnoreCase("channel")) {
            inChannel = false;
        }

        if (localName.equalsIgnoreCase("item")) {
            inItem = false;
        }

        if (localName.equalsIgnoreCase("title")) {
            if (content == null) {
                return;
            }

            if (inItem) {
                lastItem.title = content.toString();
            } else if (inImage) {
                channel.imageTitle = content.toString();
            } else if (inChannel) {
                channel.title = content.toString();
            }

            content = null;
        }

        if (localName.equalsIgnoreCase("description")) {
            if (content == null) {
                return;
            }

            if (inItem) {
                lastItem.description = content.toString();
            } else if (inImage) {
                channel.imageDescription = content.toString();
            } else if (inChannel) {
                channel.description = content.toString();
            }

            content = null;
        }

        if (localName.equalsIgnoreCase("link")) {
            if (content == null) {
                return;
            }

            if (inItem) {
                lastItem.link = content.toString();
            } else if (inImage) {
                channel.imageLink = content.toString();
            } else if (inChannel) {
                channel.link = content.toString();
            }

            content = null;
        }

        if (localName.equalsIgnoreCase("category")) {
            if (content == null) {
                return;
            }

            if (inItem) {
                lastItem.category = content.toString();
            } else if (inChannel) {
                channel.category = content.toString();
            }

            content = null;
        }

        if (localName.equalsIgnoreCase("pubDate")) {
            if (content == null) {
                return;
            }

            if (inItem) {
                lastItem.pubDate = content.toString();
            } else if (inChannel) {
                channel.pubDate = content.toString();
            }

            content = null;
        }

        if (localName.equalsIgnoreCase("guid")) {
            if (content == null) {
                return;
            }

            lastItem.guid = content.toString();
            content = null;
        }

        if (localName.equalsIgnoreCase("url")) {
            if (content == null) {
                return;
            }

            channel.imageUrl = content.toString();
            content = null;
        }

        if (localName.equalsIgnoreCase("width")) {
            if (content == null) {
                return;
            }

            channel.imageWidth = content.toString();
            content = null;
        }

        if (localName.equalsIgnoreCase("height")) {
            if (content == null) {
                return;
            }

            channel.imageHeight = content.toString();
            content = null;
        }

        if (localName.equalsIgnoreCase("language")) {
            if (content == null) {
                return;
            }

            channel.language = content.toString();
            content = null;
        }

        if (localName.equalsIgnoreCase("copyright")) {
            if (content == null) {
                return;
            }

            channel.copyright = content.toString();
            content = null;
        }

        if (localName.equalsIgnoreCase("ttl")) {
            if (content == null) {
                return;
            }

            channel.ttl = content.toString();
            content = null;
        }
    }


    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        if (content == null) {
            return;
        }

        content.append(ch, start, length);
    }


    public Item getItem(int index) {
        return items.get(index);
    }
}

【讨论】:

    【解决方案2】:

    查看以下链接,它是 Android 的开源 RSS 阅读器,您可以下载代码供参考

    http://code.google.com/p/android-rss/

    【讨论】:

    • 我们在同一时间发布所有内容。 :-)
    • 感谢 KPBird 和 subspider 的帮助,我看过这个网站,但我已经把更多时间花在了 ibm 的教程上,你能给我一些与此相关的建议吗?
    • 我更改了我的提要网站,现在它显示提要,但不是在列表视图中单击列表项时对项目的描述,你能帮我实现它吗?我的程序没有显示错误.
    • 它有 GPL 许可证。不是说不管你创建什么应用,你的应用也需要开源吗?
    【解决方案3】:

    这里有一个关于如何构建Android RSS reder的教程(包括完整的源代码):

    part 1 (complete application)

    part 2 (application updated to parse image tags from desciption)

    part 3 (application update with Android 3.0)

    本教程使用 SAX 解析器并包含一个完整的 Android 项目,该项目访问 RSS 提要,然后在列表视图中显示提要。

    似乎仍然有很多人对此感兴趣 - 所以如果您正在寻找带有片段/异步任务等以及完整应用程序代码的 Android 3.0+,我已经再次更新了帖子,@987654324 @

    【讨论】:

      【解决方案4】:

      您可以在google-play 上下载并查看我的项目。 这个项目是关于一些土耳其体育频道的提要。许多频道都在一个应用程序中。

      您可以在github查看项目源代码。

      【讨论】:

      • 它的许可证是什么?另外,是否可以告诉它仅加载 RSS 提要的最新帖子?
      • 我添加了许可文件。是的,它会加载最新的 RSS 提要。 @androiddeveloper
      • 我的意思是,如果我能告诉它有多少。如果我只需要 1,它只会加载它,而不需要解析其他的。
      • 您可以在 RssHandler 类中将此变量设置为 ARTICLES_LIMIT。这将显示您要加载多少个提要。 @androiddeveloper
      • 不错。谢谢
      【解决方案5】:

      使用XmlPullParser轻松解析这种类型的Rss Feed

           public class RSSParser {
      
      public static ArrayList<Pojo> getParserData(String Data){
          try {
              RSSXMLTag currentTag = null;
              ArrayList<Pojo> postDataList = new ArrayList<>();
              XmlPullParserFactory factory = XmlPullParserFactory
                      .newInstance();
              factory.setNamespaceAware(true);
              XmlPullParser xpp = factory.newPullParser();
              xpp.setInput(new StringReader(Data));
      
              int eventType = xpp.getEventType();
              Pojo pdData = null;
              SimpleDateFormat dateFormat = new SimpleDateFormat(
                      "EEEE, DD MMM yyyy ");
              while (eventType != XmlPullParser.END_DOCUMENT) {
                  int i = 0;
                  if (eventType == XmlPullParser.START_DOCUMENT) {
      
                  } else if (eventType == XmlPullParser.START_TAG) {
                      if (xpp.getName().equals("item")) {
      
                          pdData = new Pojo();
      
                          currentTag = RSSXMLTag.IGNORETAG;
                      } else if (xpp.getName().equals("title")) {
                          currentTag = RSSXMLTag.TITLE;
                      } else if (xpp.getName().equals("link")) {
                          currentTag = RSSXMLTag.LINK;
                      } else if (xpp.getName().equals("pubDate")) {
                          currentTag = RSSXMLTag.DATE;
                      } else if (xpp.getName().equals("creator")) {
      
                          currentTag = RSSXMLTag.CREATOR;
                      } else if (xpp.getName().equals("category")) {
                          currentTag = RSSXMLTag.CATEGORY;
                      } else if (xpp.getName().equals("description")) {
                          currentTag = RSSXMLTag.DESCRIPTION;
                      }
                  } else if (eventType == XmlPullParser.END_TAG) {
                      if (xpp.getName().equals("item")) {
                          // format the data here, otherwise format data in
                          // Adapter
                          Date postDate = dateFormat.parse(pdData.postDate);
                          pdData.postDate = dateFormat.format(postDate);
                          postDataList.add(pdData);
                      } else {
                          currentTag = RSSXMLTag.IGNORETAG;
                      }
                  } else if (eventType == XmlPullParser.TEXT) {
                      String content = xpp.getText();
                      content = content.trim();
                      Log.d("debug", content);
                      if (pdData != null) {
                          switch (currentTag) {
                              case TITLE:
                                  if (content.length() != 0) {
                                      if (pdData.postTitle != null) {
                                          pdData.postTitle += content;
                                      } else {
                                          pdData.postTitle = content;
                                      }
                                  }
                                  break;
                              case LINK:
                                  if (content.length() != 0) {
                                      if (pdData.postLink != null) {
                                          pdData.postLink += content;
                                      } else {
                                          pdData.postLink = content;
                                      }
                                  }
                                  break;
                              case DATE:
                                  if (content.length() != 0) {
                                      if (pdData.postDate != null) {
                                          pdData.postDate += content;
                                      } else {
                                          pdData.postDate = content;
                                      }
                                  }
                                  break;
                              case CATEGORY:
                                  if (content.length() != 0) {
                                      if (pdData.postCategory != null) {
                                          i = i + 1;
                                          if (i == 1) {
                                              pdData.postCategory = content;
                                          }
                                      } else {
                                          i = i + 1;
                                          if (i == 1) {
                                              pdData.postCategory = content;
                                          }
                                      }
                                  }
                                  break;
                              case DESCRIPTION:
                                  if (content.length() != 0) {
                                      if (pdData.postDescription != null) {
                                          String s = content;
      
                                          String string = s.substring(s.indexOf("src=\"") + 5, s.indexOf("\" class=\""));
                                          pdData.postDescription += string;
                                      } else {
                                          String s = content;
      
                                          String string = s.substring(s.indexOf("src=\"") + 5, s.indexOf("\" class=\""));
                                          pdData.postDescription = string;
                                      }
                                  }
                                  break;
                              case CREATOR:
                                  if (content.length() != 0) {
                                      if (pdData.postCreator != null) {
                                          pdData.postCreator += content;
                                      } else {
                                          pdData.postCreator = content;
                                      }
                                  }
                                  break;
                              default:
                                  break;
                          }
                      }
                  }
      
                  eventType = xpp.next();
              }
              return postDataList;
          }catch (Exception e){
              e.printStackTrace();
          }
      
          return null;
      }
      
      public enum RSSXMLTag {
          IGNORETAG, TITLE, LINK, DATE,CREATOR,CATEGORY, DESCRIPTION;
      }
      
      
      public class Pojo {
      
      
      public String getPostTitle() {
          return postTitle;
      }
      
      public void setPostTitle(String postTitle) {
          this.postTitle = postTitle;
      }
      
      public String getPostLink() {
          return postLink;
      }
      
      public void setPostLink(String postLink) {
          this.postLink = postLink;
      }
      
      public String getPostDate() {
          return postDate;
      }
      
      public void setPostDate(String postDate) {
          this.postDate = postDate;
      }
      
      public String getPostCategory() {
          return postCategory;
      }
      
      public void setPostCategory(String postCategory) {
          this.postCategory = postCategory;
      }
      
      public String getPostDescription() {
          return postDescription;
      }
      
      public void setPostDescription(String postDescription) {
          this.postDescription = postDescription;
      }
      
      public String getPostCreator() {
          return postCreator;
      }
      
      public void setPostCreator(String postCreator) {
          this.postCreator = postCreator;
      }
      
      public String postTitle;
      
      public String postLink;
      
      public String postDate;
      
      public String postCategory;
      
      public String postDescription;
      public String postCreator;
      }
      
      
      }
      

      【讨论】:

        猜你喜欢
        • 2013-06-07
        • 1970-01-01
        • 2019-09-20
        • 1970-01-01
        • 2015-08-06
        • 1970-01-01
        • 1970-01-01
        • 2013-01-13
        • 2023-03-09
        相关资源
        最近更新 更多