Quantcast
Viewing latest article 1
Browse Latest Browse All 2

Integrando Twitter en aplicaciones Android

Con el paso de los años hemos visto cómo Twitter ha crecido como red social y prácticamente toda página web tiene sus propios botones para compartir contenido en Twitter sin tener que redactar nada. Incluso otras redes sociales han dado funcionalidad para que se comparta contenido en Twitter automáticamente desde ellas.

Todo esto es gracias a la API de Twitter. Una API (Application Programming Interface) es el conjunto de funciones y métodos que ofrece una librería software para ser usada desde otro software como una capa de abstracción (sólo sabemos qué hace, no cómo lo hace).

Durante el desarrollo de nuestras aplicaciones puede ser que queramos incluir interacción con Twitter, ya sea de una forma sencilla como poner un tweet hasta mostrar el timeline del usuario. En esta entrada vamos a aprender cómo incluir esta funcionalidad en nuestras aplicaciones usando una librería llamada Twitter4J. Ha sido bastante complejo todo el proceso por el que he pasado para conseguir la funcionalidad, incluso abandonándolo una vez, y ahora quiero compartirlo con vosotros para ahorraros todo el tiempo posible.

¡Comencemos!

Desde hace ya tiempo se viene usando OAuth como protocolo de autorización de las API que podemos encontrar en Twitter y Facebook (entre otros). Este protocolo permite autorizar a una apliación móvil, web o de escritorio la modificación de nuestras cuentas (accediendo a datos como el timeline y los amigos o publicando contenido). Después de realizar varios intentos de autorización de OAuth para usarlo con Twitter usando la librería oauth-signpost, en esta entrada explicaremos la autorización usando la google-api-java-client.

Una vez tengamos una cuenta de Twitter debemos dirigirnos a la página de desarrolladores de Twitter para crear una nueva aplicación. Dicha aplicación no será más que un conjunto de claves que usaremos en nuestra aplicación real para realizar la interacción con Twitter. En los campos del formulario pondremos lo siguiente:

  • Name: el nombre de la aplicación. En nuestro caso será “Going Social vidasConcurrentes”, aunque en un caso de aplicación real lo suyo sería que tuviera el nombre de dicha aplicación (puesto que será el nombre que verá el usuario al tener que autorizar el uso de su cuenta de Twitter, y no debe ser confuso).
  • Description: una breve descripción de la aplicación.
  • WebSite: no hace falta que sea una URL real, pero aquí debe ir la URL del lugar donde los usuarios pueden descargar la aplicación o donde puedan encontrar más información sobre ella. Cuando publiquen un tweet desde nuestra aplicación aparecerá al final “via Going Social Test” para nuestro caso. Y al hacer click irá a la página que pongamos en este campo.
  • Callback: podéis poner aquí cualquier cosa que tenga formato de URL. Más adelante explicaremos qué es y para qué sirve el callback, pero de momento vale con saber que cualquier cosa nos sirve en este campo.

Aceptaremos las reglas de Twitter y registraremos la aplicación. Una vez hecho seremos redirigidos a la página principal de nuestra recientemente creada aplicación. Echando un rápido vistazo vemos que tenemos cinco pestañas. Las que nos interesan son Details y Settings. Lo primero, antes de explicar qué hay en Details, vamos a la pestaña Settings. En ella veremos una sección llamada “Application Type”, donde elegiremos Read and Write puesto que queremos que nuestra aplicación pueda escribir tweets por el usuario. Los demás campos son opcionales.

Ahora sí, visitamos la pestaña Details. En ella tenemos la información necesaria para la autorización OAuth. Tanto Consumer Key como Consumer Secret serán las claves que usaremos en nuestra aplicación para realizar una autorización segura para el usuario. Las tres URL que vemos son las que usaremos para pedir el token del usuario, autorizar la aplicación y acceder a la cuenta. Es el momento de abrir nuestro Eclipse.

Creación del proyecto e importado de las librerías

