Professional Documents
Culture Documents
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
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);
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:
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);
}
};