×
Namespaces

Variants
Actions
Revision as of 03:41, 27 June 2013 by hamishwillee (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Usando Twitter API ME para autorización basada en PIN desde Java ME

From Nokia Developer Wiki
Jump to: navigation, search

Este artículo explica cómo usar Twitter API ME para obtener tokens de acceso a Twitter a través de autorización basada en PIN desde una aplicación de Java ME.

Article Metadata
Code ExampleTested with
Devices(s): Nokia Asha 303, Nokia Asha 310
CompatibilityArticle
Keywords: Twitter, RecordStore, PIN-based authorization
Translated:
By cadlg
Last edited: hamishwillee (27 Jun 2013)

Contents

Introducción

Twitter usa OAuth para proveer acceso autorizado a su API, el cual le permite a los proveedores de servicios dar acceso a los datos de sus usuarios sin requerir que ellos compartan sus contraseñas con aplicaciones de terceros.

Sin embargo, el método más común de autorización de acceso require cierto tipo de integración con un browser, ya que como parte del flujo de OAuth, la aplicación necesita redireccionar al usuario a una página de Twitter, y luego redireccionarlo de regreso a una página bajo el control de la aplicación, lo cual al momento de escribir este artículo, no es posible en Java ME.

Para aplicaciones que no pueden integrar un browser para completar el flujo de OAuth, Twitter ofrece el método de autorización basada en PIN (PIN-based authorization), que es el que se demuestra en este artículo.

Cómo funciona la autorización basada en PIN ?

En resumen, la aplicación inicia el flujo de OAuth y en cierto punto abre una instancia del web browser con una página de Twitter donde el usuario tiene que ingresar al servicio para autorizar el acceso a la aplicación. Una vez el usuario ha autorizado la aplicación, un número (llamado PIN) es desplegado en el browser, el cual el usuario necesita ingresar en la pantalla de autorización de la aplicación, la cual usa ese PIN para completar el proceso de autorización.

Prerequisitos

Para poder probar el código de este artículo, usted necesita haber creado una aplicación en Twitter. Si necesita crear una nueva aplicación en Twitter, por favor diríjase a https://dev.twitter.com/apps. (Los detalles sobre cómo crear una nueva aplicación en Twitter están fuera del alcance de este artículo).

También necesita tener los binarios de Twitter API ME en su máquina de desarrollo. Si necesita descargar Twitter API ME, por favor vaya a la página de descargas de Twitter API ME. También podría usar los binarios de la librería que se incluyen en el proyecto descargable de este artículo.

Note.pngNote: La licencia de Twitter API ME permite desarrollar aplicaciones propietarias si solo los binarios son utilizados (El código fuente de la API sí se ha liberado con una licencia diferente. Vea la página de licenciamiento (documento en Inglés)).

Desarrollando la aplicación de ejemplo

Note.pngNote: En el artículo se utilizará texto en español para los comentarios en el código, pero en la aplicación descargable que lo acompaña, todos los textos se encuentran en Inglés.

Para demostrar el proceso de autorización, crearemos un aplicación LWUIT muy sencilla, la cual luego de completar el proceso de autorización almacenará el token de acceso en un RecordStore, para poder usarlo en ejecuciones futuras, y realizará una búsqueda simple en Twitter, cuyos resultados se escribirán a la consola.

Note.pngNote: En la version 1 de la API de Twitter las búsquedas podían ser realizadas anónimamente, pero en la version 1.1 todas las llamadas a la API requieren autenticación, incluyendo las búsquedas.


Tome nota que la aplicación de ejemplo no muestra ningún indicador de progreso, y para simplificar el ejemplo, tampoco realiza la búsqueda de tweets en una thread separado.

La mayor parte del código de la aplicación se incluirá y explicará aquí, pero para asegurarse que no le hace falta nada, por favor descargue el archivo zip que acompaña al artículo, el cual incluye el proyecto de prueba (en formato de Eclipse/Nokia IDE).

Como primer paso por favor cree un nuevo proyecto MIDlet, agregue las librerías de LWUIT y cree un nuevo MIDlet en blanco.

Tip.pngTip: Si necesita ayuda para completar este paso, por favor refiérase a la sección “Getting started” de la biblioteca de desarrolladores de LWUIT (documento en Inglés).

Luego, necesitamos agregar las librerías de Twitter API ME. Por favor agregue los siguientes binarios (los cuales deben estar incluídos en su descarga de Twitter API ME) en la misma forma que agregó las librerías de LWUIT:

  • twitter_api_me
  • json-me
  • kxml2-min


El nombre de los archivos jar puede variar dependiendo de las versiones usadas. En este caso hemos agregado los siguientes jars a la aplicación de ejemplo:

  • twitter_api_me-1.8.jar
  • json-me.jar
  • kxml2-min-2.3.0.jar


Después, necesitamos agregar los imports necesarios:

// Para el manejo del almacenamiento persistente
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;
 
// Para la interfaz de usuario
import com.sun.lwuit.Form;
import com.sun.lwuit.Label;
import com.sun.lwuit.Button;
import com.sun.lwuit.Display;
import com.sun.lwuit.TextArea;
import com.sun.lwuit.TextField;
import com.sun.lwuit.events.ActionEvent;
import com.sun.lwuit.events.ActionListener;
import com.sun.lwuit.layouts.BoxLayout;
import com.sun.lwuit.Command;
 
// Para el acceso a Twitter
import impl.javame.com.twitterapime.xauth.ui.MIDletOAuthDialogWrapper;
import com.twitterapime.rest.Credential;
import com.twitterapime.rest.UserAccountManager;
import com.twitterapime.search.Query;
import com.twitterapime.search.SearchDevice;
import com.twitterapime.search.Tweet;
import com.twitterapime.xauth.Token;
import com.twitterapime.xauth.ui.OAuthDialogListener;

A continuación, definiremos algunas variables miembro necesarias y construiremos la interfaz de usuario en el método startApp() del MIDlet:

	private Label label;
private TextArea textArea = null;
private Button button;
 
private Token accessToken;
private MIDletOAuthDialogWrapper pageWrapper;
 
private boolean PINrequested = false;
private String strToken;
private String strSearchCriteria;
private RecordStore recordStore;
 
...
 
Display.init(this);
Form form = new Form("Twitter Test");
form.setLayout(new BoxLayout(BoxLayout.Y_AXIS));
 
label = new Label ("Enter search term");
form.addComponent(label);
 
// El textArea será usado para ingresar el término de búsqueda
// y para ingresar el PIN (cuando se esté autorizando el acceso a Twitter)
textArea = TextField.create();
form.addComponent(textArea);
 
// El botón será usado para ejecutar la búsqueda
// y para enviar el PIN a Twitter, para completar
// el proceso de autorización
button = new Button("Search");
form.addComponent(button);
form.show();
 
//Agregamos el comando para salir
Command exitCommand = new Command("Exit") {
public void actionPerformed(ActionEvent e) {
notifyDestroyed();
}
};
form.addCommand(exitCommand);
form.setBackCommand(exitCommand);

Ahora, agregamos métodos para almacenar y recuperar el token de acceso al/del record store:

	protected void storeToken(String token){
try {
recordStore = RecordStore.openRecordStore("tk", true);
int recId; // retornado por addRecord pero no usado
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream outputStream = new DataOutputStream(baos);
try {
// Insertamos el token en un byte array.
outputStream.writeUTF(token);
}
catch (IOException ioe) {
System.out.println(ioe);
ioe.printStackTrace();
}
// Extraemos el byte array
byte[] b = baos.toByteArray();
// Si el record store está vacío, creamos un nuevo registro
if (recordStore.getNumRecords()==0)
{
try {
recId = recordStore.addRecord(b, 0, b.length);
}
catch (RecordStoreException rse) {
System.out.println(rse);
rse.printStackTrace();
}
}
// De lo contrario, actualizamos el registro existente
else
{
try {
recordStore.setRecord(1,b,0,b.length);
}
catch (RecordStoreException rse) {
System.out.println(rse);
rse.printStackTrace();
}
}
try{
recordStore.closeRecordStore();
}
catch (RecordStoreException rse){
System.out.println(rse);
rse.printStackTrace();
}
}
catch (RecordStoreException rse) {
System.out.println(rse);
rse.printStackTrace();
}
}
 
protected String retrieveToken(){
String token = null;
try {
recordStore = RecordStore.openRecordStore("tk", true);
// Si el record store está vacío, retornamos null
if (recordStore.getNumRecords()==0)
return null;
// De lo contrario, leemos el token
else
{
ByteArrayInputStream bais = new ByteArrayInputStream(recordStore.getRecord(1));
DataInputStream inputStream = new DataInputStream(bais);
try {
token = inputStream.readUTF();
}
catch (EOFException eofe) {
System.out.println(eofe);
eofe.printStackTrace();
}
catch (IOException ioe) {
System.out.println(ioe);
ioe.printStackTrace();
}
}
recordStore.closeRecordStore();
}
catch (RecordStoreException rse) {
System.out.println(rse);
rse.printStackTrace();
}
return token;
}

Ahora, necesitamos modificar el MIDlet para implementar la interface OAuthDialogListener y agregar cierto código para autorizar la aplicación cuando el record store está vacío (lo que significa que la aplicación no ha sido autorizada antes).

Así que el MIDlet debería ser declarado de esta manera:

public class TestMIDlet extends MIDlet implements OAuthDialogListener{
 
...
 
public void onAuthorize(Token accessToken) {
Credential c = new Credential(CONSUMER_KEY, CONSUMER_SECRET, accessToken);
UserAccountManager uam = UserAccountManager.getInstance(c);
try {
if (uam.verifyCredential()) {
//Almacenamos el token de acceso
this.accessToken = accessToken;
strToken = accessToken.getToken();
storeToken(strToken);
search();
}
} catch (Exception e) {
System.out.println("Error when verifying credentials: " + e.getMessage());
}
}
 
public void onAccessDenied(String message) {
System.out.println("Access denied!");
}
 
public void onFail(String error, String message) {
System.out.println("Error when authenticating user: " + error + ", message:"+ message);
}

También necesiamos agregar código para inicializar el objeto 'wrapper' del diálogo de OAuth. Agregue este código al principio del método startApp():

        pageWrapper = new MIDletOAuthDialogWrapper(this);
pageWrapper.setConsumerKey(CONSUMER_KEY);
pageWrapper.setConsumerSecret(CONSUMER_SECRET);
pageWrapper.setOAuthListener(this);

Ahora, necesitamos agregar un 'action listener' para nuestro botón. Hacemos esto en el método startApp().

Observe que el mismo botón es usado para realizar diferentes acciones. Vea los comentarios en el código para entender mejor como y cuándo se inicia el proceso OAuth.

        button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// El botón inicia/continúa el proceso de autorización
// o ejecuta la búsqueda, dependiendo del
// contenido actual de la variable miembro strToken
if (strToken == null)
{
if (!PINrequested)
{
strSearchCriteria = textArea.getText();
// Inicia el proceso de autorización
pageWrapper.login();
label.setText("Enter PIN");
button.setText("Send PIN");
textArea.setText("");
textArea.repaint();
PINrequested = true;
}
else
{
// Continúa el proceso de autorización usando el PIN
pageWrapper.login(textArea.getText());
label.setText("Enter search term");
button.setText("Search");
textArea.setText(strSearchCriteria);
textArea.repaint();
}
}
else
search();
}
});