El siguiente paso para el seguimiento de este tutorial será la creación de un proyecto de Android. Podéis hacerlo a vuestro gusto, aunque en nuestro caso es:

  • Project Name: GoingSocialTwitter
  • Build Target: 2.1-update
  • Application Name: GoingSocialTwitter
  • Package Name: com.vidasconcurrentes.goingsocialtwitter
  • Create Activity: GoingSocialTwitterActivity
  • Min SDK Version: 7

Una vez creado, vamos a añadir una serie de librerías de la google-api-java-client. Lo primero será descargar el comprimido con las librerías de la lista. Cuando realizamos este tutorial la última versión era la 1.5.0-beta. Una vez descargado (son 18MB), lo descomprimimos y nos tiritan las piernas alucinamos con la cantidad de librerías nos preparamos para seleccionar las que vamos a necesitar. Hay dependencias entre unas y otras, de modo que tendremos que agregar todas las que comente. He de decir en mi contra que no sé muy bien por qué hay que añadir tantas y que no sé qué hace cada una de ellas… y que en total van a ser unos 2MB los que vamos a añadir. En mi defensa diré que 2MB son poco si pensamos en la repercusión que puede tener nuestra aplicación dando la posibilidad de ser compartida en Twitter. Las librerías que debemos seleccionar son:

  • google-api-client-1.5.0-beta.jar
  • google-api-client-extensions-android2-1.5.0-beta.jar
  • google-http-client-1.5.0-beta.jar
  • google-oauth-client-1.5.0-beta.jar
  • commons-codec-1.3.jar
  • commons-logging-1.1.1.jar
  • gson-1.6.jar
  • guava-r09.jar
  • httpclient-4.0.3.jar
  • jackson-core-asl-1.6.7.jar

Una vez tengamos todas seleccionadas y copiadas en un directorio (para facilitar su movimiento más tarde), vamos a descargar la librería Twitter4J. Para ello vamos a la página de descargas de Twitter4J. Una vez tengamos todo, es el momento de añadir las librerías a nuestro proyecto. Para facilitar la selección y evitar que se pierda nadie, he preparado un pequeño fichero comprimido con todas las librerías necesarias. Podéis descargarlo aquí (MD5: f815e376210025a5609e60bcb5763681).

Lo siguiente es crear un directorio nuevo en nuestro proyecto llamado lib y mover ahí todas las librerías mencionadas anteriormente (incluida Twitter4J). Una vez hecho, haremos click derecho sobre nuestro proyecto en Eclipse e iremos a Properties. Del menú de la izquierda elegimos Java Build Path. De los botones de la parte derecha elegimos Add JARs… y elegimos todos los ficheros que acabamos de poner dentro del directorio lib. Si hemos hecho todo bien tendremos algo así:

Image may be NSFW.
Clik here to view.

Una vez tengamos esto, es el momento de ponernos con el código.

Creando el código

Comenzamos esta parte con una visión de conjunto de qué vamos a hacer. Los pasos en nuestra aplicación de prueba serán:

  • El usuario pulsa en un botón para autorizar la aplicación.
  • El usuario autoriza la aplicación en la página web de Twitter (pero no abrimos un navegador, todo queda dentro de nuestra aplicación).
  • La aplicación ya está autorizada para la cuenta del usuario (que ha tenido que loguearse para poder autorizarla).
  • El usuario publica un tweet.

Para que no se nos olvide, vamos a comenzar almacenando los datos de nuestra aplicación de Twitter (el Customer Key, Consumer Key…). Para ello creamos, por ejemplo, una nueva clase llamada DatosTwitter, que contendrá lo siguiente:

public class DatosTwitter {
	public static final String CONSUMER_KEY = "XXXXXXXXXXXXXXXXXXXXXX";
	public static final String CONSUMER_SECRET= "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";

	public static final String REQUEST_URL = "https://api.twitter.com/oauth/request_token";
	public static final String ACCESS_URL = "https://api.twitter.com/oauth/access_token";
	public static final String AUTHORIZE_URL = "https://api.twitter.com/oauth/authorize";

	public static final String OAUTH_CALLBACK_URL = "http://XXXXXXXXX";
}

