Bienvenidos sean a este post, hoy hablaremos sobre la localizacion gracias a nuestros dispositivos para ello Android utiliza dos medios:
- gps, utiliza los satelites de ubicacion mundial pero necesita una vision directa con los mismos y hoy practicamente cualquier dispositivo posee uno
- conexion, por medio de la conexion de wi-fi y de datos logra ubicarte cuando no tiene la conexion por gps.
El dispositivo tiene la particularidad de poder alternar entre una forma u otra para poder devolvernos la ubicacion, siempre mas exacto va a ser por medio del gps pero por ejemplo, si nosotros entendemos que se quedo sin señal de gps se podria considerar que entro en un edificio y ese edificio puede ser el trabajo de la persona y por este motivo setear automaticamente el telefono en vibracion.
Nota: Esto funcionara siempre que permitamos conocer nuestra Ubicacion habilitando la opcion en el dispositivo
Con esta posibilidad como ejemplo pasemos a ver como trabaja el API de localizacion mediante la siguiente app, para ello crearemos una nueva en Android Studio con las siguientes caracteristicas:
- Application Name: Localizacion
- Domain Company: example.org
- API (Phone and Tablet): 14
- Add an Activity: Empty Activity
Con nuestra app creada procedamos a hacer las modificaciones, nuestra primera modificacion sera en el archivo activity_main.xml donde reemplazaremos su codigo por el siguiente:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/salida"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</ScrollView>
Lo mas notorio de este codigo es el ScrollView que vamos a utilizar para poder ver continuamente todas las estadisticas que nos devuelva la app, nuestra siguiente modificacion sera en nuestra clase MainActivity y para ello reemplazaremos su codigo actual con el siguiente:
package org.example.localizacion;
import android.app.Activity;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends Activity
implements LocationListener {
private static final long TIEMPO_MIN = 10 * 1000;
private static final long DISTANCIA_MIN = 5;
private static final String[] A = {"n/d","preciso","impreciso"};
private static final String[] P = {"n/d","bajo","medio","alto"};
private static final String[] E = { "fuera de servicio",
"temporalmente no disponible","disponible" };
private LocationManager manejador;
private String proveedor;
private TextView salida;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
salida = (TextView) findViewById(R.id.salida);
manejador = (LocationManager) getSystemService(
LOCATION_SERVICE);
log("Proveedores de localizacion: \n");
muestraProveedores();
Criteria criterio = new Criteria();
criterio.setCostAllowed(false);
criterio.setAltitudeRequired(false);
criterio.setAccuracy(Criteria.ACCURACY_FINE);
proveedor = manejador.getBestProvider(criterio, true);
log("Mejor proveedor: " + proveedor + "\n");
log("Comenzamos con la ultima localizacion conocida: ");
Location localizacion = manejador.getLastKnownLocation(
proveedor);
muestraLocaliz(localizacion);
}
}
Si bien hasta ahora nuestro codigo no va a funcionar vamos a analizar esta parte, primero crearemos varias constantes, la primera va a ser TIEMPO_MIN, la cual almacenara el tiempo minimo, ese valor equivale a 10 segundos porque esta API como la mayoria se maneja en milisegundos, la siguiente constante DISTANCIA_MIN tiene un valor de 5 metros, luego tendremos tres constantes de tipo Array donde almacenaremos varios estados pero esto lo veremos un poco mas adelante, luego crearemos las tres variables para generar los enlaces con los elementos del layout y poder obtener los datos necesarios, en el metodo onCreate() crearemos nuestro vinculo con el elemento TextView llamado salida, luego a manejador lo diremos que obtenga el servicio LOCATION_SERVICE, luego llamamos a muestraProveedores() pero todavia no existe este metodo asi que lo veremos luego, despues crearemos un objeto llamado criterio derivado de la clase Criteria, luego setearemos como falsa setCostAllowed() y setAltitudeRequired() lo cual evitara que necesitemos esos datos para ser utilizado, despues setearemos su precision por medio de ACCURACY_FINE, nuestro siguiente linea se encarga de almacenar el valor de nuestro mejor proveedor, despues por medio de la funcion log(), todavia no existe este metodo, mostraremos los datos obtendios en pantalla, y por ultimo mostraremos la localizacion.
Con esto terminamos de ver el bloque recien ingresado, agregaremos los metodos para el ciclo de vida y los metodos faltantes:
@Override
protected void onResume(){
super.onResume();
manejador.requestLocationUpdates(proveedor,
TIEMPO_MIN,DISTANCIA_MIN,this);
}
@Override
protected void onPause(){
super.onPause();
manejador.removeUpdates(this);
}
public void onLocationChanged(Location location){
log("Nueva localizacion: ");
muestraLocaliz(location);
}
public void onProviderDisabled(String proveedor){
log("Proveedor deshabilitado: " + proveedor + "\n");
}
public void onProviderEnabled(String proveedor){
log("Proveedor habilitado: " + proveedor + "\n");
}
public void onStatusChanged(String proveedor,
int estado, Bundle extras){
log("Cambia estado proveedor: " + proveedor + ", estado: " +
E[Math.max(0,estado)] + " extras= " + extras + "\n");
}
private void log(String cadena){
salida.append(cadena + "\n");
}
private void muestraLocaliz(Location localizacion){
if (localizacion == null)
log("Localizacion desconocida\n");
else
log(localizacion.toString() + "\n");
}
private void muestraProveedores(){
log("Proveedores de localizacion: \n");
List<String> proveedores = manejador.getAllProviders();
for(String proveedor : proveedores)
muestraProveedor(proveedor);
}
private void muestraProveedor(String proveedor){
LocationProvider info = manejador.getProvider(proveedor);
log("LocationProvider[" + "getName=" + info.getName()
+ ", isProviderEnabled= "
+ manejador.isProviderEnabled(proveedor) + ", getAccuracy="
+ A[Math.max(0,info.getAccuracy())]+", getPowerRequirements="
+ P[Math.max(0,info.getPowerRequirement())]
+ ", hasMonetaryCost=" + info.hasMonetaryCost()
+ ", requiresCell=" + info.requiresCell()
+ ", requiresNetwork=" + info.requiresNetwork()
+ ", requiresSatellite=" + info.requiresSatellite()
+ ", supportsAltitude=" + info.supportsAltitude()
+ ", supportsBearing=" + info.supportsBearing()
+ ", supportsSpeed=" + info.supportsSpeed() + "]\n");
}
Si bien parecen bloques complejos no lo son tanto, los primeros metodos son los encargados de monitorear los ciclos de vida de nuestra app, la primera es para cuando vuelve a verse en pantalla y actualiza todos los datos, el segundo metodo se encarga de remover las actualizaciones cuando pierda el foco, luego tendremos cuatros metodos para mostrar informacion por medio del log(), el primero mostrara informacion cuando se cambie la localizacion, el segundo metodo nos informara si el metodo esta deshabilitado, el tercer metodo se encargara de mostrarnos si el proveedor esta habilitado y el cuarto nos mostrara si el estatus del mismo cambio, nuestro siguiente metodo llamado log() sera el encargado de mostrar en pantalla la informacion que le enviemos, gracias al vinculo entre salida y el elemento TextView, nuestro siguiente metodo (muestraLocaliz) nos motrara la ubicacion o en caso de ser null nos informara que es desconocida, despues veremos la informacion de los proveedores pero para ello utilizaremos un for avanzado donde llamaremos al ultimo metodo, muestraProveedor(), el cual se encargara de mostrarnos todos los datos del proveedor informado, observen como utilizamos los tres Array declarados al principio, el Array A se encarga de mostrarnos el nivel de precision (Accuracy) y el Array P se encarga de mostrarnos los requerimientos de energia (PowerRequirements) , el restos de los datos se obtienen con los metodos relacionados directamente. Con esto nos falta una sola modificacion mas para poder probar nuestra app, para ello debemos abrir el archivo AndroidManifest.xml donde podremos agregar los permisos:
android.permission.ACCESS_COARSE_LOCATION
o la siguiente linea:
android.permission.ACCESS_FINE_LOCATION
El primer permiso nos permitiria poder obtener la localizacion por medio de las redes moviles y del Wi-Fi pero la segunda linea nos permitira acceder no solamente a la localizacion por medio de las redes disponibles sino tambien por la señal de gps, por ende para nuestra app utilizaremos la segunda linea ya que nos permitira poder tener una ubicacion mas precisa, procedamos a agregar la siguiente linea en el archivo AndroidManifest.xml:
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION" />
Con todos los permisos establecidos podremos probar nuestra app, si la probamos con nuestro emulador, preferentemente un Android menor al 6.0, obtendremos una salida como se ve a continuacion

Probemos la misma app pero ahora con un equipo real, en casos de Android 6.0 o superior recuerden verificar que tenga los permisos concedidos sino devolvera un error, si todo esta bien saldra como se ve en la siguiente imagen

Como se ve en las imagenes observen como se ven las tres posibilidades para poder ajustar con mejor precision nuestra ubicacion.
En resumen, hoy hemos visto como se puede utilizar la localizacion por medio de distintos sistemas, gps, network y pasivo, hemos visto los paquetes necesarios, los permisos que se deben conceder y como funciona en nuestro equipo emulado y en un equipo real, espero les haya sido util sigueme en Twitter, Facebook o Google+ para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Tambien podes donar
Es para mantenimiento del sitio, gracias!
$1.50