Ejercicios
Servicio reproductor de música
Vamos a crear un servicio que inicie la reproducción de un recurso audio al arrancarse, y que detenga la reproducción al pararse.
Descargad las plantillas de la sesión. En el proyecto
ServicioMusica
tenemos una actividad principal que muestra un botón Start y un botón Stop. En sus respectivosOnClickListener
's tendremos que iniciar y parar el servicio con los métodosstartService(...)
ystopService(...)
, pasándoles en ambos casos unnew Intent(main, MiAudioServicio.class)
como parámetro. Pero para ello tendremos que crear antes la clase que define el servicio:Creamos una nueva clase Java que se llame
MiAudioServicio
y sobrecargamos los métodosonStartCommand
,onCreate
,onDestroy
yonBind
, ayudándonos de las herramientas que proporciona Eclipse.Declaramos un campo
private MediaPlayer mediaPlayer;
en la clase del servicio.Cuando iniciemos el servicio desde la actividad, primero se creará y se invocará al método
onCreate(...)
. En él crearemos el reproductor:mostrando un
Toast
para quedarnos tranquilos de que el servicio se ha iniciado. El recurso R.raw.ubuntu es un archivo .ogg que se incluye en la carpetares/raw
de las plantillas del proyecto. También podía haber sido un mp3.Una vez creado, se ejecutará el método
onStartCommand(...)
. En él iniciaremos la reproducción y devolveremos el valorService.START_STICKY
.Finalmente, al destruir el servicio, detendremos la reproducción y mostraremos un
Toast
:En cuanto al método
onBind
, devolveremosnull
, que indica que el servicio no tiene definido un interfaz AIDL para comunicarse con otros.Para que el servicio funcione en la aplicación, habrá que declararlo en el
AndroidManifest.xml
, dentro deapplication
:
Si todo ha ido bien, y si hemos implementado los listeners de los botones que inician y detienen el servicio, debería funcionar. Probad iniciar el servicio y salir de la aplicación, entrar en otras, etc. El sonido seguirá reproduciéndose. Para detenerlo, volvemos a abrir la aplicación y lo detenemos.
Servicio con proceso en background. Contador
Los servicios se utilizan para ejecutar algún tipo de procesamiento en background. En el anterior ejercicio utilizamos el reproductor del sistema y simplemente le indicamos cuándo iniciarse y cuándo detenerse. En este ejercicio vamos a crear nuestro propio proceso que ejecute determinada tarea, en este caso, que vaya contando desde 1 hasta 100, deteniéndose 5 segundos antes de cada incremento. En cada incremento mostraremos un Toast
que nos informe de la cuenta.
En las plantillas tenemos el proyecto ServicioContador
que ya incluye la declaración del servicio en el manifest, la actividad que inicia y detiene el servicio, y el esqueleto del servicio MiCuentaServicio
.
En el esqueleto que se proporciona, viene definida una extensión de
AsyncTask
llamadaMiTarea
. Los métodosonPreExecute
,doInBackground
,onProgressUpdate
yonCancelled
están sobrecargados pero están vacíos. Se pide implementarlos, el primero de ellos inicializando el campoi
que se utiliza para la cuenta, el segundo ejecutando un bucle desde 1 hasta 100, y en cada iteración pidiendo mostrar el progreso y durmiento después 5 segundos conThread.sleep(5000)
. El tercer método,onProgressUpdate
mostrará elToast
con el progreso, y por último el método de cancelación pondrá el valor máximo de la cuenta para que se salga del bucle.En los métodos del servicio,
onCreate
,onStartCommand
yonDestroy
, introduciremos la creacion de la nuevaMiTarea
, su ejecución (métodoexecute()
de la tarea) y la cancelación de su ejecución (métodocancel()
de la tarea).
Una vez más, el servicio deberá seguir funcionando aunque se salga de la aplicación y podrá ser parado entrando de nuevo en la aplicación y pulsando Stop.
Servicio con notificaciones. Números primos
Este ejercicio es una extensión del anterior, pero vamos a utilizar un nuevo proyecto plantilla, el ServicioNotificaciones
. En lugar de mostrar cualquier número de la cuenta, vamos a mostrarlos sólo si son primos. Además, en lugar de mostrar un Toast
, vamos a mostrar una Notification
que aparecerá en la barra de tareas y se actualizará con la llegada de cada nuevo número. Si salimos de la aplicación sin parar el servicio, seguirán apareciendo notificaciones, y si pulsamos sobre la notificación, volverá a lanzar la actividad, cerrándose la notificación que hemos pulsado.
Dentro del servicio
MiNumerosPrimosServicio
se encuentra declarada laAsyncTask
llamadaMiTarea
. En ella tenemos como campos de la clase unaNotification
y unNotificationManager
. Hay que darles valores en el métodoonPreExecute()
.El método
doInBackground(...)
ejecutará un bucle que irá incrementandoi
mientras su valor sea menor deMAXCOUNT
. En cada iteración, si el número es primo (función incluida en la plantilla), pedirá que se muestre el progreso, pasándole como parámetro el nuevo primo encontrado.Implementar el método
onProgressUpdate(...)
para que muestre la notificación. Para ello habrá que actualizar la notificación con el métodosetLatestEventInfo
, al cuál le pasaremos en un String la información del último primo descubierto y le pasaremos unPendingIntent
para que al pulsar sobre la notificación, nos devuelva a la actividad de la aplicación, por si la hemos cerrado. Para crear el PendingIntent utilizaremos el métodoPendingIntent.getActivity(...)
al cuál le tenemos que pasar unnew Intent(getApplicationContext(),Main.class)
.La aplicación debería funcionar en este punto, mostrando las notificaciones y relanzando la aplicación si son pulsadas, pero no cerrándolas al pulsarlas. Para ello simplemente tenemos que llamar al método
cancel(id)
delnotificationManager
y pasarle la constante NOTIF_ID para que la notificación no se muestre como una nueva, sino como actualización de la que ya habíamos puesto. Una manera de hacerlo es en un método estático delMiNumerosPrimosServicio
, que podemos llamarcerrarMiNotificacion(NotificationManager nm)
. Este método será invocado desde elMain.onResume()
.
IP AppWidget
En programación de Android se denomina Widget
a los componentes de alto nivel de la interfaz de usuario, y AppWidgets
a los widgets que se pueden añadir al escritorio del sistema operativo, como el reloj, pequeños controles, etc.
Vamos crear un proyecto AppWidget
para construir un AppWidget de Android, que nos muestre en todo momento la IP que el dispositivo está usando en este momento. No necesitaremos ninguna actividad, así que podemos desmarcar la casilla "Create activity", o bien eliminar la actividad después (no sólo la clase, sino también la declaración en el manifest).
En el proyecto pulsamos con el boton derecho y añadimos un nuevo Android XML File, de tipo AppWidget Provider, que se llame miwidget.xml
. El editor nos permite pulsar sobre el AppWidget Provider y editar sus atributos. Ponemos los siguientes:
El miwidget_layout lo tenemos que crear, o dará error. Así que creamos un nuevo Android XML File de tipo Layout llamado miwidget_layout.xml
y le añadimos un campo de texto TextView
con el texto vacío.
Creamos una clase MiWidget
que herede de AppWidgetProvider
, en el paquete es.ua.jtech.daa.appwidget
. Sobrecargamos su método onUpdate(...)
y actualizamos en él el campo de texto, usando RemoteViews
y pasándoselos al AppWidgetManager
:
Antes de probar el widget hay que declararlo en el AndroidManifest.xml
, dentro de application
:
Ejecutamos el widget desde Eclipse, como aplicación android, y comprobamos que no ocurra ningún error en la consola de Eclipse. Ya se puede añadir el widget en el escritorio, efectuando una pulsación larga sobre una porción de área libre del escritorio, y seleccionando nuestro widget.
Instrucciones para programar el servicio que se pide:
Creamos la clase
public static class UpdateService extends Service
dentro de la claseMiWidget
y sobrecargamos los métodosonBind
(que es obligatorio, pero devolveránull
) yonStartCommand
que devolveráService.START_STICKY
.Hay que declarar el servicio en el
AndroidManifest.xml
, dentro deapplication
, con:Del método
MiWidget.onUpdate(...)
podemos cortar todas las líneas y sustituirlas por la llamada al servicio:En el método
onStartCommand
del servicio, pegaremos las líneas que actualizan los RemoteViews, pero las modificaremos para que obtengan el contexto y el paquete del widget, quedando el método así:
Ahora podemos volver a probar el widget, ejecutándolo desde Eclipse. Si funciona, podemos pasar a sustituir la línea
por el código que accede a la URL por HTTP, obteniendo un InputStream y convirtiendo los bytes a String para mostrarlo:
Antes de probarlo hay que añadir el permiso de Internet en el AndroidManifest.xml
, fuera de application
:
Ejecutamos y observamos el resultado:
Se puede añadir un comportamiento al pulsar sobre algún componente del widget. Por ejemplo, para que se abra un navegador con la web consultada, añadiríamos las siguientes líneas para actualizar el updateViews
:
Para que la referencia al recurso
R.id.miwidgetlayout
funcione, se tiene que definir el atributoandroid:id="@+id/miwidgetlayout"
delLinearLayout
del widget, que se encuentra en el archivomiwidget_layout.xml
.
Última actualización
¿Te fue útil?