Índice 1 Contador: Servicio con proceso en background (0.6 puntos)... 2 2 Broadcast Receiver: Captura de llamadas (0.6 puntos)...2 3 Broadcast Receiver: Reenvío de datos (0.6 puntos)...3 4 Arranque: Iniciar servicio al arrancar el móvil (0.6 puntos)... 4 5 Calculadora: Comunicación con el servicio (0.6 puntos)...4
1. Contador: Servicio con proceso en background (0.6 puntos) Los servicios se utilizan para ejecutar algún tipo de procesamiento en background. En este ejercicio vamos a crear nuestro propio proceso asociado a un servicio que ejecutará una determinada tarea. En este caso el proceso asociado contará desde 1 hasta 100 deteniéndose 5 segundos antes de cada incremento. Cada vez que se cambie de valor se mostrará un Toast que nos informe de la cuenta. En las plantillas tenemos el proyecto android-av-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 llamada MiTarea. Los métodos onpreexecute, doinbackground, onprogressupdate y oncancelled están sobrecargados pero están vacíos. Se pide implementarlos, el primero de ellos tiene que inicializar el campo i que se utiliza para la cuenta, el segundo tiene que ejecutar un bucle desde 1 hasta 100, y en cada iteración pedir que se muestre el progreso (publishprogress) y hacer una pausa de 5 segundos con Thread.sleep(5000). El tercer método, onprogressupdate mostrará el Toast 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 y ondestroy, introduciremos la creación de la nueva MiTarea, su ejecución (método execute() de la tarea) y la cancelación de su ejecución (método cancel() de la tarea). 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. 2. Broadcast Receiver: Captura de llamadas (0.6 puntos) Se pide crear un proyecto android-av-broadcast que capture los números de teléfono de las llamadas entrantes y los muestre a través del LogCat. El proyecto tendrá un único fichero de código Java (llamado MiBroadcastReceiver) que implementará un BroadcastReceiver. En primer lugar añadiremos esta clase al Manifest, y le asignaremos un intent-filter que capture las acciones de tipo: "android.intent.action.phone_state". Además es necesario solicitar en el Manifest permisos para leer el estado del teléfono, para esto tenemos que añadir: "<uses-permission android:name="android.permission.read_phone_state"/>". En el método "onreceive" de nuestra clase "MiBroadcastReceiver" comprobaremos que el evento recibido es del tipo esperado: String action = intent.getaction(); if(action.equals("android.intent.action.phone_state") { 2
\\... Si es de este tipo obtendremos el número de teléfono de la llamada a partir de los extras que recibimos en el intent (revisar la sección correspondiente de teoría) y lo mostraremos en el Log. Al ejecutar esta aplicación Eclipse nos mostrará los siguientes avisos: "No Launcher activity found!", "The launch will only sync the application package on the device!". Esto es normal debido a que no hay una actividad principal que pueda mostrar, sin embargo sí que instalará la aplicación. Para comprobar que tu aplicación funciona correctamente abre la vista "Emulator Control" (Window > Show view > Other... > "Emulator Control") y realiza una llamada de prueba. Nota A partir de la versión 3.1 de Android es necesario que se incluya una actividad visible (además de la clase con el BroadcastReceiver) para que sea efectuado el registro del receiver. En esta actividad podríamos poner algún texto explicativo como: "Se ha registrado el servicio". 3. Broadcast Receiver: Reenvío de datos (0.6 puntos) Vamos a ampliar el ejercicio anterior para que al recibir una llamada envíe datos mediante un SMS a un número de teléfono. El servicio podría, por ejemplo, enviar la posición GPS cuando recibe la llamada de un número específico. En este ejercicio, por simplificar, enviaremos un SMS cuando se reciba una llamada desde cualquier número y como texto del SMS se incluirá el propio número que ha llamado. En primer lugar modificamos el Manifest de la aplicación anterior para solicitar permisos para el envío de SMSs: <uses-permission android:name="android.permission.send_sms"/> En el fichero de código del broadcast ("MiBroadcastReceiver") añadimos la siguiente función para el envío de SMSs: public void send( String phonenumber, String message ) { SmsManager sms = SmsManager.getDefault(); sms.sendtextmessage( phonenumber, null, message, null, null ); Log.i( "SendSMS", "Enviando SMS a " + phonenumber + ": \"" + message + "\"" ); Por último modificamos el código del método "onreceive" para que además de mostrar el número de la llamada por el Log lo envíe por SMS. Para probar este ejercicio tenemos que abrir dos emuladores. En uno de ellos instalamos 3
el servicio y utilizamos el segundo emulador para realizar la llamada y comprobar que se recibe el SMS correctamente. Para realizar una llamada de un emulador a otro simplemente hay que marcar el número del puerto que aparece en el título de la ventana de cada emulador. 4. Arranque: Iniciar servicio al arrancar el móvil (0.6 puntos) En el proyecto android-av-onboot tenemos un servicio que se lanza al iniciar la actividad, mostrando Toasts del 1 al 5 y finalizando. Puedes comprobar ejecutando este proyecto como al arrancar o instalar la actividad se muestran estos Toast de aviso. Se pide modificar el código para que el servicio se inicie cuando el móvil haya terminado de arrancar. Para ello añadiremos el siguiente permiso al AndroidManifest.xml: <uses-permission android:name="android.permission.receive_boot_completed" /> También registraremos un receptor de broadcast MiBroadcastReceiver con un intent-filter para android.intent.action.boot_completed. A continuación implementaremos un BroadcastReceiver (llamado MiBroadcastReceiver) y en su método onreceive() introduciremos el código: if( "android.intent.action.boot_completed".equals(intent.getaction())) { ComponentName comp = new ComponentName(context.getPackageName(), MiServicio.class.getName()); ComponentName service = context.startservice( new Intent().setComponent(comp)); if (null == service){ Log.e(MiBroadcastReceiver.class.toString(), "Servicio no iniciado: " + comp.tostring()); else { Log.e(MiBroadcastReceiver.class.toString(), "Intent no esperado " + intent.tostring()); Tras ejecutar el proyecto desde Eclipse habrá que reiniciar el emulador para observar que el servicio se inicia al finalizar el arranque. El botón de apagar del emulador no funcionará, lo mejor es cerrar el emulador y volver a abrirlo. 5. Calculadora: Comunicación con el servicio (0.6 puntos) En este ejercicio vamos a practicar con los métodos de comunicación con un servicio. Para esto vamos a implementar una calculadora que a partir de un par de números de entrada realice su suma, resta, multiplicación o división utilizando un servicio. 4
En primer lugar creamos el proyecto y en la interfaz de la aplicación insertamos dos campos de edición (donde el usuario escribirá los operandos), un campo de texto vacío (donde se mostrará el resultado) y cuatro botones (para la suma, resta, multiplicación y división). A continuación añadiremos un servicio, llamado "MiServicioBind", en el cual implementaremos la clase onbind para poder realizar el binding. Además le añadiremos cuatro métodos públicos que a partir de dos números decimales devuelvan su suma, resta, multiplicación o división respectivamente. Además recordad que tenéis que añadir el servicio al Manifest del proyecto. En el código de la actividad principal, además de obtener referencias a los campos de edición y los botones e implementar sus métodos onclick, tendremos que atar el servicio que hemos creado. En los listener de los botones llamaremos al método correspondiente y mostraremos el resultado en el textview. Por último, tendremos que desatar el servicio al destruir la actividad. 5
6