Donde, en CONSUMER_KEY y CONSUMER_SECRET pondremos las que Twitter nos ha dado para nuestra aplicación y en OAUTH_CALLBACK_URL pondremos una URL cualquiera (no tiene ni por qué ser una URL bien formada), más adelante explicaremos para qué la usamos. Ni que decir tiene que no debemos dar estos datos a nadie.

Lo siguiente es crear el layout para la aplicación. Símplemente tendremos que copiar el siguiente código en nuestro fichero main.xml (y no dejar lo anterior):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Esto es el codigo de respuesta" android:id="@+id/codigoRespuesta"></TextView>
    <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/linearLayout1" android:gravity="center">
        <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Autentificar" android:id="@+id/botonAutentificar"></Button>
        <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Borrar credenciales" android:id="@+id/botonBorrarCredenciales"></Button>
    </LinearLayout>
    <EditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:id="@+id/editTextTweet">
        <requestFocus></requestFocus>
    </EditText>
    <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Enviar tweet" android:layout_gravity="center" android:id="@+id/botonMandarTweet"></Button>
</LinearLayout>

Recordemos que es una mala práctica usar cadenas de texto en los text de cada componente. Si esto fuera una aplicación de verdad, deberíamos usar el fichero strings.xml y hacer referencias a él.

Con esto tendremos lo siguiente, si ejecutamos:

Image may be NSFW.
Clik here to view.

Lo siguiente que haremos será modificar el código de la Activity creada automáticamente. Para ello abrimos la clase GoingSocialTwitterActivity y cambiamos el método onCreate() de la siguiente forma:

// añadimos la siguiente linea como atributo de la clase
private SharedPreferences sharedPreferences;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);

    // obetenemos los elementos de la interfaz
    TextView codigoRespuesta = (TextView) findViewById(R.id.codigoRespuesta);
    Button botonAutentificar = (Button) findViewById(R.id.botonAutentificar);
    Button botonBorrarCredenciales = (Button) findViewById(R.id.botonBorrarCredenciales);
    Button botonMandarTweet = (Button) findViewById(R.id.botonMandarTweet);
    EditText editTextTweet = (EditText) findViewById(R.id.editTextTweet);
}

De esta forma ya tenemos accesibles los cinco elementos que hemos creado en nuestra interfaz. Además hemos creado un atributo de la clase SharedPreferences. Cuando queremos mantener pocos datos entre una ejecución de la aplicación y otra, Android nos ofrece las SharedPreferences. En nuestro caso vamos a usarlas para almacenar los tokens del usuario una vez esté logueado y haya autorizado nuestra aplicación, para que no tenga que hacerlo de nuevo cada vez que quiera mandar un tweet. La forma de cargar dichas preferencias es por medio del PreferenceManager.

Lo siguiente que vamos a hacer es añadir funcionalidad a los botones, de modo que cuando se pulsen se ejecuten cosas. Para ello vamos a añadir el código que viene a continuación al final del anterior, pero aún dentro de onCreate():

botonAutentificar.setOnClickListener(new View.OnClickListener() {
	@Override
	public void onClick(View v) {
		// ejecutaremos lo necesario para autorizar la aplicación
	}
});

botonBorrarCredenciales.setOnClickListener(new View.OnClickListener() {
	@Override
	public void onClick(View v) {
		// ejecutaremos lo necesario para borrar las SharedPreferences
	}
});

botonMandarTweet.setOnClickListener(new View.OnClickListener() {
	@Override
	public void onClick(View v) {
		// ejecutaremos lo necesario para publicar un tweet
	}
});

No hay mucho que explicar aquí. Sólo creamos diferentes listeners anónimos para los botones, que implementarán el método onClick(). Vamos a comenzar por el botón de autorización. Su código final será:

botonAutentificar.setOnClickListener(new View.OnClickListener() {
	@Override
	public void onClick(View v) {
		startActivity(new Intent().setClass(v.getContext(), TokenAccesoOAuth.class));
	}
});

Esto significa que cuando pulsemos se ejecutará una nueva actividad de tipo TokenAccesoOAuth. Y sí, lo habéis adivinado: el siguiente paso es crear esta actividad. Su código inicial será:

public class TokenAccesoOAuth extends Activity {

	private SharedPreferences sharedPreferences;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
	}
	@Override
	protected void onResume() {
		super.onResume();
	}
}

Aquí también usaremos las SharedPreferences, así que también las añadimos como atributo y las obtenemos del sistema. Todo el código que se ejecute aquí irá en el método onResume(), que será el encargado de realizar la autorización. En ella vamos a crear una vista web que viene incluida como las View por defecto de Android: el WebView. No olvidemos añadir esta actividad al AndroidManifest.xml, o si no la aplicación se cerrará al intentar ejecutar una actividad que no conoce. Añadimos lo siguiente antes de :

<activity android:name=".TokenAccesoOAuth"></activity>

Añadimos el siguiente código al final de onResume():

WebView webView = new WebView(this);
webView.getSettings().setJavaScriptEnabled(true);
webView.setVisibility(View.VISIBLE);
setContentView(webView);

Creamos el WebView, activamos Javascript para que funcione el formulario de login de Twitter, lo hacemos visible y se lo ponemos a la actividad como vista a mostrar. Lo siguiente será hacer que esta vista muestre algo.

Aquí es donde el norte se pierde un poco y se ponen las cosas complicadas. Los pasos son así y tenemos que hacer un acto de Fe, pues el cauce de OAuth es complejo. El siguiente código lo colocamos al final del último código mencionado arriba:

try {
	final OAuthHmacSigner signer = new OAuthHmacSigner();
	signer.clientSharedSecret = DatosTwitter.CONSUMER_SECRET;

	OAuthGetTemporaryToken tempToken = new OAuthGetTemporaryToken(DatosTwitter.REQUEST_URL);
	tempToken.transport = new ApacheHttpTransport();
	tempToken.signer = signer;
	tempToken.consumerKey = DatosTwitter.CONSUMER_KEY;
	tempToken.callback = DatosTwitter.OAUTH_CALLBACK_URL;

	OAuthCredentialsResponse tempCredentials = tempToken.execute();
	signer.tokenSharedSecret = tempCredentials.tokenSecret;

	OAuthAuthorizeTemporaryTokenUrl authorizeUrl = new OAuthAuthorizeTemporaryTokenUrl(DatosTwitter.AUTHORIZE_URL);
	authorizeUrl.temporaryToken = tempCredentials.token;
	String authorizationUrl = authorizeUrl.build();
} catch(Exception ex) {
	Log.e("GoingSocialTwitter", "Error: " + ex);
}

Lo primero que hacemos es crear un objeto para firmar las operaciones que vamos a hacer con nuestra clave (el Consumer Secret). Lo siguiente es pedir a Twitter que nos de un token que vamos a usar junto con nuestro Consumer Key y el Callback, y que finalmente usaremos para autorizar la aplicación. Una vez se ejecuten estos pasos tendremos una URL para la autorización de la aplicación. El siguiente paso será, entonces, ir a esa URL.

Para conseguirlo, vamos a crear el cliente del WebView que creamos arriba. Añadimos el siguiente código antes del catch() del código superior:

webView.setWebViewClient(new WebViewClient() {
	@Override
	public void onPageStarted(WebView view, String url, Bitmap bitmap) {
		Log.i("GoingSocial", "onPageStarted: " + url);
	}
	@Override
	public void onPageFinished(WebView view, String url) {
		Log.i("GoingSocial", "onPageFinished: " + url);
	}
});

Este será el esqueleto de nuestra actividad web. Ahora es cuando vamos a ver para qué nos sirve el Callback URL. Cuando se ejecute este cliente web entraremos por el método onPageStarted(), que sólo tiene una línea usando el Log para que veamos mientras desarrollamos por dónde vamos. Después se cargará la web que diremos más adelante (que es la que tenemos almacenada en authorizeUrl). Una vez se haya completado el proceso de autorizado, Twitter nos redireccionará al Callback URL. Eso significa que va a intentar abrir una nueva página web, pero lo que vamos a hacer nosotros es interceptar dicha llamada, hacer unas operaciones y retornar a nuestra actividad principal. Comenzamos con el esqueleto de dicho método:

@Override
public void onPageFinished(WebView view, String url) {
	// solo si estamos interceptando la URL de callback
	if(url.startsWith(DatosTwitter.OAUTH_CALLBACK_URL)) {
		try {
			if(url.indexOf("oauth_token=") != -1) {

			} else if(url.indexOf("error=") != -1) {

			}
		} catch(Exception ex) {
			Log.e("GoingSocial", "Excepcion en onPageFinished: " + ex.getMessage());
		}
	}
	Log.i("GoingSocial", "onPageFinished: " + url);
}

Aquí lo que hacemos es, sólo si vamos a la URL de Callback, interceptar. Esta URL no sólo tendrá el callback, sino más información como los tokens de la autorización. Por tanto, existirán dos partes en el código: si existe el token de autorización (recordemos que el método indexOf() de los String devuelve -1 si no se encuentra la cadena que le pasamos como parámetro), y si existe algún error. Comenzamos con el primer caso, añadiendo el siguiente código dentro del if correspondiente:

String requestToken = extractParamFromUrl(url, "oauth_token");
String verificador = extractParamFromUrl(url, "oauth_verifier");

signer.clientSharedSecret = DatosTwitter.CONSUMER_SECRET;

OAuthGetAccessToken accessToken = new OAuthGetAccessToken(DatosTwitter.ACCESS_URL);
accessToken.transport = new ApacheHttpTransport();
accessToken.temporaryToken = requestToken;
accessToken.signer = signer;
accessToken.consumerKey = DatosTwitter.CONSUMER_KEY;
accessToken.verifier = verificador;

OAuthCredentialsResponse credentials = accessToken.execute();
signer.tokenSharedSecret = credentials.tokenSecret;

Igualmente, esta parte es así y debemos hacer un acto de Fe. Lo primero es extraer de la URL el token y el verifier. Para ello nos vamos a apoyar en el siguiente método (que debe ser añadido dentro del WebViewClient anónimo):

private String extractParamFromUrl(String url,String paramName) {
	String queryString = url.substring(url.indexOf("?", 0) + 1, url.length());
	QueryStringParser queryStringParser = new QueryStringParser(queryString);
	return queryStringParser.getQueryParamValue(paramName);
}

Y la clase QueryStringParser, que debemos crear en nuestro proyecto y que contiene el siguiente código:

package com.vidasconcurrentes.goingsocialtwitter;

import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

public class QueryStringParser {
    private final String queryString;

    private int paramBegin;
    private int paramEnd = -1;
    private int paramNameEnd;
    private String paramName;
    private String paramValue;

    private Map<String, String> paramPairs = new HashMap<String, String>();

    public QueryStringParser(String queryString) {
        this.queryString = queryString;
        while(next()) {
        	paramPairs.put(getName(),getValue());
        }
    }

    public String getQueryParamValue(String name) {
    	return paramPairs.get(name);
    }

    private boolean next() {
        int len = queryString.length();
        while (true) {
            if (paramEnd == len) {
                return false;
            }
            paramBegin = paramEnd == -1 ? 0 : paramEnd+1;
            int idx = queryString.indexOf('&', paramBegin);
            paramEnd = idx == -1 ? len : idx;
            if (paramEnd > paramBegin) {
                idx = queryString.indexOf('=', paramBegin);
                paramNameEnd = idx == -1 || idx > paramEnd ? paramEnd : idx;
                paramName = null;
                paramValue = null;
                return true;
            }
        }
    }

    private String getName() {
        if (paramName == null) {
            paramName = queryString.substring(paramBegin, paramNameEnd);
        }
        return paramName;
    }

    private String getValue() {
        if (paramValue == null) {
            if (paramNameEnd == paramEnd) {
                return null;
            }
            try {
                paramValue = URLDecoder.decode(queryString.substring(paramNameEnd + 1, paramEnd));
            } catch (Exception ex) {
                throw new Error(ex);
            }
        }
        return paramValue;
    }
}

