sábado, 17 de abril de 2010

Limitaciones de widgets de android

O por qué te va a costar la vida misma encontrar widget de twitter para android que te permita pulsar enlaces desde la página principal :)

Ultimamente uso mucho twitter, en el ordenador de escritorio utilizo TweetDeck y en el android utilizo Peep, que es el cliente por defecto, la verdad es que si los comparas, peep queda bastante mal, no soporta muchas de las características que tienen las aplicaciones de pc.

Como decía un amigo cuando le enseñé orgulloso el stub de motor físico y de colisiones que estoy programando, esto es cuestión de montar un par de clases por aqui y otro par de clases por allá, así es que ni corto ni perezoso me documenté un poco y a tirar líneas.

Como base para el widget simplemente copié el que viene con el SDK de android dentro de la carpeta ApiDemos y para manipular la api de twitter he utilizado twitter4j, con lo que prácticamente tengo el 80% de la aplicación escrita, para el que quiera tiene el código fuente en http://code.google.com/p/androtwitt/

Ahora vienen los problemas y además todos juntos, me dije a mi mismo, jm, por qué no pones los enlaces en el propio widget, eso hará que sea más usable, así es que puse el atributo android:autoLink = true en los TextView del layout del widget, error, craso error, vamos, concretamente este:

android.util.AndroidRuntimeException: Calling startActivity() from
outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK
flag. Is this really what you want?


Hombre, pues la verdad es que el hecho de que me pegue un pellejazo no es precisamente lo que quería, pero bueno, si te pones así..., que significa esto, tengo una versión corta y una larga.

La larga es que cuando utilizas el atributo android:autoLink, el texto de los textview se convierte en hipertexto, por lo tanto puedes pulsar sobre los enlaces, esta pulsación se recoge en el evento onTouchEvent, que llama al método UrlSpan.onClick y éste a su vez crea una nueva actividad, esta actividad no tiene el flag FLAG_ACTIVITY_NEW_TASK y por lo tanto la máquina virtual no puede lanzar el navegador, por que no lo puede meter en la pila de llamadas del widget, o algo así ;)

La corta es que por ese camino estoy jodido :)

Por lo tanto yo, que soy el rey del workaround, decidí extender el objeto TextView para sobreescribir el maldito método con nocturnidad y alevosía, sería un corte limpio, sin sangre ;), ya sabeis como son estas cosas.

En android crear una vista es sencillo, sólo tienes que crear una clase que extienda de View o de alguna de sus subclases, en este caso extendería directamente de TextView y definir en ref/values/attrs.xml los atributos que vas a permitir en tu vista, además opcionalmente puedes definir un res/layout/vista.xml que defina el aspecto del widget, fácil, fácil, pero error, doble craso error, no puedes incluir una "custom view" en un widget por cuestiones de seguridad. Pos vaya mierda :(

Moraleja, ciñete al listado de layouts y vistas que se lista en la documentación, por que en cuestión de widgets no te puedes salir del tiesto.