2010-10-29 3 views

ответ

5

Я использую lib xmlpull_1_1_3_4c.jar и, например, читаю твиттер-каналы (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); 
    } 
} 

Edit:

Это весь класс, который заполняет каналы в виде списка, используя 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); 
    } 
} 
} 
+0

Я думаю, это URL: http://www.extreme.indiana.edu/xgws/xsoap/xpp/. Можете ли вы подробнее объяснить, что нам действительно нужно. Также вы можете пролить свет на другой ответ, который включает в себя 4 шага (ответ DavLink? Спасибо –

+0

что ваш прецедент? Вам действительно нужно хранить новости в БД локально? В моем приложении, например, я просто показываю твиттер-каналы в listview с их хранением, поэтому шаги 3,4 являются необязательными, я бы сказал, в зависимости от вашего использования. Вам также нужны новости, постоянно действующие/доступные в автономном режиме? –

+0

см. отредактированный ответ с целым классом, как показать каналы в просмотр списка. –

3

Это не просто реализовать.

Файл RSS - это XML-файл, структура которого соответствует стандарту (имена фиксированных тегов).

В приложении вам нужно будет:

  • Скачать на RSS-канал: использовать HttpClient, услуги ...
  • Извлечение данных из XML: использовать XML-анализатор, некоторые из них при условии
  • Хранить данные: лучшим решением является SQLite базы данных
  • Отображение данных: ListView с CursorAdapter указывающую на базу данных
+0

ok! Таким образом, есть 4 шага. Мне удастся выполнить последние 3 шага. Расскажите мне о первом. Как я могу загрузить RSS-канал в Android? –

+0

Сделано! :) У меня есть загружаемые каналы и сохранены в файле базы данных. У меня есть вопрос: что делает этот метод Xml.parse (this.getInputStream(), Xml.Encoding.ISO_8859_1, root.getContentHandler()); Вы можете посмотреть в классе AndroidSaxFeedParser.java. Cheers –

1

DavLink, справа. Разбор RSS не является тривиальным.

Очень просто настроить реализацию SAX-синтаксического анализатора, но сложная часть состоит в том, чтобы анализировать любые каналы под солнцем.

Вам необходимо угодить всем форматам RSS 1, RSS 2, Atom и т. Д. Даже тогда вам придется бороться с плохо отформатированными фидами.

В прошлом у меня были проблемы с подобными проблемами, поэтому я решил обработать фид на сервере и просто получить разобранное содержимое. Это позволяет мне запускать более сложные библиотеки и парсер, которые я могу изменить, не вытесняя обновления для моего приложения.

У меня есть следующая служба, запущенная на AppEngine, которая позволяет значительно упростить синтаксический анализ XML/JSON в конце. Для ответа есть фиксированная и простая структура. Вы можете использовать это для разбора

http://evecal.appspot.com/feedParser

Вы можете отправить как POST и GET запросы со следующими параметрами.

feedLink: URL ответа RSS Feed: JSON или XML в качестве формата ответа

Примеры:

Для запроса POST

локон --data-UrlEncode «feedLink = HTTP: //feeds.bbci.co.uk/news/world/rss.xml»--data-UrlEncode "ответ = JSON" http://evecal.appspot.com/feedParser

Для запроса GET

evecal. appspot.com/feedParser?feedLink=http://feeds.nytimes.com/nyt/rss/HomePage & response = xml

Мое приложение для Android «NewsSpeak» также использует это.

После того, как вы получите информацию, вы можете использовать простой listview с массивом, имеющим массив элементов.

Смежные вопросы