Esta clase no hace falta que se comprenda y podéis símplemente copiarla y no hacerla mucho caso. Básicamente ofrece funcionalidad para parsear una URL dada en un String y poder acceder a los valores de cada uno de las claves de dicha URL. En este punto quisiera agradecer al autor de este blog su código fuente, del cual he sacado esta clase.

Con esta parte hecha, falta añadir dos cosas más al código del caso en que encontremos “oauth_token” en la URL. Añadimos el siguiente código antes del else if:

String[] credenciales = { credentials.token, credentials.tokenSecret };
new AlmacenCredenciales(sharedPreferences).escribe(credenciales);

view.setVisibility(View.INVISIBLE);
TokenAccesoOAuth.this.finish();

Lo que hacemos es guardarnos en las SharedPreferences las credenciales, para posteriormente ocultar el WebView y lanzar la actividad principal de nuevo. Aún no hemos creado la clase AlmacenCredenciales, pero lo haremos en breves. Primero acabamos con la rama del else if, que tendrá la siguiente forma:

} else if(url.indexOf("error=") != -1) {
	view.setVisibility(View.INVISIBLE);
	new AlmacenCredenciales(sharedPreferences).borra();
	TokenAccesoOAuth.this.finish();
}

Con esto hacemos algo parecido a lo anterior. Solo que en lugar de guardarnos las credenciales, lo que hacemos es borrar lo que tuviéramos almacenado y posteriormente relanzar la actividad principal.

Falta una cosa más en esta clase, y es que aún no hemos dicho qué URL tiene que cargar el WebView (de forma que así tal cual está no funcionaría porque no iría a ninguna parte). Añadimos la siguiente línea antes del último catch() de la clase:

webView.loadUrl(authorizationUrl);

Ahora sí, esta clase la damos por finalizada.

Es el momento de crear la clase AlmacenCredenciales, que hasta ahora nos habrá estado Eclipse chillando con un error. Creamos la clase y pegamos el siguiente código:

package com.vidasconcurrentes.goingsocialtwitter;

import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;

public class AlmacenCredenciales {

	private SharedPreferences prefs;

	public AlmacenCredenciales(SharedPreferences prefs) {
		this.prefs = prefs;
	}

	public String[] lee() {
		String[] tokens = new String[2];
		tokens[0] = prefs.getString("token", "");
		tokens[1] = prefs.getString("token_secret", "");
		return tokens;
	}

	public void escribe(String[] tokens) {
		Editor editor = prefs.edit();
		editor.putString("token", tokens[0]);
		editor.putString("token_secret", tokens[1]);
		editor.commit();
	}

	public void borra() {
		Editor editor = prefs.edit();
		editor.remove("token");
		editor.remove("token_secret");
		editor.commit();
	}
}

Es bastante descriptivo el propio código. El método lee() recoge los tokens de las SharedPreferences y las devuelve, el método escribe() coge un Editor de dichas preferencias y escribe ambos tokens, y el método borra() quita ambos strings de las preferencias.

Con esto ya hemos añadido la funcionalidad al botón de autorización, que era de largo el más complejo y extenso, y con ello acabamos la parte del cauce de OAuth (menos mal). Lo siguiente será añadir funcionalidad a los otros dos botones con los que contamos en la interfaz. Comenzamos añadiendo la funcionalidad al botón de borrado de las credenciales en la clase GoingSocialTwitterActivity. Para ello modificamos el código para que quede así:

botonBorrarCredenciales.setOnClickListener(new View.OnClickListener() {
	@Override
	public void onClick(View v) {
		new AlmacenCredenciales(sharedPreferences).borra();
	}
});

Simple. Por último vamos a crear el código que permite publicar un tweet. Para ello vamos a ayudarnos de la librería Twitter4J que descargamos e incluimos previamente, y que es la que de verdad usa la API de Twitter (¡pues hasta ahora no hemos hecho más que autorizar el uso de la aplicación en la cuenta del usuario!). Comenzamos creando estos dos métodos en la propia actividad principal:

private Twitter loginTwitter() {
	String[] tokens = new AlmacenCredenciales(sharedPreferences).lee();
	AccessToken a = new AccessToken(tokens[0], tokens[1]);

	Twitter twitter = new TwitterFactory().getInstance();
	twitter.setOAuthConsumer(DatosTwitter.CONSUMER_KEY, DatosTwitter.CONSUMER_SECRET);
	twitter.setOAuthAccessToken(a);

	return twitter;
}

private void mandaTweet(SharedPreferences sharedPrefs, String message) throws Exception {
	Twitter twitter = loginTwitter();
	twitter.updateStatus(message);
}

Con el primero de ellos, loginTwitter(), lo que hacemos es obtener las credenciales que habíamos guardado (o nada si no hemos autorizado aún la aplicación), y obtener un objeto Twitter que nos ofrece Twitter4J que contendrá las llamadas a la API. Con el segundo de los métodos nos logueamos y publicamos el tweet.

Sólo nos resta añadir las llamadas a estos métodos. Para ello vamos a añadir la funcionalidad necesaria al botón de envío de tweets, cuyo código será:

botonMandarTweet.setOnClickListener(new View.OnClickListener() {
	@Override
	public void onClick(View v) {
		try {
			mandaTweet(sharedPreferences, editTextTweet.getText().toString());
			codigoRespuesta.setText(editTextTweet.getText().toString());
		} catch(Exception ex) {
			codigoRespuesta.setText("Error: " + ex.getMessage());
		}
	}
});

En caso de haberse producido un error al mandar el tweet (como por ejemplo que el login no haya sido correcto por falta de red o porque las SharedPreferences no contenían nada), la excepción lanzada se recogería aquí y mostraríamos el mensaje de la excepción en la interfaz.

Tenemos que añadir al AndroidManifest.xml que queremos usar el permiso para acceder a Internet. Podemos hacerlo con la GUI o añadiendo esto después de <uses-sdk>:

<uses-permission android:name="android.permission.INTERNET"></uses-permission>

Con esto habríamos acabado el código, ¡sólo nos resta probar que lo que hemos hecho funciona!

Podemos, por ejemplo, una vez ejecutada la aplicación, ver qué pasa si pulsamos en Enviar Tweet después de escribir un tweet:

Image may be NSFW.
Clik here to view.

Ahora pulsamos el botón Autentificar, nos logueamos, y veremos esto:

Image may be NSFW.
Clik here to view.

Por último, la aplicación volverá a la actividad de inicio, en la que esta vez sí podemos pulsar en Enviar tweet y veremos algo así:

Image may be NSFW.
Clik here to view.

Podemos comprobar que efectivamente hemos publicado dicho tweet yendo a nuestro perfil de Twitter:

Image may be NSFW.
Clik here to view.

Os invito a probar a cerrar la aplicación, volver a abrirla y escribir un tweet sin pulsar en Autentificar para comprobar que se guardan los datos de los token entre ejecuciones.

¡Hasta aquí llega la entrada de hoy!

Durante la entrada de hoy hemos visto cómo publicar tweets en la cuenta del usuario de nuestra aplicación usando el protocolo OAuth y la librería Twitter4J. Hemos visto también cómo hacer para mantener la información de la autorización del usuario en la aplicación, de modo que el usuario no tenga que volver a autorizar la aplicación cada vez que la abra.

Es importante ver que esta opción puede tener mucho calado en nuestras aplicaciones. Sólo doy un ejemplo, muy sencillo. Digamos que nuestra aplicación (una real) tiene un menú. Podríamos querer ofrecer un botón para compartir en Twitter, el cual tenga ya predefinido un tweet con el link al Market o a nuestra web, y una mención a nuestra cuenta de Twitter. Incluso podríamos querer ofrecer esta funcionalidad en diferentes partes de nuestra aplicación con diferentes tweets pre-generados.

Espero que os haya sido de utilidad, pues a mi me costó pegarme mucho con ello hasta hacerlo funcionar (incluso probé otros dos métodos más).

¡Un saludo para todos los lectores!


Viewing latest article 1
Browse Latest Browse All 2