Miguel Angel
Este usuario no ha compartido ninguna información biográfica
Entradas de Miguel Angel
Curso de introducción a Android VIII (Broadcast Receivers con GPS, o cómo saber si tu novia dice la verdad cuando se va con sus amigas…, Parte II)
5 dic
En esta entrada vamos a seguir aprovechando la funcionalidad que nos brinda la clase Broadcast Receiver. Esta vez aprovecharemos para explicar cómo manejar el GPS en Android con el fin de obtener la coordenada del usuario, sin que éste sea consciente de ello, mediante la famosa llamada perdida.
A modo de recordatorio, vamos a ver por encima cómo era la estructura del programa que hicimos en la entrada anterior para aprovechar las partes que nos interesan y añadirle la parte del GPS.
Main.java: Actividad “Hola Mundo” que lanza el Broadcast Receiver.
TrojanCall.java: Broadcast Receiver que atrapa las llamadas entrantes que se producen en el teléfono móvil y las filtra y procesa mediante un listener MyPhoneStateListener.
MyPhoneStateListener.java: Implementación de PhoneStateListener para recoger el estado de una llamada entrante y poder filtrarla.
A nuestra clase Main.java vamos a añadirle una función que inicialice el módulo GPS y que lance un listener para que registre la posición del usuario cada 20 segundos. Nuestro Main.java quedaría así:
Si nos fijamos en el código, se han añadido dos partes fundamentales en él: una variable global donde se almacenará la posición del usuario y un método para inicializar y recoger la posición mediante GPS.
Para recoger la posición GPS, lo primero que hacemos es obtener una instancia del manejador GPS del móvil. Una vez tenemos referenciado el manejador GPS procedemos a inicializar la variable loc mediante la última posición que hayamos obtenido del proveedor que le indiquemos al método getLastKnowLocation. En nuestro caso, hemos elegido que el proveedor sea la red telefónica LocationManager.NETWORK_PROVIDER, pero podemos elegir entre los siguientes:
- NETWORK_PROVIDER: Determina la posición del usuario basándose en la celda telefónica en la que se encuentre y, si dispone de conexión wifi, de la combinación del punto de acceso al que se encuentre conectado.
- GPS_PROVIDER: Determina la posición el usuario usando satélites GPS. Dependiendo de las condiciones en las que se encuentre el usuario puede tardar más tiempo en devolver una posición buena, por ejemplo, si se encuentra en espacios interiores.
- PASSIVE_PROVIDER: Determina la posición del usuario basándose en la recogida de posiciones de otras aplicaciones. Por ejemplo, si Google Latitude necesita recoger la posición GPS para enviarla a un servicio web, este proveedor se aprovecha de esa acción para obtener la coordenada. Si necesitamos saber la posición de un usuario en un determinado momento, este es el proveedor menos adecuado. Sin embargo, este es el proveedor que menos batería gasta.
Una vez indicado el proveedor lanzamos un listener en una clase que monitorice lo que está pasando en el GPS del móvil. Cuando lanzamos el listener LocationListener debemos añadir los siguientes métodos:
- onLocationChanged: Este método se activa cada vez que se cumple una condición que indicaremos más adelante mediante el método requestLocationUpdates. El método requestLocationUpdates recibirá un parámetro de tiempo y otro de distancia, de esta forma onLocationChanged se activará siempre que haya pasado más tiempo y más distancia que la indicada.
-
onProviderEnabled: Este método se activa al activarse el proveedor indicado en requestLocationUpdates.
- onProviderDisabled: Este método se activa al desactivarse el proveedor indicado en requestLocationUpdates.
- onStatusChanged: Este método se activa al cambiar el estado del proveedor indicado en requestLocationUpdates.
Después de definir el listener, lo lanzamos mediante el método requestLocationUpdates con la condición de que registre la posición siempre que hayan pasado 20 segundos y más de 0 metros. Le indicamos también que utilice como proveedor NETWORK_PROVIDER.
Vamos a pasar ahora a la clase que recibe y envía la coordenada GPS a un servidor. La clase que se encarga de esta tarea es MyPhoneStateListener.java y tiene la siguiente pinta:
Como podemos observar seguimos el mismo procedimiento que en la entrada anterior. Simplemente hemos añadido un método privado para obtener las coordenadas moduleGPSPosition() que obtiene la latitud, la longitud y la precisión del usuario (para poder fiarnos de la coordenada) mediante los métodos getLatitude(), getLongitude() y getAccuracy() de la clase Location. Una vez obtenida la coordenada la enviamos al servidor mediante el método sendGPSinfo().
Por último, hay que añadir los permisos al AndroidManifest.xml, ya que para el GPS tenemos algunos permisos nuevos. El fichero quedaría de la siguiente manera:
Aquí os dejo un ejemplo de la salida del programa donde se ve claramente que me han pillado en la cafetería de la uni echando unas cerves… y yo que le había dicho a mi jefe que estaba currando!!
Y esto es todo, adjuntamos el código como siempre y espero que os guste! Saludoss!
Curso de introducción a Android VII (Broadcast Receivers, o cómo averiguar qué trama tu novia en su móvil…, Parte I)
10 nov
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
)
¿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.
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.
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.
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:
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)
===============================================================
.png)














