miércoles, 3 de diciembre de 2014

Profundizando en la Localización Geográfica - Android



En el apartado anterior comentamos los pasos básicos necesarios para construir aplicaciones que accedan a la posición geográfica del dispositivo. Ya comentamos algunas particularidades de este servicio de la API de Android, pero dejamos en el tintero algunas aclaraciones más detalladas y un tema importante y fundamental, como es la depuración de este tipo de aplicaciones que manejan datos de localización. En este nuevo apartado intentaré abarcar todos estos temas.

Como base para este apartado voy a utilizar la misma aplicación de ejemplo que construimos en la anterior entrega, haciendo tan sólo unas pequeñas modificaciones:
* Reduciremos el tiempo entre actualizaciones de posición a la mitad, 15 segundos, para evitar tiempos de espera demasiado largos durante la ejecución de la aplicación.
* Generaremos algunos mensajes de log en puntos clave del código para poder estudiar con más detalle el comportamiento de la aplicación en tiempo de ejecución.
La generación de mensajes de log resulta ser una herramienta perfecta a la hora de depurar aplicaciones del tipo que estamos tratando, ya que en estos casos el código no facilita demasiado la depuración típica paso a paso que podemos realizar en otras aplicaciones.

En nuestro caso de ejemplo sólo vamos a generar mensajes de log cuando ocurran dos circunstancias:

> Cuando el proveedor de localización cambie de estado, evento onStatusChanged(), mostraremos el nuevo estado.
> Cuando se reciba una nueva actualización de la posición, evento onLocationChanged(), mostraremos las nuevas coordenadas recibidas.

Nuestro código quedaría por tanto tal como sigue:


Si ejecutamos en este momento la aplicación en el emulador y pulsamos el botón "Activar" veremos cómo los cuadros de texto se rellenan con la información de la última posición conocida (si existe), pero sin embargo estos datos no cambiarán en ningún momento ya que por el momento el emulador de Android tan sólo cuenta con esa información. ¿Cómo podemos simular la actualización de la posición del dispositivo para ver si nuestra aplicación responde exactamente como esperamos?

Pues bien, para hacer esto tenemos varias opciones. La primera de ellas, y la más sencilla, es el envío manual de una nueva posición al emulador de Android, para simular que éste hubiera cambiado su localización. Esto se puede realizar desde la perspectiva de DDMS, en la pestaña Emulator Control, donde podemos encontrar una sección llamada Location Controls, mostrada en la imagen siguiente:


Con estos controles podemos enviar de forma manual al emulador en ejecución unas nuevas coordenadas de posición, para simular que éstas se hubieran recibido a través del proveedor de localización utilizado. De esta forma, si introducimos unas coordenadas de longitud y latitud y pulsamos el botón "Send" mientras nuestra aplicación se ejecuta en el emulador, esto provocará la ejecución del evento onLocationChanged() y por consiguiente se mostrarán estos mismos datos en sus controles correspondientes de la interfaz, como vemos en la siguiente captura de pantalla:


Por supuesto, si hacemos nuevos envíos de coordenadas desde Eclipse veremos cómo ésta se va actualizando en nuestra aplicación sin ningún tipo de problemas. Sin embargo este método de manual no resulta demasiado adecuado ni cómodo para probar toda la funcionalidad de nuestra aplicación, por ejemplo la actualización de posición cada 15 segundos.

Por ello, Android proporciona otro método algo menos manual de simular cambios frecuentes de posición para probar nuestras aplicaciones. Este método consiste en proporcionar, en vez de una sola coordenada cada vez, una lista de coordenadas que se irán enviando automáticamente al emulador una tras otra a una determinada velocidad, de forma que podamos simular que el dispositivo se mueve constantemente y que nuestra aplicación responde de forma correcta y en el momento adecuado a esos cambios de posición. Y esta lista de coordenadas se puede proporcionar de dos formas distintas, en formato GPX o como fichero KML. Ambos tipos de fichero son ampliamente utilizados por aplicaciones y dispositivos de localización, como GPS, aplicaciones de cartografía y mapas, etc. Los ficheros KML podemos generarlos por ejemplo a través de la aplicación Google Earth o manualmente con cualquier editor de texto, pero recomiendo consultar los dos enlaces anteriores para obtener más información sobre cada formato. Para este ejemplo, yo he generado un fichero KML de muestra con una lista de 1000 posiciones geográficas al azar.

Para utilizar este fichero como fuente de datos para simular cambios en la posición del dispositivo, accedemos nuevamente a los Location Controls y pulsamos sobre la pestaña GPX o KML, según el formato que hayamos elegido, que en nuestro caso será KML. Pulsamos el botón "Load KML…" para seleccionar nuestro fichero y veremos la lista de coordenadas como en la siguiente imagen:


Una vez cargado el fichero, tendremos disponibles los cuatro botones inferiores para (de izquierda a derecha):

* Avanzar automáticamente por la lista.
* Ir a la posición anterior de la lista de forma manual.
* Ir a la posición siguiente de la lista de forma manual.
* Establecer la velocidad de avance automático.

Entendido esto, vamos a utilizar la lista de posiciones para probar nuestra aplicación. Para ello, ejecutamos la aplicación en el emulador, pulsamos nuestro botón "Activar" para comenzar a detectar cambios de posición, y pulsamos el botón de avance automático (botón verde) que acabamos de comentar

Llegados a este punto pueden ocurrir varias cosas, dependiendo del dispositivo o el emulador que estemos utilizando, y por supuesto de la versión de Android sobre la que ejecutemos el ejemplo. O bien todo funciona según lo esperado y empezamos a recibir una lectura de posición cada 15 segundos, o bien pueden aparecernos varias actualizaciones con una frecuencia mucho menor que el periodo especificado. La primera situación parece lógica, es lo que habíamos pedido. ¿Pero cómo es posible la segunda? ¿No habíamos configurado el LocationListener para obtener actualizaciones de posición cada 15 segundos? ¿Por qué llegan más actualizaciones de las esperadas? Antes de contestar a esto, dejemos por ejemplo que la aplicación se ejecute durante un minuto sobre un emulador con versión 2.2 de Android (API 8). Tras unos 60 segundos de ejecución detenemos la captura de posiciones pulsando nuestro botón "Desactivar".

Ahora vayamos a la ventana de log del DDMS y veamos los mensajes de log ha generado nuestra aplicación para intentar saber qué ha ocurrido. En mi caso, los mensajes generados son los siguientes (en tu caso deben ser muy parecidos):


Estudiemos un poco este log. Si observamos las marcas de fecha hora vemos varias cosas:

> Un primer grupo de actualizaciones entre las 10:50:37 y las 10:50:47, con 8 lecturas.
> Un segundo grupo de actualizaciones entre las 10:51:02 y las 10:51:13, con 11 lecturas. 198
> Un tercer grupo de actualizaciones entre las 10:51:28 y las 10:51:38, con 10 lecturas.
> Entre cada grupo de lecturas transcurren aproximadamente 15 segundos.
> Los grupos están formados por un número variable de lecturas.

Por tanto ya podemos sacar algunas conclusiones. Indicar al location listener una frecuencia de 15 segundos entre actualizaciones no quiere decir que vayamos a tener una sola lectura cada 15 segundos, sino que al menos tendremos una nueva con dicha frecuencia. Sin embargo, como podemos comprobar en los logs, las lecturas se recibirán por grupos separados entre sí por el intervalo de tiempo indicado.

Más conclusiones, ahora sobre el estado del proveedor de localización. Si buscamos en el log los momentos donde cambia el estado del proveedor vemos dos cosas importantes:

>Después de recibir cada grupo de lecturas el proveedor pasa a estado 1 (TEMPORARILY_UNAVAILABLE).

>Tras empezar a recibir de nuevo lecturas el proveedor pasa a estado 2 (AVAILABLE)

Estos cambios en el estado de los proveedores de localización pueden ayudarnos a realizar diversas tareas. Un ejemplo típico es utilizar el cambio de estado a 1 (es decir, cuando se ha terminado de recibir un grupo de lecturas) para seleccionar la lectura más precisa del grupo recibido, algo especialmente importante cuando se están utilizando varios proveedores de localización simultáneamente, cada uno con una precisión distinta.

A modo de resumen, en este apartado hemos visto cómo podemos utilizar las distintas herramientas que proporciona la plataforma Android y el entorno de desarrollo Eclipse para simular cambios de posición del dispositivo durante la ejecución de nuestras aplicaciones en el emulador. También hemos visto cómo la generación de mensajes de log puede ayudarnos a depurar este tipo de aplicaciones, y finalmente hemos utilizado esta herramienta de depuración para entender mejor el funcionamiento de los location listener y el comportamiento de los proveedores de localización.



Saludos compañeros, aprovechen la información.








No hay comentarios:

Publicar un comentario en la entrada