10 nov 2011

Curso de introducción a Android VII (Broadcast Receivers, o cómo averiguar qué trama tu novia en su móvil..., Parte I)

Dejando un poco de lado el desarrollo del Flu Bot para móviles, hoy nos vamos a centrar en una funcionalidad que ofrece el SDK de Android y que permite el desarrollo de aplicaciones muy interesantes, la clase Broadcast Receiver.

En esta primera parte del artículo, vamos a centrarnos en definir qué es un Broadcast Receiver y qué se puede conseguir con esta clase. Posteriormente, mostraremos un ejemplo de aplicación que todos podréis probar en vuestro teléfono o emulador (siempre con fines didácticos por favor, lo del título es una coña :P)

¿Qué es un Broadcast Receiver?

Un Broadcast Receiver es una especie de receptor de los eventos que produce el sistema operativo Android. Típicamente, un Broadcast Receiver se utiliza para mostrar notificaciones de los eventos que ocurren en nuestro teléfono móvil, como por ejemplo el descubrimiento de una red wifi o el agotamiento de la batería. Nosotros vamos a aprovechar esta funcionalidad para hacer cosas un poco más maliciosas.

¿Qué eventos puedo capturar?

Me podría tirar todo el día escribiendo la cantidad de eventos del móvil que podemos capturar, de todas formas os pongo algunos de los más interesantes:

android.provider.Telephony.SMS_RECEIVED Evento de mensaje recibido.android.intent.action.PHONE_STATE Evento de llamadas recibidas.android.intent.action.AIRPLANE_MODE Evento modo vuelo. android.intent.action.BATTERY_LOW Evento batería baja.android.intent.action.BOOT_COMPLETED Evento de inicio del sistema operativo.android.intent.action.SCREEN_OFF Evento bloqueo de pantalla.android.intent.action.SCREEN_ON Evento desbloqueo de pantalla.android.bluetooth.intent.action.DISCOVERY_STARTED Evento comienzo de escáner Bluetooth.android.bluetooth.intent.action.ENABLED Evento Bluetooth habilitado.

Ejemplo de aplicación: nunca una llamada perdida fue tan peligrosa.

A continuación, vamos a poner en práctica la teoría propuesta con la realización de una aplicación basada en un Broadcast Receiver. Esta aplicación se ejecutará en el teléfono móvil de la víctima, de forma que cuando reciba una llamada perdida de un teléfono en concreto, enviará los mensajes de su bandeja de entrada a un servidor definido por nosotros.

Este Broadcast Receiver irá camuflado en una aplicación, aparentemente benévola, que será la encargada de lanzarlo. A continuación mostramos el código que lanza el Broadcast Receiver.

clip_image002

Como podemos observar, la aplicación que lanza el Broadcast Receiver es la más sencilla del mundo, no nos hemos complicado, ya que lo interesante está en las líneas de creación del Intent correspondiente al Broadcast Receiver y la forma de lanzarlo mediante el método sendBroadcast.

Después de ver la aplicación que lanza el Broadcast Receiver, vamos a ver qué pinta tiene el código del mismo.

clip_image004

Esta clase será la encargada de interceptar las llamadas que hagamos al teléfono. Como podemos ver, simplemente heredamos de la clase Broadcast Receiver y reescribimos el método onReceive que se activará cuando se produzca el evento al cual nos hemos registrado (más adelante veremos cómo registrarnos). Dentro del método onReceive activaremos el manejador necesario para tratar la llamada interceptada, este proceso se realiza mediante la instancia a la clase manager del teléfono TelephonyManager y a la implementación de un listener que implementará de la clase abstracta PhoneStateListener.

La clase correspondiente al listener de llamadas MyTelephonyManager tiene esta apariencia.

clip_image006

Lo primero que hacemos en el constructor de la clase es guardarnos el contexto que nos pasa el Broadcast Receiver, de esta forma podremos acceder a métodos que dependen de él más adelante. Posteriormente, cuando una llamada se produzca, se activará el método onCallStateChanged de nuestro listener y será ahí donde filtremos el tipo de llamada. En este caso no hemos filtrado por número, pero podéis hacerlo usando el parámetro incomingNumber del método. Una vez filtrado que la llamada está en estado RINGING (en el código os pongo los demás estados para indicar los que existen) procedemos a leer los mensajes de la bandeja de entrada mediante nuestro método moduleGetSMS. Dentro de este método nos declaramos la URI donde se encuentra la bandeja de entrada de los mensajes y nos ponemos a leer mediante un puntero a cada registro que compone un sms. Cada SMS leído tendrá esta pinta:

From:<tlf origen del sms> : <cuerpo del sms>

Una vez formado el string de los mensajes, lo mandamos por un socket mediante el método sendSMSInfo (si la información es muy grande lo ideal sería trocearla en varios String, este código es sólo una prueba).

Por último, debemos hacer unas pequeñas variaciones en nuestro querido AndroidManifest.xml. Estas variaciones consisten en dar permisos a la aplicación para que pueda manejar el manager de llamadas, el manager de mensajes, la salida a Internet y, por último, registrar el Broadcast Receiver para que capture eventos de llamadas. Nuestro AndroidManifest.xml quedaría de la siguiente manera:

clip_image008

Para finalizar, comentar que los Broadcast Receiver quedan registrados en el teléfono una vez lanzados, de forma que si lo reiniciamos seguiremos teniendo activa la funcionalidad. Otro detalle muy importante es que son invisibles, no aparecen ni en Aplicaciones Activas ni en Servicios en Ejecución y, por supuesto, no hace falta tener la aplicación que lo lanza activa para poder disfrutar de sus funciones.

Como siempre, os adjunto el código, espero que os guste...

Saludos!!

 

Recursos: Código Fuente

 

===============================================================

Curso de introducción a Android (Instalación del Android SDK + Hello World)

Curso de introducción a Android II (Creando nuestra primera aplicación)

Curso de introducción a Android III (Escáner de redes WIFI)

Curso de introducción a Android IV (Crackeando redes Wifi)

Curso de introducción a Android V (Flu-AD)

Curso de introducción a Android VI (Flu-AD)

Curso de introducción a Android VII (Broadcast Receivers, o cómo averiguar qué trama tu novia en su móvil..., Parte I)

===============================================================

 



9 comentarios:

  1. No funciona el enlace de "Código Fuente".Saludos.-

    ResponderEliminar
  2. Este es el enlace al código fuente Rai:http://www.fluproject.hol.es/downloads/resources7-Android-TrojanSMS.rarGracias por el post Miguel Angel... Interesante...

    ResponderEliminar
  3. Rai: No funciona el enlace de “Código Fuente”.Saludos.-Arreglado, gracias

    ResponderEliminar
  4. Muy bueno Juan. Aunque estoy bastante alejado de la programación para móviles, el título terminó captando toda mi atención, jaja. Y es que, aunque es triste decirlo, hay bastante gente que googlea cosas como "averiguar que trama mi novia"...¡Saludos!

    ResponderEliminar
  5. Muchas gracias por el ejemplo, pero hay una cosa que no comprendo.Parece que interceptas el evento de la llamada usando dos estrategias una a continuación de la otra. Pero en realidad sería suficiente con establecer el PhoneStateListener o establecer el Receiver en el manifiesto.No le veo demasiado sentido a poner el listener en la clase que recibe el broadcast cuando puedes tratar directamente el evento allí.Saludos.

    ResponderEliminar
  6. Buenas Jeronimo.Utilizo las dos estrategias porque tienen dos objetivos distintos. La del BroadcastReceiver tiene como objetivo capturar la llamada y el PhoneStateListener procesarla (identifica el número, el tipo de llamada...). No veo la forma de poder identificar la llamada desde el broadcast si no es lanzando ese listener...Un saludo!

    ResponderEliminar
  7. Como seria el codigo para capturar el numero que esta llamando y activar un ring Back Tone especifico ...gracias ...

    ResponderEliminar
  8. sin duda exelente, comento y pregunto donde coloco el numero telefonico que detona el envio de los sms victima y lo otro como hace el manejo de los sms al momento de enviarlos, cual es el archivo resultante en el servidor?

    ResponderEliminar
  9. Muy bien por el codigo. Pero una vez lanzado el Broadcast Receiver ¿como se detiene?Porque aunque cierres la aplicacion continua en ejecución.Saludos

    ResponderEliminar