En este tutorial vamos a explicar como crear una aplicación que nos permite leer los tweets de cualquier usuario y guardarlos en formatos xml y json.
Para ello la aplicación utilizará la API que twiter facilita, permitirá al usuario introducir el nombre de un usuario y la aplicación descargará los últimos tweets del usuario introducido y los guardará en formato xml y json.
Espero que le guste y le sea fácil de entender. No dude en comentar.
¡ Saludos !
Enlaces de interés:
Código Fuente
Puede descargar si lo desea el código fuente de este proyecto.
Pasos a seguir:
1. Creamos la interfaz de la actividad principal en donde se mostrará los tweets.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <EditText android:id="@+id/edtxtBuscar" android:layout_width="228dp" android:layout_height="wrap_content" android:ems="10" > <requestFocus /> </EditText> <Button android:id="@+id/btnAceptar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="@string/aceptar" /> </LinearLayout> <TextView android:id="@+id/txtInformacion" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceSmall" /> <ScrollView android:id="@+id/scrollView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="22dp" > <TextView android:id="@+id/txtTweets" android:layout_width="match_parent" android:layout_height="match_parent" android:textAppearance="?android:attr/textAppearanceMedium" /> </ScrollView> </LinearLayout> </RelativeLayout>
2. Declaramos los campos que vayamos a utilizar en la clase de la actividad principal.
/** * Muestra y almacena los tweets del nombre que se indique en ficheros * xml y json * * @author José Miguel Acosta Martín * */ public class TwitterActivity extends Activity { //////////////////////////////////////////////////////////////////////////////////////////// // CAMPOS // //////////////////////////////////////////////////////////////////////////////////////////// // Campos gráficos private EditText edtxtNombre; // Campo gráfico donde el usuario introduce el nombre a buscar private Button btnAceptar; // Campo gráfico donde la aplicación busca private TextView txtInformacion; // Campo gráfico que muestra información adicional private TextView txtTweets; // Campo gráfico que muestra los tweets //////////////////////////////////////////////////////////////////////////////////////////// // FIN CAMPOS // ////////////////////////////////////////////////////////////////////////////////////////////
3. Iniciamos los campos y programamos los eventos en el método onCreate().
/** * Al iniciar la aplicación ... */ @SuppressLint("NewApi") @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_twitter); // INICIALIZACIÓN DE CAMPOS ////////////////////////////////////////////////////////////// // Inicialización de campos gráficos edtxtNombre = (EditText) findViewById(R.id.edtxtBuscar); btnAceptar = (Button) findViewById(R.id.btnAceptar); txtInformacion = (TextView) findViewById(R.id.txtInformacion); txtTweets = (TextView) findViewById(R.id.txtTweets); // FIN INICIALICACIÓN DE CAMPOS ////////////////////////////////////////////////////////// // Permisos para acceder a internet StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); //////////////////////////////////////////////////////////////////////////////////////////// // EVENTOS // //////////////////////////////////////////////////////////////////////////////////////////// btnAceptar.setOnClickListener(new OnClickListener() { /** * Muestra los tweets y los escribe en ficheros xml y json */ public void onClick(View v) { // Muestra los tweets por pantalla y los escribe en ficheros xml y json mostrarTweets(edtxtNombre.getText().toString()); } }); //////////////////////////////////////////////////////////////////////////////////////////// // FIN EVENYOS // //////////////////////////////////////////////////////////////////////////////////////////// }
4. Creamos el método que se encargará de leer los tweets.
/** * Lee los tweets * * @param nombre Nombre de la persona que se quiere leer los tweets * @return Los tweets */ public String leerTwitterFeed(String nombre) { // CAMPOS ////////////////////////////////////////////////////////////////////////////////////////////////////// StringBuilder builder; // Almacena la cadena de texto HttpClient client; HttpGet httpGet; // Almacena la url desde donde se obtiene los tweets HttpResponse response; StatusLine statusLine; // Almacena el estado de la conexión int statusCode; // Almacena el codigo del estado de la conexión HttpEntity entity; InputStream content; BufferedReader reader; String line; // Almacena la linea leida // FIN CAMPOS ////////////////////////////////////////////////////////////////////////////////////////////////// // EJECUCIÓN ///////////////////////////////////////////////////////////////////////////////////////////////////// // Inicialización de campos builder = new StringBuilder(); client = new DefaultHttpClient(); httpGet = new HttpGet("https://api.twitter.com/1/statuses/user_timeline.json?screen_name=" + nombre); // Url desde donde se obtienen los tweets try { // Inicialización de campos response = client.execute(httpGet); statusLine = response.getStatusLine(); // Obtiene el estado de la línea statusCode = statusLine.getStatusCode(); // Obtiene el codigo que determina el estado de la línea // Si es correcto if (statusCode == 200) { entity = response.getEntity(); content = entity.getContent(); reader = new BufferedReader(new InputStreamReader(content)); // Lee todo el fichero while ((line = reader.readLine()) != null) { // Añade la linea leida builder.append(line); } // Limpia el campo de información txtInformacion.setText(""); } else { // Indica al usuario que se ha producido un error al descargar el fichero txtInformacion.setText("Fallo al descargar el fichero"); } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return builder.toString(); // FIN EJECUCIÓN //////////////////////////////////////////////////////////////////////////////////////////////////////////// }
5. Y también tendremos que programar el método que se encargará de guardar los tweets en un fichero xml.
/** * Guarda los tweets en un fichero xml * * @param tweet Texto del tweet * @param fecha Fecha del tweet * @param nombreFichero Nombre del fichero */ public void guardarXml(String tweet, String fecha, String nombreFichero){ // CAMPOS ///////////////////////////////////////////////////////////////////////////////// XmlSerializer ser; OutputStreamWriter fout; // Fichero donde se escribre // FIN CAMPOS //////////////////////////////////////////////////////////////////////////// // EJECUCIÓN /////////////////////////////////////////////////////////////////////////////// try { //Crea el serializer ser = Xml.newSerializer(); //Crea un fichero en memoria interna fout = new OutputStreamWriter(openFileOutput(nombreFichero + ".xml", Context.MODE_APPEND)); //Asigna el resultado del serializer al fichero ser.setOutput(fout); //Construye el XML ser.startTag("", "tweet"); ser.startTag("", "texto"); ser.text(tweet); ser.endTag("", "texto"); ser.startTag("", "fecha"); ser.text(fecha); ser.endTag("", "fecha"); ser.endTag("", "tweet"); ser.endDocument(); // Cierra el fichero fout.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalStateException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } // FIN EJECUCIÓN //////////////////////////////////////////////////////////////////////////////////////// }
6. Creamos otro método para guardar los tweets en formato Json.
/** * Guarda los tweets en un fichero json * * @param tweet Texto de tweet * @param fecha Fecha del tweet * @param nombreFichero Nombre del fichero donde se quiere guardar * @param tamano Tamaño del array de tweets * @param numeroTweet El número del tweet que se quiere guardar */ public void guardarJson(String tweet, String fecha, String nombreFichero, int tamano, int numeroTweet){ // CAMPOS ///////////////////////////////////////////////////////////////////////////////////////////////// OutputStreamWriter fout; // Fichero donde se escribre // FIN CAMPOS ///////////////////////////////////////////////////////////////////////////////////////////// // EJECUCIÓN ////////////////////////////////////////////////////////////////////////////////////////////// try { //Crea un fichero en memoria interna fout = new OutputStreamWriter(openFileOutput(nombreFichero + ".json", Context.MODE_APPEND)); // Controla si es la primera entrada if (numeroTweet == 0){ // Si es la primera entrada ... // Añade fout.append("["); } // Controla si no es la última entrada if (numeroTweet < tamano - 1){ // Si no es la última entrada ... // Añade fout.append("{ tweet:" + "\"" + tweet + "\"" + ", fecha:" + "\"" + fecha + "\"" + "},"); } else { // Si es la última entrada ... // Añade fout.append("{ tweet:" + "\"" + tweet + "\"" + ", fecha:" + "\"" + fecha + "\"" + "}]"); } // Cierra el fichero fout.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } // FIN EJECUCIÓN //////////////////////////////////////////////////////////////////////////////////////////// }
9. Le mostramos los datos al usuario además de utilizar los métodos anteriores para guardar los tweets en diferentes ficheros.
/** * Muestra y escribre los tweets en ficheros xml y json * * @param nombre Nombre de quien se quiere leer los tweets */ public void mostrarTweets(String nombre){ // CAMPOS /////////////////////////////////////////////////////////////////////////////// JSONArray jsonArray; // Almacena los tweets JSONObject jsonObject; // Almacena el tweet String tweet; // Almacena el tweet String fecha; // Almacena la fecha del tweet // FIN CAMPOS ////////////////////////////////////////////////////////////////////////// // EJECUCIÓN /////////////////////////////////////////////////////////////////////////// try { // Almacena los tweets jsonArray = new JSONArray(leerTwitterFeed(nombre)); // Se informa sobre el número de tweets txtInformacion.setText("Número de entradas " + jsonArray.length()); // Recorre el array de tweets for (int i = 0; i < jsonArray.length(); i++) { // Obtiene el objeto del array jsonObject = jsonArray.getJSONObject(i); // Obtiene el tweet tweet = jsonObject.getString("text"); // Obtiene la fecha fecha = jsonObject.getString("created_at"); // Muestra los tweets txtTweets.append(jsonObject.getString("text") + "\n\n"); // Guarda los tweets en un fichero xml guardarXml(tweet, fecha, nombre); // Guarda los tweets en un fichero json guardarJson(tweet, fecha, nombre, jsonArray.length(), i); } } catch (Exception e) { e.printStackTrace(); } // FIN EJECUCIÓN /////////////////////////////////////////////////////////////////////// }
10. Finalmente le añadimos los permisos necesarios al manifiesto para que Android nos permita usar la conexión a Internet.
<uses-permission android:name="android.permission.INTERNET"/>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.ACDAT.ejercicio7" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" /> <uses-permission android:name="android.permission.INTERNET"/> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".TwitterActivity" android:label="@string/title_activity_twitter" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
FIN
No funciona, no me carga los tweets... me sale unexpected value from nativegetenabletags: 0
ResponderEliminarHola, he estado mirando tu error y parece ser que se trata de un error del emulador cuando se utiliza la API 17, intenta probar a emular la aplicación con una API inferior a ver si se soluciona tu problema. Saludos!.
Eliminarlo puse a que se ejecutara en mi android 2.3.4 y me sale lo siguiente: W/System.err(2013): java.net.UnknownHostException: api.twitter.com
Eliminarolvidalo!! ya esta! muchisimas gracias! lo que paso fue que en el manifest no puse el uso de internet
EliminarMuchas gracias por tu respuesta, he actualizado la entrada para que no haya más confusiones con los permisos de Internet. Saludos!
EliminarChiqui, te has confundido de link. La página a la que nos lleva es el link de descarga de "Lector de noticias RSS". ¿Podrías colgarlo hoy?. Muchas gracias y un saludo.
ResponderEliminar