Titulo de la entradaTitulo de la entrada

Localización por GPS_A

“Desarrollo de Aplicaciones Móviles en Android”
Ejercicio Intermedio D: Localización por GPS
A.  Descripción

En    este    ejercicio,    introduciremos    cómo   funcionan    los    servicios    de   localización    en Android   y   explicaremos   cómo   conseguir   que   la    API   de   Android   nos   indique   nuestra   posición GPS.  Para   ello   crearemos    una  aplicación muy   sencilla   que  activa   y  desactiva   el  receptor   GPS   del
dispositivo Android, devolviendo la posición al usuario.
En   Android,   tenemos  dos  paquetes   de  servicios   relacionados   con  la   geo---localización,  el
mapa y la posición. Veremos cómo obtener nuestra posición de forma sencilla y rápida.

Hay    dos   posibles   fuentes   de   información   sobre   nuestra   posición,   el   receptor GPS    del dispositivo   o   la   red,  y    por  red  nos  referimos   a   la   red  que  esté   utilizando   el   dispositivo   para conectarse   a   internet.   Así,    el   dispositivo   nos puede  devolver   nuestra  posición   en  base  a   qué
antenas de  telefonía   móvil   está  utilizando,   triangulando   la   posición,   o  si   estamos utilizando   un
hotspot  Wi---Fi   cuya  posición   es  conocida,   obtenerla.   En   cualquier   caso,  cada  método  tiene   sus ventajas   y   sus  desventajas,   y   aunque en  un  principio   el   GPS  siempre   parece   el   mejor,   no  suele funcionar   bien   en   interiores,   y    un   uso  excesivo    drena  mucho    la   batería,   cosa   que   como programadores  debemos  siempre   tener   en  cuenta,  y  asegurarnos  de  que  nuestras  aplicaciones
cuiden de la batería lo máximo posible.
B. Implementación

B---1.  Interfaz
Para   empezar,   debemos   crear   un   nuevo   proyecto   y   añadirle    al   Layout dos   nuevos TextView, uno  para  mostrar  la   longitud   y  otro   para  la   latitud.   Justo   debajo,  añadiremos   un ToggleButton,  que   como   ya   sabemos   es   un   botón   con   una   peculiaridad:    posee   dos estados.    Puede   estar    activado    (el    método    isChecked() retorna    true)   o   desactivado (isChecked() retorna     false).    Lo     utilizaremos     para     activar     y     desactivar     el     GPS.
Naturalmente, a los dos TextView y al ToggleButton debemos asignarles una ID.

Ahora    pasamos   a   la   actividad.    Empezamos    añadiendo    un   método    privado    llamado
initConfig() al   que  llamaremos   en  el   constructor.  Luego   añadimos   tres   variables   privadas
a la  actividad,  dos  TextView  y  un ToggleButton,  y  añadimos  el  código  necesario  en
initConfig() para que estas variables hagan referencia a las vistas del main.xml.


B---2. La API de Localización
Antes de poder escribir código en el que solicitamos información al sistema operativo de nuestra  posición  (lo  cual  requiere  activar  las  funciones  de GPS),  necesitamos  que nuestra aplicación tenga los permisos necesarios, o Android nos cerrará la aplicación. Esto lo hacemos acudiendo al manifest, y añadiendo estas dos líneas al final, justo antes de que se cierre el tag
<manifest>:


<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION">
</uses-permission>
<uses-permission 
android:name="android.permission.ACCESS_COARSE_LOCATION">
</uses-permission>


Estos   permisos   nos  permiten   obtener   información   directa   del  chip  GPS (ACCESS_FINE_LOCATION) o de la red (ACCESS_COARSE_LOCATION ).  A partir de ahora todo el código es Java, así que volvemos a nuestra única actividad, y le añadimos éstas variables:

private LocationManager locMgr;
private LocationListener onLocationChange;
La primera variable, de tipo LocationManager, es la que nos permite tener acceso a objetos  de la  clase  Location,  que son  los  que nos  darán  las  coordenadas  de longitud  y latitud que queremos. Como sabemos, la API de Android se basa mucho en el patrón de diseño Observador, y esto también se extiende a la API de localización. Lo que queremos mostrar en
nuestra  aplicación  es siempre  la  última  posición  que obtiene  el  dispositivo  a través  del receptor, por lo que tenemos que registrarnos como observador, y eso lo hacemos a través del LocationListener.
Volvamos  al  initConfig().  Tras  inicializar  los  TextView y el  ToggleButton, inicializaremos el LocationManager y el LocationListener, con este código:

locMgr = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
onLocationChange = new LocationListener() {
public void onLocationChanged(android.location.Location location) { longitutdeTextView.setText("Longitud: " + location.getLongitude()); latitudeTextView.setText("Latitud: " + location.getLatitude()); Log.i(LOG_TAG, "Received Location update.");
}
public void onProviderDisabled(String provider) {
Log.i(LOG_TAG, "Location provider " + provider + " has been disabled.");
}
public void onProviderEnabled(String  provider) {
Log.i(LOG_TAG, "Location provider " + provider + " has been enabled.");

}

public void onStatusChanged(String provider, int status, Bundle extras) {
Log.i(LOG_TAG, "Location provider " + provider + " has changed status to "
+ status);
}
};


NOTA:   Suponemos   que  el  alumno   ya  está  familiarizado   con  el  uso  del   LogCat y   de  sus  funciones.
No   podemos   crear   una   nueva   instancia    de   LocationManager,  sino    que   debemos pedírselo   al   sistema,   y  eso   lo   hacemos  mediante   la   llamada   getSystemService(). Luego inicializamos     el     LocationListener,   que    actuará    cuando    lo    registremos.     La     llamada onLocationChanged() se   produce   cuando   el    dispositivo    consigue    un   nuevo   dato   sobre nuestra   posición,   el   onProviderDisabled() es   llamado   cuando  pedimos   que   Android   nos dé   información    de   localización    de   un   proveedor   que   está   deshabilitado    por   el    usuario    (por ejemplo,   el   GPS   está   desactivado),   y  lo   contrario   en  el   caso  del   onProviderEnabled().   El
último  método,  onStatusChanged(),  es  llamado  cuando  hay  cambios  respecto  al
proveedor  de  servicio   de  localización,   por  ejemplo,   al   volverse   no  disponible,   al   volver   a  estar disponible,   etc.  A   veces  también   provee  de  información   extra   en  el   Bundle, como  el   número
de satélites utilizados para obtener la posición GPS.
Podemos  ver  que,  en  el   método   que   más  nos  interesa,   el   onLocationChanged(), actualizamos    el   texto   que  se   muestra  en   los   TextView con    la    localización   de   la   que   nos provee  Android.   El   objeto   Location provee  de  más  información,   y  animamos   a  los   alumnos
a indagar un poco y a descubrir qué más nos puede ofrecer.
Ahora    tenemos   el    segmento   de   código    más   importante,    el    del    ToggleButton.  Lo que    queremos      es    que    cuando     el    usuario      active     el     botón,    registremos       nuestro LocationListener con   el    proveedor   del    servicio    de   localización    por   GPS    para   que   nos avise   en  cuanto  tenga   una  nueva   posición  (es   decir,  que  llame   a  los   métodos correspondientes
de    onLocationChange),   y    que    cuando    desactivemos     el     botón,    dejemos     de    solicitar
posiciones   por  GPS   para  ahorrar  batería.   Si   nosotros  éramos  los   únicos   solicitando   información GPS,    Android    desactivará    el    chip    automáticamente    al    decirle    que   ya   no   queremos   más información sobre nuestra posición.
Dado   que   todos   somos   humanos,   tenemos   que   programar   para   el    peor   caso.   ¿Qué
ocurre    si   el   usuario   pulsa   el   botón  Atrás   sin   haber  vuelto   a   tocar    el   ToggleButton para decirle   a  Android   que   deje   de   solicitar   información   por  GPS?   Android   mantendrá   el   chip   GPS activo    pensando   que   hay   una   aplicación   solicitando    información,    y   dado   que   aún   estamos registrados   en  el  listener,   Android   no  podrá liberar   la   memoria   de  nuestra aplicación,   drenando
la   batería   hasta  que  logremos   matar  el   proceso   o  apaguemos    el   teléfono.   Debemos   ser  muy
precavidos    con   esto.   Éste    es   el    código    del    ToggleButton, que   ponemos   al    final   del
initConfig():

toggleButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (toggleButton.isChecked()){
locMgr.requestLocationUpdates(LocationManager.GPS_PROVIDER,
0, 0f, onLocationChange);
}
else {
locMgr.removeUpdates(onLocationChange);
}
}
});

NOTA:    A   partir   de  este  código,   los  alumnos   deben  ser  capaces de  añadir   a  la  actividad   el   método  onDestroy()   con  las
llamadas   necesarias,   la   de   la   clase    padre   y   la    que   informa    al   sistema   operativo    que   ya   no   queremos  más  información    de
localización.
En  el   onClick(),   estamos   registrando    nuestro   LocationListener (onLocationChange)  para   recibir    información    sobre   nuestra    posición    GPS.    En    vez   de utilizar   el    GPS,   también   podríamos   haber  utilizado   la   red  (de   telefonía   o  Wi---Fi,    eso  lo   decide Android) cambiando el primer argumento por LocationManager.NETWORK_PROVIDER. En
el   último   argumento  le   decimos   cuál   es  nuestro  LocationListener asociado   a  la   petición, y  luego   quedan  el   segundo  y  el   tercer  argumento,  los   relacionados   directamente   con  el   gasto de  la   batería.   El    segundo   argumento   es  el   tiempo   mínimo,   en  milisegundos,   que  debe  pasar antes  de  que  Android   vuelva  a  solicitar   nuestra posición   GPS.  Por   ejemplo,    un  valor   de  10000
significaría     que    como    poco,    pasarán    diez     segundos    entre    petición     y    petición.     El      tercer
argumento   es   la   distancia    mínima,    en   metros,   entre   petición    y   petición.    Nosotros   hemos solicitado   que  Android   nos  diga   nuestra  posición   lo   antes   posible,   sin   descanso,  prácticamente en   tiempo   real,   lo   cual    es   la   configuración    que  más  consume    la   batería.   No    se   recomienda realizar   peticiones   con   intervalo    inferior   a   1   minuto   en   aplicaciones    de   uso  diario.    Por
supuesto,   hay   excepciones;    por   ejemplo,   en   un   navegador   GPS    para   el   coche,   se   presupone
que  el   usuario   comprará   el   adaptador para  darle   corriente   al   dispositivo   Android,   ya   que  lo   que
prima   en   este   caso   de   uso  es   la    fiabilidad    de   la    información    al    conducir    y   no   el   consumo
energético.
Por    último,    queremos  mostrar  un   dato   al    usuario   para  empezar,    el   de   la    última posición   conocida   por  el   sistema,   sea  de   GPS    o   de   la   red.  Esto   lo   haremos  con   el   siguiente código, que ya cierra el método initConfig():

android.location.Location location = locMgr.getLastKnownLocation(LocationManager.GPS_PROVIDER); if (location == null)
location =
locMgr.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
longitutdeTextView.setText("Longitud: " + location.getLongitude());
latitudeTextView.setText("Latitud: " + location.getLatitude());
}
else {
longitutdeTextView.setText("Longitud: No disponible");
latitudeTextView.setText("Latitud: No disponible");
}

Como    vemos,    lo    que   hacemos   es   pedirle   a   Android   cuál   es   la   última    posición   que conoce   a   través   del   GPS,   y    si    no  conoce    ninguna   (devolvería   null),   le   preguntamos    por el proveedor   de   red,  y    si    aún  así    no   tenemos  una  posición,    mostramos que   no   tenemos  la información   disponible.   Podemos  intentar   darle   las   posiciones   al   emulador   con   el   DDMS,    sin
embargo,    lo   más  divertido   es   instalar   esta   aplicación    en   un   dispositivo    Android   y    caminar,
viendo cómo van cambiando los datos.


C.  Conclusión
La  geo---localización  es  una de las  cualidades  más  solicitadas  de todo  smartphone,  y
sobre  todo,   de   cualquier   plataforma   móvil.   Es   un  recurso  que   podemos  aplicar   prácticamente en todos  los  aspectos  de diseño  en nuestras  aplicaciones,  y  lo  más  importante,  aún está pendiente de ser descubierto por la inmensa mayoría de usuarios con teléfonos móviles.
En este ejercicio hemos introducido la API de localización, pero hay muchísimas cosas relacionadas  con  el entorno  de un dispositivo  Android  que los  alumnos  están  todavía  por descubrir, como el acelerómetro, la brújula digital, etc.