Y finalmente necesitamos implementar los métodos necesario para realizar la búsqueda:

	public void searchTweets(String exact){
try{
SearchDevice s = SearchDevice.getInstance();
// Número de tweets a retornar=25, lenguaje=en, tipo=recent tweets (tweets recientes)
Query q = new Query("rpp=25&lang=en&phrase="+exact+"&result_type=recent");
Tweet[] twts = null;
if(q != null)
twts = s.searchTweets(q);
else
System.out.println("Query not constructed");
for (int i=0; i<twts.length;i++)
System.out.println(i + "):" + twts[i]);
System.out.println("number of tweets received: " + twts.length);
}
catch (Exception e){
System.out.println(e);
e.printStackTrace();
}
}
 
protected void search(){
if (strToken != null)
searchTweets(textArea.getText());
}

Resumen

En resumen, así es como la aplicación cumple con su objetivo:

  1. Llama al método pageWrapper.login() para iniciar el proceso de autorización.
  2. Cuando el usuario ingresa el PIN recibido de Twitter, llama al método pageWrapper.login(PIN) para continuar el proceso de autorización.
  3. Cuando el método onAuthorize() es llamado, crea una credencial que consiste del 'consumer key', 'consumer secret' y el token de acceso que recibió de Twitter, y la verifica. Si la credencial es verificada, almacena el token de acceso.
  4. Con el token de acceso la aplicación tiene permitido interactuar con Twitter, en este caso, realiza una sencilla búsqueda de tweets.

Código Fuente

Un archivo zip que contiene el proyecto de la aplicación creada en este artículo, puede ser descargado aquí: TwitterAPIME Test.zip

This page was last modified on 27 June 2013, at 03:41.
130 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×