arquitectura de aplicaciones€¦ · ciencia de la computaci ón e ia android avanzado - 10 layout...
TRANSCRIPT
Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles
© 2011-2012 Depto. Ciencia de la Computación e IA
Android avanzado
Sesión 3: Notificaciones y AppWidgets
Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles
© 2011-2012 Depto. Ciencia de la Computación e IAAppWidgets Android avanzado - 2
Puntos a tratar
• Notificaciones• AppWidgets
• Crear un Widget• RemoteViews• Recibir los intent de actualización• Servicio de actualización• Actividad de configuración
Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles
© 2011-2012 Depto. Ciencia de la Computación e IAAppWidgets Android avanzado - 3
Notificaciones
• Las Notification son el mecanismo típico que utilizan los servicios para comunicarse con el usuario.
• No roban el foco a la aplicación actual.
• Permanecen el tiempo que haga falta hasta ser vistas o descartadas
• Permiten mostrar distintos tipos de información
• Pueden responder a la pulsación
• Se pueden actualizar
Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles
© 2011-2012 Depto. Ciencia de la Computación e IAAppWidgets Android avanzado - 4
Notification Manager
• El id sirve para actualizar la misma notificación o poner una nueva, si es un id nuevo.
• También se puede modificar la información de una instancia ya creada de una Notification:
Notification notification; int id = 1; NotificationManager notificationManager; notificationManager = (NotificationManager)getSystemService( Context.NOTIFICATION_SERVICE); notification = new Notification(R.drawable.icon, "Mensaje evento", System.currentTimeMillis()); notificationManager.notify(id, notification);
notification.setLatestEventInfo(getApplicationContext(), "Texto", contentIntent); notificationManager.notify(id, notification);
Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles
© 2011-2012 Depto. Ciencia de la Computación e IAAppWidgets Android avanzado - 5
Contestar a la pulsación
• contentIntent es un Intent que se puede usar para abrir una actividad
• Al abrirse la actividad conviene cerrar la notificación que ya no será necesaria. Se puede hacer desde el método onResume() de la actividad:
notification.setLatestEventInfo(getApplicationContext(), "Texto", contentIntent);
@Override protected void onResume() { super.onResume(); notificationManager.cancel(MiTarea.NOTIF_ID); }
Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles
© 2011-2012 Depto. Ciencia de la Computación e IAAppWidgets Android avanzado - 6
Notificaciones con AsyncTask private class MiTarea extends AsyncTask<String, String, String>{ public static final int NOTIF1_ID = 1; Notification notification; NotificationManager notificationManager; @Override protected void onPreExecute() { super.onPreExecute(); notificationManager = (NotificationManager)getSystemService( Context.NOTIFICATION_SERVICE); notification = new Notification(R.drawable.icon, "Mensaje evento", System.currentTimeMillis()); } @Override protected String doInBackground(String... params) { while(condicionSeguirEjecutando){ if(condicionEvento) publishProgress("Información del evento"); } return null; } @Override protected void onProgressUpdate(String... values) { Intent notificationIntent = new Intent( getApplicationContext(), MiActividadPrincipal.class); PendingIntent contentIntent = PendingIntent.getActivity( getApplicationContext(), 0, notificationIntent, 0); notification.setLatestEventInfo(getApplicationContext(), values[0], contentIntent); notificationManager.notify(NOTIF_ID, notification); } }
Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles
© 2011-2012 Depto. Ciencia de la Computación e IAAppWidgets Android avanzado - 7
AppWidgets
• También conocidos como widgets
• Ocupan determinado área del home (escritorio)
• Se refrescan con determinada frecuencia
Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles
© 2011-2012 Depto. Ciencia de la Computación e IAAppWidgets Android avanzado - 8
Definir un widget
• Declaración necesaria en• En un recurso XML• En el AndroidManifest.xml
• Clase que herede de AppWidgetProvider• Normalmente habrá un servicio actualizando el widget.
Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles
© 2011-2012 Depto. Ciencia de la Computación e IAAppWidgets Android avanzado - 9
XML del widget
• Declara:• Área que ocupa• Layout que lo define• Período de actualización en milisegundos, mínimo 30 min
<?xml version="1.0" encoding="utf-8"? ><appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="146dip" android:minHeight="72dip" android:updatePeriodMillis="600000" android:initialLayout="@layout/miwidget_layout" />
Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles
© 2011-2012 Depto. Ciencia de la Computación e IAAppWidgets Android avanzado - 10
Layout
• Los views definidos en el layout del widget se actualizan a través de RemoteViews
• Ejemplo de layout básico:
<?xml version="1.0" encoding="utf-8"?><LinearLayout android:id="@+id/miwidget" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal">
<TextView android:text="" android:id="@+id/TextView01" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
</LinearLayout>
Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles
© 2011-2012 Depto. Ciencia de la Computación e IAAppWidgets Android avanzado - 11
Componentes permitidos
• layouts • FrameLayout• LinearLayout• RelativeLayout
• views • AnalogClock• Button, Chronometer • ImageButton• ImageView• ProgressBar• TextView
• EditText no está permitido: emular con actividad al pulsar
Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles
© 2011-2012 Depto. Ciencia de la Computación e IAAppWidgets Android avanzado - 12
Android 3 y 4
• Nuevos componentes• GridView• ListView• StackView • ViewFlipper• AdapterViewFlipper
Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles
© 2011-2012 Depto. Ciencia de la Computación e IAAppWidgets Android avanzado - 13
Widget y AndroidManifest.xml
• Declarar el widget, su recurso XML y, si procede, el servicio que lo actualiza
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="es.ua.jtech.ajdm.appwidget" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <receiver android:name=".MiWidget" android:label="Mi Widget"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/miwidget" /> </receiver> <service android:name=".MiWidget$UpdateService" /> </application> <uses-sdk android:minSdkVersion="8" /></manifest>
Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles
© 2011-2012 Depto. Ciencia de la Computación e IAAppWidgets Android avanzado - 14
RemoteViews
RemoteViews updateViews = new RemoteViews( context.getPackageName(), R.layout.miwidget_layout); //Actualizar un campo de texto del widgetupdateViews.setTextViewText(R.id.TextView01, "texto"); //Comportamiento al pulsar el widget//On-click listener que envía un broadcast intentIntent intent = new Intent(ACTION_WIDGET_CLICK);PendingIntent pendingIntent = PendingIntent.getBroadcast( context, 0, intent, 0);updateViews.setOnClickPendingIntent( R.id.miwidget, pendingIntent); ComponentName thisWidget = new ComponentName( context, MiWidget.class);AppWidgetManager.getInstance(context).updateAppWidget( thisWidget, updateViews);
• Actualizar los componentes obteniendo el AppWidgetManager a partir del context
Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles
© 2011-2012 Depto. Ciencia de la Computación e IAAppWidgets Android avanzado - 15
RemoteViews
• Si pulsamos algún componente, lanzar una actividad:
// ... //¿qué hacer si lo pulsamos? Lanzar alguna actividad: Intent defineIntent = new Intent(....); PendingIntent pendingIntent = PendingIntent.getActivity( getApplicationContext(), 0, defineIntent, 0); updateViews.setOnClickPendingIntent(R.id.miwidget,pendingIntent); //Y la actualización del widget con el updateViews creado: ComponentName thisWidget = new ComponentName( this, MiWidget.class); AppWidgetManager.getInstance(this).updateAppWidget( thisWidget, updateViews);
Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles
© 2011-2012 Depto. Ciencia de la Computación e IAAppWidgets Android avanzado - 16
Recibir intents de actualización
• El widget es un receptor de intents• El intent de actualización
android.appwidget.action.APPWIDGET_UPDATE• Intents propios, por ejemplo
es.ua.jtech.av.ACTION_WIDGET_CLICK
• En el <receiver>:
<intent-filter> <action android:name="es.ua.jtech.av.ACTION_WIDGET_CLICK" /> </intent-filter>
Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles
© 2011-2012 Depto. Ciencia de la Computación e IAAppWidgets Android avanzado - 17
Recibir intents de actualización
• Recibir el intent propiopublic class MiWidget extends AppWidgetProvider { @Override public void onUpdate( Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { actualizar(context); } @Override public void onReceive(Context context, Intent intent) { super.onReceive(context, intent); if(intent.getAction().equals( "es.ua.jtech.av.ACTION_WIDGET_CLICK")){ actualizar(context); } }}
Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles
© 2011-2012 Depto. Ciencia de la Computación e IAAppWidgets Android avanzado - 18
Recibir intents de actualización
• Lanzar un pending intent para provocar la actualización:
Intent intent = new Intent("es.ua.jtech.av.ACTION_WIDGET_CLICK");PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);updateViews.setOnClickPendingIntent(R.id.miwidget, pendingIntent);
Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles
© 2011-2012 Depto. Ciencia de la Computación e IAAppWidgets Android avanzado - 19
Widget con servicio
public class MiWidget extends AppWidgetProvider { @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { // Inicio de nuestro servicio de actualización: context.startService(new Intent(context, UpdateService.class)); } public static class UpdateService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) {
...
... return Service.START_STICKY; } @Override public IBinder onBind(Intent intent) { return null; } }}
• Lanzar el servicio de actualización cada vez que se solicite el update del AppWidget
Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles
© 2011-2012 Depto. Ciencia de la Computación e IAAppWidgets Android avanzado - 20
Actividad de configuración del widget
• Se lanzará al intentar añadir el widget a la pantalla principal.
• En el manifest:
• En el xml del widget:
<activity android:name=".MiConfigurationActivity"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/> </intent-filter></activity>
<appwidget-provider...
android:updatePeriodMillis="3600000" android:configure="es.ua.jtech.av.appwidget.MiConfigurationActivity"/>
Especialista Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles
© 2011-2012 Depto. Ciencia de la Computación e IAAppWidgets Android avanzado - 21
Actividad de configuración del widget
• La actividad debe devolver:• Un Intent con un extra con el identificador del App Widget
usando la constante EXTRA_APPWIDGET_ID.
Ésta es incluída en el Intent que lanza la actividad.
• La actividad de configuración puede servir para decidir qué tamaño va a tener el widget, o qué tipo de vista va a mostrar.
Intent resultado = new Intent();result.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);setResult(RESULT_OK, resultado);finish();