【发布时间】:2016-12-21 18:03:55
【问题描述】:
我有这个网址:http://www.webpronews.com/feeds
现在我需要获取提要并在 android 中显示它。有什么线索吗?
【问题讨论】:
标签: android
我有这个网址:http://www.webpronews.com/feeds
现在我需要获取提要并在 android 中显示它。有什么线索吗?
【问题讨论】:
标签: android
我使用 lib xmlpull_1_1_3_4c.jar,例如阅读下面的 twitter 提要 (rss)。
XML Pull 是开源的。您只需要根据您的提要调整标签。如果您在网上找不到罐子,我可以通过电子邮件将其发送给您。我不记得我从哪里得到它,它曾经在 xmlpull.org,但不知道它现在在哪里。 我从 http://www.ibm.com/developerworks/opensource/library/x-android/ 链接的某个地方得到它
import org.developerworks.android.FeedParser;
import org.developerworks.android.FeedParserFactory;
import org.developerworks.android.Message;
import org.developerworks.android.ParserType;
import org.xmlpull.v1.XmlSerializer;
....
loadFeed(ParserType.ANDROID_SAX);
....
private void loadFeed(ParserType type){
try{
Log.i("AndroidNews", "ParserType="+type.name());
FeedParser parser = FeedParserFactory.getParser(type);
long start = System.currentTimeMillis();
messages = parser.parse();
long duration = System.currentTimeMillis() - start;
String xml = writeXml();
titles = new ArrayList<String>(messages.size());
for (Message msg : messages){
titles.add(msg.getTitle());
}
} catch (Throwable t){
Log.e("AndroidNews",t.getMessage(),t);
}
}
private String writeXml() {
XmlSerializer serializer = Xml.newSerializer();
StringWriter writer = new StringWriter();
try {
serializer.setOutput(writer);
serializer.startDocument("UTF-8", true);
serializer.startTag("", "messages");
serializer.attribute("", "number", String.valueOf(messages.size()));
for (Message msg: messages){
serializer.startTag("", "message");
serializer.attribute("", "date", msg.getDate());
serializer.startTag("", "title");
serializer.text(msg.getTitle());
serializer.endTag("", "title");
serializer.startTag("", "url");
serializer.text(msg.getLink().toExternalForm());
serializer.endTag("", "url");
serializer.startTag("", "body");
serializer.text(msg.getDescription());
serializer.endTag("", "body");
serializer.endTag("", "message");
}
serializer.endTag("", "messages");
serializer.endDocument();
return writer.toString();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
编辑:
这是使用 ArrayAdapter 将提要填充到列表视图的整个类,但任何数据库上都没有光标,因为我不在本地存储提要:
import android.app.ProgressDialog;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Html;
import android.util.Log;
import android.util.Xml;
import android.view.Gravity;
import android.view.View;
import android.widget.*;
import org.developerworks.android.FeedParser;
import org.developerworks.android.FeedParserFactory;
import org.developerworks.android.Message;
import org.developerworks.android.ParserType;
import org.xmlpull.v1.XmlSerializer;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
public class Twitter extends BaseActivity implements
AdapterView.OnItemClickListener {
private List<Message> messages;
private List<String> titles;
//TweetsAdapter ta = new TweetsAdapter(this);
public ListView lstTweets = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.twitter);
// set header title
((TextView)findViewById(R.id.txtHeaderTitle)).setText( Html.fromHtml("<b>" + getResources().getString(R.string.activity_title_twitter) +"</b>"));
// highlight icon
ImageButton btn = (ImageButton)findViewById(R.id.btnTwitter);
btn.setBackgroundResource(R.drawable.menu_icon_twitter_active);
// load list of tweets
lstTweets = (ListView)findViewById(R.id.lstTweets);
lstTweets.setOnItemClickListener(this);
new AsyncTask<Void, Void, Void>() {
ProgressDialog p;
boolean success = false;
@Override
protected void onPostExecute(Void aVoid) {
p.dismiss();
if (!success) {
Twitter.this.runOnUiThread(new Runnable() {
public void run() {
Toast toast = Toast.makeText(Twitter.this, "Sorry, could not connect to Twitter.", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL, 0, 0);
toast.show();
}
});
} else {
ArrayAdapter<String> adapter =
new ArrayAdapter<String>(Twitter.this, R.layout.twitter_list_row,titles);
lstTweets.setAdapter(adapter);
}
}
@Override
protected void onPreExecute() {
p = ProgressDialog.show(Twitter.this,"Loading...","...please wait a moment.");
}
@Override
protected Void doInBackground(Void... params) {
try {
loadFeed(ParserType.ANDROID_SAX);
if (messages!=null&&messages.size()>0) success = true;
} catch (RuntimeException e) {}
catch (Exception e) {}
return null;
}
}.execute();
}
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
Intent viewMessage = new Intent(Intent.ACTION_VIEW,
Uri.parse(messages.get(position).getLink().toExternalForm()));
this.startActivity(viewMessage);
}
private void loadFeed(ParserType type){
try{
Log.i("AndroidNews", "ParserType="+type.name());
FeedParser parser = FeedParserFactory.getParser(type);
long start = System.currentTimeMillis();
messages = parser.parse();
long duration = System.currentTimeMillis() - start;
String xml = writeXml();
titles = new ArrayList<String>(messages.size());
for (Message msg : messages){
titles.add(msg.getTitle());
}
} catch (Throwable t){
Log.e("AndroidNews",t.getMessage(),t);
}
}
private String writeXml(){
XmlSerializer serializer = Xml.newSerializer();
StringWriter writer = new StringWriter();
try {
serializer.setOutput(writer);
serializer.startDocument("UTF-8", true);
serializer.startTag("", "messages");
serializer.attribute("", "number", String.valueOf(messages.size()));
for (Message msg: messages){
serializer.startTag("", "message");
serializer.attribute("", "date", msg.getDate());
serializer.startTag("", "title");
serializer.text(msg.getTitle());
serializer.endTag("", "title");
serializer.startTag("", "url");
serializer.text(msg.getLink().toExternalForm());
serializer.endTag("", "url");
serializer.startTag("", "body");
serializer.text(msg.getDescription());
serializer.endTag("", "body");
serializer.endTag("", "message");
}
serializer.endTag("", "messages");
serializer.endDocument();
return writer.toString();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
【讨论】:
实现起来并不简单。
RSS 文件是一种结构符合标准(固定标签名称)的 XML 文件。
在您的应用程序中,您需要:
【讨论】:
DavLink,是对的。 RSS 解析并非易事。
设置一个 SAX 解析器的实现相当容易,但难的部分是能够在阳光下解析任何和每个提要。
您需要满足所有格式的 RSS 1、RSS 2、Atom 等。即便如此,您也必须应对格式不佳的提要。
我过去曾遇到过类似的问题,因此决定在服务器上进行提要解析并获取解析后的内容。这允许我运行更复杂的库和解析器,我可以在不为我的应用推出更新的情况下对其进行修改。
我在 AppEngine 上运行了以下服务,它允许您最终进行更简单的 XML / JSON 解析。响应有一个固定而简单的结构。你可以用它来解析
http://evecal.appspot.com/feedParser
您可以使用以下参数发送 POST 和 GET 请求。
feedLink : RSS feed 响应的 URL : JSON 或 XML 作为响应格式
例子:
对于 POST 请求
curl --data-urlencode "feedLink=http://feeds.bbci.co.uk/news/world/rss.xml" --data-urlencode "response=json" http://evecal.appspot.com/feedParser
对于 GET 请求
evecal.appspot.com/feedParser?feedLink=http://feeds.nytimes.com/nyt/rss/HomePage&response=xml
我的安卓应用“NewsSpeak”也使用这个。
获得信息后,您可以使用一个简单的列表视图和一个包含您的项目数组的数组适配器。
【讨论】: