Vous êtes sur la page 1sur 6

Localizacin geogrfica

Introduccin
La localizacin geogrfica en Android es uno de esos servicios que, a pesar de requerir
poco cdigo para ponerlos en marcha, no son para nada intuitivos ni fciles de llegar a
comprender por completo. Y esto no es debido al diseo de la plataforma Android en
s, sino a la propia naturaleza de este tipo de servicios. Por un lado, existen multitud de
formas de obtener la localizacin de un dispositivo mvil, aunque la ms conocida y
popular es la localizacin por GPS, tambin es posible obtener la posicin de un
dispositivo por ejemplo a travs de las antenas de telefona mvil o mediante puntos
de acceso Wi-Fi cercanos, y todos cada uno de estos mecanismos tiene una precisin,
velocidad y consumo de recursos distinto. Por otro lado, el modo de funcionamiento
de cada uno de estos mecanismos hace que su utilizacin desde nuestro cdigo no sea
todo lo directa e intuitiva que se deseara. Iremos comentando todo esto a lo largo del
artculo, pero vayamos paso a paso.

Mecanismos de localizacin
Lo primero que debe conocer una aplicacin que necesite obtener la localizacin
geogrfica es qu mecanismos de localizacin (proveedores de localizacin, o location
providers) tiene disponibles en el dispositivo. Como ya hemos comentado, los ms

comunes sern el GPS y la localizacin mediante la red de telefona, pero podran


existir otros segn el tipo de dispositivo.
La forma ms sencilla de saber los proveedores disponibles en el dispositivo es
mediante una llamada al mtodo getAllProviders() de la clase LocationManager, clase
principal en la que nos basaremos siempre a la hora de utilizar la API de localizacin de
Android. Para ello, obtendremos una referencia al location manager llamando a
getSystemService(LOCATION_SERVICE), y posteriormente obtendremos la lista de
proveedores mediante el mtodo citado para obtener la lista de nombres de los
proveedores:
LocationManager locManager =
(LocationManager)getSystemService(LOCATION_SERVICE);
List<String> listaProviders = locManager.getAllProviders();

Una vez obtenida la lista completa de proveedores disponibles podramos acceder a las
propiedades de cualquiera de ellos (precisin, coste, consumo de recursos, o si es
capaz de obtener la altitud, la velocidad, ). As, podemos obtener una referencia al
provider mediante su nombre llamando al mtodo getProvider(nombre) y
posteriormente utilizar los mtodos disponibles para conocer sus propiedades, por
ejemplo getAccuracy() para saber su precisin (tenemos disponibles las constantes
Criteria.ACCURACY_FINE para precisin alta, y Criteria.ACCURACY_COARSE para
precisin media), supportsAltitude() para saber si obtiene la altitud, o
getPowerRequirement() para obtener el nivel de consumo de recursos del proveedor.
Por tal motivo la aplicacin tiene que registrar en la aplicacin los siguientes permisos:
<uses-permission
android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION" />
La lista completa de mtodos para obtener las caractersticas de un proveedor se
puede consultar en la documentacin oficial de la clase LocationProvider.
LocationManager locManager =
(LocationManager)getSystemService(LOCATION_SERVICE);
List<String> listaProviders = locManager.getAllProviders();
LocationProvider provider =
locManager.getProvider(listaProviders.get(0));
int precision = provider.getAccuracy();
boolean obtieneAltitud = provider.supportsAltitude();
int consumoRecursos = provider.getPowerRequirement();

Al margen de esto, hay que tener en cuenta que la lista de proveedores devuelta por el
mtodo getAllProviders() contendr todos los proveedores de localizacin conocidos
por el dispositivo, incluso si stos no estn permitidos (segn los permisos de la
aplicacin) o no estn activados, por lo que esta informacin puede que no nos sea de
mucha ayuda.

Mejor proveedor
Android proporciona un mecanismo alternativo para obtener los proveedores que
cumplen unos determinados requisitos entre todos los disponibles. Para ello nos
permite definir un criterio de bsqueda, mediante un objeto de tipo Criteria, en el que
podremos indicar las caractersticas mnimas del proveedor que necesitamos utilizar
(podis consultar la documentacin oficial de la clase Criteria para saber todas las
caractersticas que podemos definir). As, por ejemplo, para buscar uno con precisin
alta y que nos proporcione la altitud definiramos el siguiente criterio de bsqueda:
Criteria req = new Criteria();
req.setAccuracy(Criteria.ACCURACY_FINE);
req.setAltitudeRequired(true);

Tras esto, podremos utilizar los mtodos getProviders() o getBestProvider() para


obtener la lista de proveedores que se ajustan mejor al criterio definido o el proveedor
que mejor se ajusta a dicho criterio, respectivamente. Adems, ambos mtodos
reciben un segundo parmetro que indica si queremos que slo nos devuelvan
proveedores que estn activados actualmente. Veamos cmo se utilizaran estos
mtodos:
//Mejor proveedor por criterio
String mejorProviderCrit = locManager.getBestProvider(req, false);
//Lista de proveedores por criterio
List<String> listaProvidersCrit = locManager.getProviders(req, false);

El proveedor est disponible y activado?


Aunque, como ya hemos visto, tenemos la posibilidad de buscar dinmicamente
proveedores de localizacin segn un determinado criterio de bsqueda, es bastante
comn que nuestra aplicacin est diseada para utilizar uno en concreto, por ejemplo
el GPS, y por tanto necesitaremos algn mecanismo para saber si ste est activado o
no en el dispositivo. Para esta tarea, la clase LocationManager nos proporciona otro
mtodo llamado isProviderEnabled() que nos permite hacer exactamente lo que
necesitamos. Para ello, debemos pasarle el nombre del provider que queremos
consultar. Para los ms comunes tenemos varias constantes ya definidas:

LocationManager.NETWORK_PROVIDER. Localizacin por la red de telefona.


LocationManager.GPS_PROVIDER. Localizacin por GPS.
De esta forma, si quisiramos saber si el GPS est habilitado o no en el dispositivo (y
actuar en consecuencia), haramos algo parecido a lo siguiente:

//Si el GPS no est habilitado


if (!locManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
mostrarAvisoGpsDeshabilitado();
}

En el cdigo anterior, verificamos si el GPS est activado y en caso negativo mostramos


al usuario un mensaje de advertencia. Este mensaje podramos mostrarlo
sencillamente en forma de notificacin de tipo toast, pero despus veremos cmo
podemos, adems de informar de que el GPS est desactivado, invitar al usuario a
activarlo dirigindolo automticamente a la pantalla de configuracin del dispositivo.

Obtener la localizacin
Una vez que sabemos que nuestro proveedor de localizacin favorito est activado, ya
estamos en disposicin de intentar obtener nuestra localizacin actual. Y aqu es
donde las cosas empiezan a ser menos intuitivas. Para empezar, en Android no existe
ningn mtodo del tipo obtenerPosicinActual(). Obtener la posicin a travs de un
dispositivo de localizacin como por ejemplo el GPS no es una tarea inmediata, sino
que puede requerir de un cierto tiempo de procesamiento y de espera, por lo que no
tendra sentido proporcionar un mtodo de ese tipo.
Si buscamos entre los mtodos disponibles en la clase LocationManager, lo ms
parecido que encontramos es un mtodo llamado getLastKnownLocation(String
provider), que como se puede suponer por su nombre, nos devuelve la ltima posicin
conocida del dispositivo devuelta por un provider determinado. Es importante
entender esto: este mtodo NO devuelve la posicin actual, este mtodo NO solicita
una nueva posicin al proveedor de localizacin, este mtodo se limita a devolver la
ltima posicin que se obtuvo a travs del proveedor que se le indique como
parmetro. Y esta posicin se pudo obtener hace pocos segundos, hace das, hace
meses, o incluso nunca (si el dispositivo ha estado apagado, si nunca se ha activado el
GPS, ). Por tanto, cuidado cuando se haga uso de la posicin devuelta por el mtodo
getLastKnownLocation().
Entonces, de qu forma podemos obtener la posicin real actualizada? Pues la forma
correcta de proceder va a consistir en algo as como activar el proveedor de
localizacin y suscribirnos a sus notificaciones de cambio de posicin. O dicho de otra

forma, vamos a suscribirnos al evento que se lanza cada vez que un proveedor recibe
nuevos datos sobre la localizacin actual. Y para ello, vamos a darle previamente unas
indicaciones (que no ordenes, ya veremos esto en el prximo artculo) sobre cada
cuanto tiempo o cada cuanta distancia recorrida necesitaramos tener una
actualizacin de la posicin.
Todo esto lo vamos a realizar mediante una llamada al mtodo
requestLocationUpdates(), al que deberemos pasar 4 parmetros distintos:

Nombre del proveedor de localizacin al que nos queremos suscribir.


Tiempo mnimo entre actualizaciones, en milisegundos.
Distancia mnima entre actualizaciones, en metros.
Instancia de un objeto LocationListener, que tendremos que implementar
previamente para definir las acciones a realizar al recibir cada nueva
actualizacin de la posicin.

Tanto el tiempo como la distancia entre actualizaciones pueden pasarse con valor 0, lo
que indicara que ese criterio no se tendr en cuenta a la hora de decidir la frecuencia
de actualizaciones. Si ambos valores van a cero, las actualizaciones de posicin se
recibirn tan pronto y tan frecuentemente como estn disponibles. Adems, como ya
hemos indicado, es importante comprender que tanto el tiempo como la distancia
especificadas se entendern como simples indicaciones o pistas para el proveedor,
por lo que puede que no se cumplan de forma estricta. En el prximo artculo
intentaremos ver esto con ms detalle para entenderlo mejor. Por ahora nos basta con
esta informacin.
En cuanto al listener, ste ser del tipo LocationListener y contendr una serie de
mtodos asociados a los distintos eventos que podemos recibir del proveedor:
onLocationChanged(location). Lanzado cada vez que se recibe una
actualizacin de la posicin.
onProviderDisabled(provider). Lanzado cuando el proveedor se deshabilita.
onProviderEnabled(provider). Lanzado cuando el proveedor se habilita.
onStatusChanged(provider, status, extras). Lanzado cada vez que el proveedor
cambia su estado, que puede variar entre OUT_OF_SERVICE,
TEMPORARILY_UNAVAILABLE, AVAILABLE.
Por nuestra parte, tendremos que implementar cada uno de estos mtodos para
responder a los eventos del proveedor, sobre todo al ms interesante,
onLocationChanged(), que se ejecutar cada vez que se recibe una nueva localizacin
desde el proveedor. Veamos un ejemplo de cmo implementar un listener de este
tipo:
locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
muestraPosicion(location);

}
public void onProviderDisabled(String provider){
lblEstado.setText("Provider OFF");
}
public void onProviderEnabled(String provider){
lblEstado.setText("Provider ON");
}
public void onStatusChanged(String provider, int status,
Bundle extras){
Log.i("LocAndroid", "Provider Status: " + status);
lblEstado.setText("Provider Status: " + status);
}
};

Vous aimerez peut-être aussi