2010-10-29 23 views

Respuesta

5

Utilizo lib xmlpull_1_1_3_4c.jar y, por ejemplo, leo feeds de Twitter (rss) como a continuación.

XML Pull es de código abierto. Solo necesita ajustar las etiquetas de acuerdo con su feed. Si no puede encontrar el tarro en línea, puedo enviarlo por correo electrónico. No recuerdo de dónde lo saqué, solía estar en xmlpull.org, pero no estoy seguro de dónde está ahora. lo tengo en alguna parte vinculada desde 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); 
    } 
} 

Editar:

Ésta es toda la clase que puebla las alimentaciones a una vista de lista, utilizando un ArrayAdapter, no hay cursor en cualquier base de datos, sin embargo, ya No guardo los feeds localmente:

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

Supongo que esta es la URL: http://www.extreme.indiana.edu/xgws/xsoap/xpp/. ¿Puede explicar más en detalle lo que realmente tenemos que hacer aquí? También puede arrojar algo de luz sobre la otra respuesta que implica 4 pasos (respuesta de DavLink? Gracias –

+0

¿cuál es su caso de uso? ¿Realmente necesita almacenar las noticias en un DB localmente? En mi aplicación, por ejemplo, solo muestro los feeds de Twitter en una lista sin almacenarlos, entonces los pasos 3,4 son opcionales, diría yo, dependiendo de su uso. ¿Necesita las noticias persistentes/disponibles fuera de línea también? –

+0

vea la respuesta editada con una muestra de toda la clase sobre cómo mostrar los feeds una vista de lista. –

3

No es fácil de implementar.

Un archivo RSS es un archivo XML cuya estructura cumple con un estándar (nombres de etiquetas fijas).

En su aplicación, lo que tendría que:

  • Descargar la fuente RSS: utilizar HttpClient, servicios ...
  • Extraer los datos de XML: utilizar un analizador XML, algunos están dentro
  • almacenar los datos: la mejor solución es una base de datos SQLite
  • mostrar los datos: ListView con CursorAdapter apuntando a la base de datos
+0

bien! Entonces hay 4 pasos allí. Puedo llevar a cabo los últimos 3 pasos. Cuéntame sobre el primero. ¿Cómo puedo descargar un feed RSS en Android? –

+0

¡Hecho! :) Tengo los feeds descargados y guardados en un archivo de base de datos. Tengo una pregunta aquí: ¿Qué hace este método Xml.parse (this.getInputStream(), Xml.Encoding.ISO_8859_1, root.getContentHandler()); Puede ver la clase AndroidSaxFeedParser.java. Cheers –

1

DavLink, tiene razón. El análisis de RSS no es trivial.

Es bastante fácil configurar una implementación de un analizador SAX, pero la parte más difícil es poder analizar cualquier alimentación bajo el sol.

Debe atender todos los formatos RSS 1, RSS 2, Atom, etc. Incluso entonces deberá lidiar con alimentaciones mal formateadas.

He tenido problemas similares en el pasado, así que decidí hacer el análisis de mi fuente en un servidor y obtener los contenidos analizados. Esto me permite ejecutar librerías y analizadores más complejos que puedo modificar sin necesidad de actualizar mi aplicación.

Tengo el siguiente servicio ejecutándose en App Engine que permite un análisis mucho más simple de XML/JSON en su extremo. Hay una estructura fija y simple para la respuesta. Puede usar esto para analizar

http://evecal.appspot.com/feedParser

Puede enviar tanto POST y GET solicitudes con los siguientes parámetros.

feedLink: La URL de la respuesta feed RSS: JSON o XML como el formato de respuesta

Ejemplos:

Para una petición POST

rizo --Hojas-urlencode "feedLink = http: //feeds.bbci.co.uk/news/world/rss.xml" --Hojas-urlencode "respuesta = json" http://evecal.appspot.com/feedParser

Por petición GET

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

Mi aplicación para Android "NewsSpeak" usa esto también.

Después de obtener su información, puede usar una vista de lista simple con un arrayadapter que tenga su conjunto de elementos.