CAPITULO 1 – Introducción
Saludos chi@s
Si, soy yo :3 , una vez más me doy paseo por los dominios de El Androide Libre, pero esta ves cruzo la barrera de espectador y formare parte (por unos cuantos bytes) del equipo de producción de este genial blog.
A modo de introducción y con la intención de refrescar la memoria debo decir que los widgets son ”vistas”[1] en miniatura de aplicaciones que se pueden incrustar en otras aplicaciones (como la pantalla de inicio) y las cuales puedes recibir actualizaciones periódicas.
Con estos dos datos : Aplicación que se puede incrustar en la pantalla de inicio y que reciba actualizaciones periódicas, podemos hacernos una idea de que vamos a hablar , a que si ? xDDD
Por lo que se desprende de lo anterior que el tema fundamental de este post, es simple : Como se desarrolló el Widget de El Androide Libre para Android.[2] [3]
Debo decir también que este widget fue mi primera vez :3 y quiero agradecer al desarrollador y amigo Pablo Verd Gallego[4] que me facilitó muchísimo las cosas.
CAPITULO 2 – Desarrollo (Si tranquilos el melodrama se terminó xDDD )
Sin dar mucho rodeo (ya di el suficiente xDDD ) toca cocinar el bocadillo.
Para desarrollar una Aplicación Widget necesitamos algunos ingredientes, los cuales son:
- Objeto AppWidgetProviderInfo[5] : Describe los metadatos de un widget, tales como el esquema[6] del widget, la frecuencia de actualización, y la clase AppWidgetProvider. Esto debería ser definido en un XML.
- Objecto AppWidgetProvider[7] : Define los métodos básicos que te permitirán interactuar con el widget a través de eventos de difusión(broadcast events). A través de estos eventos recibirá cuando la aplicación Widget es actualizada, activada, desactivada y borrada.
- Layout [6]: Aquí se definiría en un xml la apariencia inicial del widget.
Pues bien con estos datos , toca darles un poco de forma.
Lo primero que haremos sera crear un nuevo proyecto android en el eclipse:
Una vez clickemos aparecerá la siguiente pantalla:
En la cual tenemos 5 marcas en rojo que son:
- Nombre del proyecto: Es el nombre que nos aparece en el listado de proyectos
- Build Target: Aquí escogemos la versión de android para la cual deseamos se genere la aplicación, en este caso 1,6 API 4
- Application name: Este es el nombre de la aplicación , el que nos saldrá en el menú de aplicaciones y en el market y en todos lados del sistema android
- Package name: En java todo esta organizado en paquetes, que tienen jerarquías y cada palabra separada por puntos es una carpeta normalmente xDDD
- Min SDK Version es la versión con la cual deseamos nuestra aplicación sea también compatible hacia abajo, en este caso API 3 que es Android 1.5
Fijaros que no esta marcada la casilla “Create Activity” Usualmente viene marcada y asi se genera una típica aplicación Hello World que a pesar de ser muy simple nos deja pistas para saber como funciona una app android
Ya con el esqueleto de la aplicación creado buscamos el archivo dentro del proyecto que se llama AndroidManifest.xml este archivo dice como es y como funcionara nuestra aplicación en gran medida en el sistema android.
Este seria el contenido de nuestro AndroidManifest.xml :
<?xml version=»1.0″ encoding=»utf-8″?>
<manifest xmlns:android=»http://schemas.android.com/apk/res/android»
package=»com.yeradis.android.widget.elandroidelibre»
android:versionCode=»1″
android:versionName=»1.0″>
<application android:icon=»@drawable/icon» android:label=»@string/app_name»></application>
<uses-sdk android:minSdkVersion=»3″/>
</manifest>
Como podrán ver a simple vista reconocerán algunos de los valores que escogimos previamente a la hora de crear el proyecto, pero mirad lo que esta seleccionado en negrita. Esto es el cuerpo de nuestra aplicación y esta vacío, ya que desmarcamos que nos creara la ventana de ejemplo.
Ahora dentro del bloque “application” escribimos lo siguiente:
<receiver android:name=».Widget»>
<intent-filter>
<action android:name=»android.appwidget.action.APPWIDGET_UPDATE»/>
</intent-filter>
<meta-data android:name=»android.appwidget.provider» android:resource=»@xml/appwidget_info»/>
</receiver>
Y con esto decimos que nuestra aplicación android es un widget y que las características del mismo están dadas por su metadata, en este caso en @xml/appwidget_info.
Pero ojo, que name=”.Widget” es donde estará el código(Widget.java) del widget que es realmente el que hará algo , como obtener datos de la red y ponerlos donde toca.
VOILA! , hasta aquí ya podemos decir que tenemos un widget , aunque no hace mucho , ya que petaría porque no encuentra el archivo appwidget_info.xml dentro de la carpeta xml y esta carpeta debería estar dentro de la carpeta “res” (aquí dentro están las imágenes de la aplicación ,las ventanas, sonidos,textos,etc)
Como no existe debemos crear la carpeta xml y dentro el archivo appwidget_info.xml con mas información del Widget como la apariencia de donde vendrá y cada cuanto tiempo se actualizara.
El contenido de este xml debería ser así:
<appwidget-provider
xmlns:android=»http://schemas.android.com/apk/res/android»
android:minWidth=»270dp»
android:minHeight=»54dp»
android:updatePeriodMillis=»1800000″
android:initialLayout=»@layout/widget»
android:layout_margin=»0dp»
>
</appwidget-provider>
El cual dice que nuestro widget sera 270dp(minWidth) de ancho y 54dp(minHeight) de alto pero que además se actualizara cada 30 minutos (updatePeriodMillis=1800000) y que la apariencia inicial esta en el archivo widget.xml(initialLayout=@layour/widget) dentro de la carpeta xml, todo esto sin ningún margen posible así se acoplara mejor a los extremos.
Toca entonces ver como se vera nuestra widget, y eso lo podremos ver en el archivo layout/widget.xml(podía ser otro nombre)
nota: en la carpeta res/layout es donde están todas las ventanas y demás elementos visuales de las aplicaciones android.
Dentro de la carpeta layout crearemos el archivo widget.xml con el siguiente contenido:
<?xml version=»1.0″ encoding=»utf-8″?>
<LinearLayout android:id=»@+id/widget»
android:layout_width=»fill_parent» android:layout_height=»wrap_content»
android:orientation=»vertical» xmlns:android=»http://schemas.android.com/apk/res/android»
android:background=»@drawable/panel» android:minWidth=»270dp»
android:minHeight=»54dp» android:padding=»0dp»
android:layout_marginBottom=»0dp»>
<LinearLayout android:id=»@+id/widget29″
android:layout_width=»fill_parent» android:layout_height=»wrap_content»
android:orientation=»horizontal» android:layout_marginBottom=»0dp»
android:padding=»0dp»>
<ImageView android:id=»@+id/condition_image»
android:layout_width=»wrap_content» android:layout_height=»wrap_content»
android:src=»@drawable/icon_small» android:layout_gravity=»center_vertical»
android:layout_marginRight=»2dp» android:layout_marginBottom=»0dp»>
</ImageView>
<LinearLayout android:id=»@+id/widget282″
android:layout_width=»fill_parent» android:layout_height=»wrap_content»
android:orientation=»vertical» android:layout_marginBottom=»0dp»>
<LinearLayout android:id=»@+id/widget281″
android:layout_width=»fill_parent» android:layout_height=»wrap_content»
android:orientation=»horizontal» android:gravity=»center_vertical»>
<TextView android:id=»@+id/title» android:layout_width=»wrap_content»
android:layout_height=»wrap_content» android:textSize=»16dp»
android:text=»www.elandroidelibre.com/»
android:textColor=»#FFF»
android:ellipsize=»end» android:lines=»2″>
</TextView>
</LinearLayout>
<LinearLayout android:id=»@+id/widget28″
android:layout_width=»fill_parent» android:layout_height=»fill_parent»
android:orientation=»horizontal» android:gravity=»center_vertical»>
<TextView android:id=»@+id/content» android:layout_width=»wrap_content»
android:layout_height=»wrap_content»
android:text=»Cargando…»
android:textSize=»12dp» android:ellipsize=»end» android:lines=»2″>
</TextView>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout android:layout_width=»fill_parent»
android:layout_height=»fill_parent» android:orientation=»horizontal»
android:gravity=»left» android:background=»@drawable/bg_green»
android:minHeight=»3dp»>
</LinearLayout>
<LinearLayout android:layout_width=»fill_parent»
android:layout_height=»fill_parent» android:orientation=»horizontal»
android:gravity=»left» android:background=»#FFF» android:minHeight=»3dp»>
</LinearLayout>
</LinearLayout>
Para que no sea lien mas xDDD , aqui os dejo visualmente que es son todos estos garabatos xDD :
- Tenemos todo un área grande que contiene todo, serian los bordes mas extremos
- Tenemos el icono del Android Libre para que se pueda identificar con los dueños (quizás debería cambiar el icono por uno mejor)
- Los dos bloques de texto de la derecha están dentro de otro que no esta marcado
- Las franjas blanca y verde de la parte de abajo para hacer juego con el icono xDDD
Y hasta aquí tenemos definida nuestra forma visual del widget.
Ya esta , es todo…. que no que es broma, recuerdan el archivo Widget.java ? Ahora viene lo mas complicado xDDD
CAPITULO 3: NECESITO AYUDA POR FAVOR!
Si si si la parte de antes era la sencilla xDDD. Pero tranquilos no pasa nada tampoco es para quedarse calvo[8] Con suerte tienes algún amigo o conocido como Pablo Verd Galledo[4] Pues eso, ahora respiramos hondo y abrimos el archivo Widget.java y podremos ver:
package com.yeradis.android.widget.elandroidelibre;
import com.yeradis.android.widget.elandroidelibre.Rss.Item;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.RemoteViews;
public class Widget extends AppWidgetProvider {
/** Called when the activity is first created. */
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
Log.e(«status», «enabled»);
}
@Override
public void onUpdate(final Context context, final AppWidgetManager appWidgetManager, final int[] appWidgetIds) {super.onUpdate(context, appWidgetManager, appWidgetIds);
final RemoteViews updateView = new RemoteViews(
context.getPackageName(), R.layout.widget);
updateInfo(context, updateView, appWidgetManager, appWidgetIds);
Log.e(«status», «update»);
}
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
super.onReceive(context, intent);
Log.e(«status», «receive»);
}
public void updateInfo(Context ctx, RemoteViews updateView,
AppWidgetManager appWidgetManager, int[] appWidgetIds) {
try {
Item item = Rss.getFirst();
updateView.setImageViewResource(R.id.condition_image,
R.drawable.icon_small);
updateView.setTextViewText(R.id.title, item.getTitle());
updateView.setTextViewText(R.id.content, item.getDescription());
Intent defineIntent = new Intent();
defineIntent.setClass(ctx,
com.yeradis.android.widget.elandroidelibre.Windows.class);
PendingIntent pendingIntent = PendingIntent.getActivity(ctx,
0 /* no requestCode */, defineIntent, 0 /* no flags */);
updateView.setOnClickPendingIntent(R.id.widget, pendingIntent);} catch (Exception e) {
updateView.setTextViewText(R.id.content, e.getMessage());
e.printStackTrace();
Log.e(«ERROR», e.getMessage());
}
appWidgetManager.updateAppWidget(appWidgetIds, updateView);
}
}
Donde de las primeritas cosas que podremos leer será:
public class Widget extends AppWidgetProvider
Les suena algo ? si es así es señal que no se han saltado los primeros capitulos xDDD :p Pero lo interesante esta en el método onUpdate que es el que se ejecutará cada media hora por aquello de la actualización ¿recuerdan ? exacto , eso mismo.
En ese método realmente para evitar que se quede congelado el widget y otros síntomas típicos de estas aplicaciones , nos crearemos una vista remota(RemoteViews) que procesaremos en otro método y esta vista es la que actualizará a nuestro widget con la nueva información.
Dentro de updateInfo veremos algunas cosillas, primero:
Item item = Rss.getFirst();
Esto es una clase java que me cree para leer el Rss[9] de El Androide Libre y sacar la información, no solo sino que en este caso solo utilizare el valor del primer articulo aunque estén todos almacenados en el objeto. Realmente esto no es muy importante , encontraran mejores cosas en la web.
lo segundo:
- updateView.setImageViewResource(R.id.condition_image, R.drawable.icon_small);
- updateView.setTextViewText(R.id.title, item.getTitle());
- updateView.setTextViewText(R.id.content, item.getDescription());
Tomo los valores de ese primero elemento y se los asigno a las partes del widget necesarias para su visualización.
Aunque lo realmente importante aquí es :
appWidgetManager.updateAppWidget(appWidgetIds, updateView);
Ya que por muchos datos que obtengamos de la red y asignemos a los elementos visuales si no los devolvemos al sistema android para que los pinte de nada servirá xDDD
CAPITULO 5: DESPEDIDA Y AGRADECIMIENTOS
Ya esta señores y señoritas. A grandes rasgos tienen como está hecho el Widget de El Androide Libre[2]
En una próxima entrega hablaremos de la aplicación , esa que aparece cuando le haces click al widget y salen los demás artículos entre otras cosillas.
No quiero despedirme sin antes agradecer a lo chic@s de El Androide Libre por la confianza depositada en mi al pedirme como regalo de aniversario de este sitio un Widget para todo uds los seguidores de este blog.
Gracias también a todos los que tiene la aplicación y nos van dejando comentarios y sugerencias en el Market así como por otras vias, en fin
GRACIAS POR USAR EL WIDGET/APP EL ANDROIDE LIBRE[2]
Sin otro asunto que tratar(por ahora)….
Me despido
Si queréis descargar el widget y la aplicación aquí la tenéis
Referencia:
[1] En Android todo son vistas , un botón , una ventana,un listado, etc. Estas vistas se conocen como Widgets en la interfaz del usuario.
[2]http://www.androidzoom.com/android_applications/news_and_weather/el-androide-libre_icbr.html
[3]Si no sabes de que aplicación estamos hablando, estás tardando en descargártela[2] xDDD
[4]http://www.androidzoom.com/android_applications/pablo+verd+gallego/by_matching
[5]http://developer.android.com/reference/android/appwidget/AppWidgetProviderInfo.html
[6] en la jerga de los programadores(muchos de ellos entre los que me incluyo) se le conoce como Layout a secas y sin traducción, lo típico, a muchas cosas las llamamos por su versión en ingles xDDD
[7]http://developer.android.com/reference/android/appwidget/AppWidgetProvider.html
[8]http://lh3.ggpht.com/_xD3G2L5XZD0/TG8bNHpHF5I/AAAAAAAAPT0/WsXkPFW1WRI/s800/2010-05-01%2010.27.31_edit0_edit0.jpg
[9]view-source:http://feeds.feedburner.com/elandroidelibre?format=xml