lunes, 31 de diciembre de 2012

Comenzando con Google Maps API v2 parte 2



Desarrollo sobre la plataforma Android

Hola a todos, en este post vamos a hablar otra vez de Google Maps en Android, pero esta vez, no vamos a hablar de un tema exclusivo de la API v2 de Google Maps, ya que la versión 1 usa también estas estrategias para manejar la localización ;)
En un principio puede resultarnos complicado, cosas simples como por ejemplo obtener nuestra posición actual, algunas de las cosas que pueden hacer que nos resulte complicado, pueden ser:

  • Muchas fuentes de información: aunque parezca extraño esto, el tener múltiples fuentes de información (GPS, Wifi, 3G, Cell-ID), puede ocasionarnos el problema de no saber cual usar, o de configurar uno y no otro.
  • El cambio de posición: el saber como y cada cuanto se actualiza la posición.
  • Consumos de datos y energía: como deben imaginar también tenemos que tener en cuenta que de acuerdo a la manera en que tomemos estos datos, van a variar los consumos de estas cosas :P
Por suerte la librería de Android nos va a ayudar bastante con este tema, las dos cosas principales que vamos a necesitar van a ser dos objetos, uno de tipo LocationManager y el otro un listener de tipo LocationListener, un sencillo ejemplo podría ser:

// Tomamos la referencia hacia el manager
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
// Y aqui deberemos definir nuestro listener, para poder
// actualizar nuestra ubicacion
LocationListener locationListener = new LocationListener() {
   
public void onLocationChanged(Location location) {
     
// Este es el metodo que mas nos va a interesar implementar

// ya que es el que nos va a dar nuestra ubicacion
     hacerUsoDeNuestraUbicacion(location);
   
}

// Estos otros metodos tambien deberiamos implementarlos
   
public void onStatusChanged(String provider, int status, Bundle

extras) {}
   
public void onProviderEnabled(String provider) {}

   
public void onProviderDisabled(String provider) {}
 
};
// Y aca registramos nuestro listener con el location manager, para
// poder ir tomando las actualizaciones de ubicacion
locationManager
.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);

Así que a nuestro manager deberemos pasarle, cual va a ser el proveedor de ubicación, en este caso le pase NETWORK, pero tranquilamente podria ser el GPS, tambien podriamos registrar los dos proveedores ;) los otros dos parámetros que son números, van a manejar la frecuencia con la que se va a ir actualizando. Hay que pensar en hacerlo dependiendo de nuestras necesidades, porque podríamos hacerlo todo el tiempo, pero hay que tener en cuenta el consumo de recursos y batería :P
Una vez visto esto, vamos a tener que tener en cuenta los permisos necesarios en nuestra app, para que pueda utilizar la internet, gps o el medio que usemos para tomar los datos. Ya que si esto no lo plasmamos en el manifest, nos va a saltar un error al querer correr la aplicación.
Si van a utilizar la red y el GPS, van a necesitar agregar este permiso:

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

Ahora si solo van a usar la red, podrían usar este permiso:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
En el primer caso no se necesitan dos permiso, ya que ACCESS_FINE_LOCATION contiene los dos permisos.
Como dije antes, hay que tener cuidado con el tema de los consumos, aquí hay un gráfico del proceso para encontrar la ubicación:





Después de ver este gráfico, debemos pensar en cuando vamos a comenzar a escuchar, para obtener actualizaciones de la ubicación. Así que para no afectar los consumos, debemos ver si comenzamos a escuchar cuando arranca la app, o cuando sucede algún tipo de acción, y ver cuando se va a terminar la escucha. Hay que tener en cuenta el periodo de tiempo por el que va a estar escuchando, ya que lo podríamos hacer por periodos, pero tenemos que ver que esos periodos de tiempo sean lo suficientemente largos para que el dispositivo pueda encontrar el dato.



Una cosa a tener en cuenta es algo que puede ser útil, pero a su vez puede causar dolores de cabeza, la clase LocationManager tiene un método llamado getLastKnownLocation().Este método, utiliza la caché de la última ubicación recibida, no devuelve la posición actual, tampoco solicita una nueva posición al proveedor de localización, este método se limita a devolver la última posición que se obtuvo a través del proveedor que se le indique como parámetro. Y esta posición se pudo obtener hace pocos segundos, hace días, hace meses, o incluso nunca.Por eso hay que tener cuidado cuando se usa, al querer usar la posición devuelta por el método getLastKnownLocation().
Volviendo al tema anterior,  por eso debemos pensar bien cuando utilizar requestLocationUpdates() para tomar los datos, y cuando locationManager.removeUpdates(locationListener);
Para detener esa escucha del listener, y dejar así de consumir recursos. Otro tip:



  • Para reducir los consumos, y así no tener quejas de las personas que utilizan la aplicación, podría reducir la frecuencia con la que se actualiza la ubicación, seteando en el LocationProvider.
  • Y restringir a uno de todos los proveedores, GPS, NETWORK, también esto lo podemos setear eligiendo que LocationProvider utilizamos.

Antes de dar un pequeño ejemplo funcional sobre toda esta teoría :D queria comentarles, que con el emulador podemos similar el uso de GPS, es más para algunas cosas de este tipo, puede llegar a ser más útil, que un movil físico, ya que con archivos KML podremos simular recorridos: https://developers.google.com/kml/documentation/kml_tut?hl=es

public class NuestraUbicacion extends Activity implements LocationListener {
 
//  En la activity deberiamos creear los textview
 private TextView latituteText;
 
private TextView longitudeText;
 
private LocationManager locationManager;
 
private String proveedor;
/** En este caso implementamos directamente en la clase el LocationListener  y heredamos de Activity */
 
@Override
 
public void onCreate(Bundle savedInstanceState) {
   
super.onCreate(savedInstanceState);
   setContentView(R.layout.main);
// tomamos la refencia de los textview
   latituteText = (TextView) findViewById(R.id.TextView1);
   longitudeText = (TextView) findViewById(R.id.TextView2);

   
// Tomamos el location manager
   locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
   
// Definimos un objeto del tipo criteria para que este elija cual locatioin provider nos
   
// conviene utilizar
   Criteria criteria =
new Criteria();
   proveedor = locationManager.getBestProvider(criteria, false);
   Location ubicacion = locationManager.getLastKnownLocation(proveedor);

   
// vemos si se inicializamos la ubicacion
   
if (location != null) {
     System.out.println("Proveedor  " + proveedor + " ha sido seleccionado.");
     onLocationChanged(ubicacion);
   }
else {
     latituteText.setText("Ubicacion no encontrada");
     longitudeText.setText("Ubicacion no encontrada");
   }
 }

 
/* actualizamos la ubicacion */
 
@Override
 
protected void onResume() {
   
super.onResume();
   locationManager.requestLocationUpdates(proveedor, 400, 1,
this);
 }

 
/* detenemos el listener  */
 
@Override
 
protected void onPause() {
   
super.onPause();
   locationManager.removeUpdates(
this);
 }

 
@Override
 
public void onLocationChanged(Location location) {
   
int lat = (int) (location.getLatitude());
   
int lng = (int) (location.getLongitude());
   latituteText.setText(String.valueOf(lat));
   longitudeText.setText(String.valueOf(lng));
 }

 
@Override
 
public void onStatusChanged(String provider, int status, Bundle extras) {
   
// metodo a sobreescribit del LocationListener

 }
// lanzamos un toast cuando es habilitado el proveedor
 
@Override
 
public void onProviderEnabled(String provider) {
   Toast.makeText(
this, "Habilitado el nuevo proveedor  " + proveedor,
       Toast.LENGTH_SHORT).show();

 }
// lanzamos un toast  cuando es deshabilitado el proveedor
 @Override
 
public void onProviderDisabled(String provider) {
   Toast.makeText(
this, "Disabled provider " + provider,
       Toast.LENGTH_SHORT).show();
 }
}

Otros post relacionados con el tema:
http://www.aprendiendodeandroidymas.com/2012/12/comenzando-con-google-maps-api-v2-parte.html
http://www.aprendiendodeandroidymas.com/2013/04/comenzando-con-google-maps-api-v2-parte.html

Documentación oficial:
http://developer.android.com/guide/topics/location/strategies.html
https://developers.google.com/maps/documentation/android/?hl=es
http://developer.android.com/guide/topics/location/index.html
https://developers.google.com/maps/documentation/android/?hl=es
https://developers.google.com/maps/documentation/android/reference/index?hl=es

Es todo por ahora, vimos cómo obtener nuestra localización, y utilizar los diferentes medios para el posicionamiento. En el próximo post, probablemente veamos, como agregar marcadores, y algunas cosas para dejar más vistoso nuestro mapa. Espero que les haya gustado :D


Saludos a todos, Gabriel E. Pozo

sábado, 22 de diciembre de 2012

Comenzando con Google Maps API v2 parte 1



Desarrollo sobre la plataforma Android



Hola a todos nuevamente, en este post vamos a hablar de nuevo de Google Maps en Android, pero esta vez, vamos a ver el uso de la API v2 de Google Maps, ya que la versión 1 ya quedó deprecated :D , asi que vamos a tener que volver a ver que vamos a necesitar, configurar el uso de la API y después vamos a realizar un par de cosas que creo que nos van a resultar bastante útil, como es, que nuestro mapa se ubique en la posicion donde nos encontramos, y también como marcar algunos punto interesantes en el mapa.
En esta ocasión además de utilizar la API de Google, también vamos a utilizar un sistema de persistencia de datos, en este caso SQLite, el motor de base de datos que trae por defecto Android. Si tiene alguna duda con ello, pueden mirar esta serie de post:


http://www.aprendiendodeandroidymas.com/2012/04/persistencia-de-datos-con-sqlite-sobre.html

Cualquier consulta,tratare de ayudarlos en lo que pueda :) así que ahora comencemos con lo nuestro y cualquier cosa, realicen un comentario.
Antes que nada vamos a necesitar, instalar Google Play Service, ya que para poder usar Google Maps ahora, es un poco diferente a la versión anterior, así que con el SDK manager, la descargamos:




Después, al igual que en la anterior versión vamos a necesitar el hash de nuestra key para firmar la app, pero esta vez en vez de MD5 va a ser el SHA1, para eso en la terminal tipeamos el siguiente comando:
keytool -list -v -keystore ~/.android/debug.keystore
(por las dudas les recuerdo, que al igual que en la anterior versión de la API, esta key solo sirve para el desarrollo, para que la app la puedan subir a Google Play, deberán generar un nuevo certificado, todo esto esta explicado en el anterior post ;)
Al ejecutar el comando, se debería ver una salida de consola, similar a esta:




Una vez tenemos el hash de nuestro certificado, deberemos (a diferencia de la anterior versión de la API) ir a nuestra  Consola de Google API, ingresando en la siguiente dirección:https://code.google.com/apis/console



Una vez que hayamos, ingresado, vamos arriba a la derecha, desplegamos el panel y creamos un nuevo proyecto, con el nombre que nosotros deseemos. Ahora deberás ir a la opción Service y activar la opción Google Maps Android API v2 y aceptamos los términos de servicios ;)




Con estos pasos, ya no nos queda mucho para terminar de configurar el proyecto, así que vamos directamente a obtener la KEY, vamos entonces arriba a la derecha, seleccionamos API Access y hacemos click en create new Android key.





En el formulario que nos aparece, deberemos poner el hash SHA1 que antes obtuvimos, y además el nombre del package de nuestro proyecto separado por un punto y coma, algo similar a esto:
22:74:RE:3E:7C:11:B2:07:46:EB:07:84:32:59:3C:6A:89:7E:16:96;com.aprendiendodeandroid.rosario

Y luego de eso, obtendremos algo similar a esto:




Así que con esto ya tenemos la key necesaria para nuestro proyecto, como en la anterior API, ahora esta key debemos agregarla a nuestro AndroidManifest dentro de los tag <application> y </application>


<meta-data
    android:name="com.google.android.maps.v2.API_KEY"
    android:value="AkjnasASSGectCsZjY9JZEasdjnklnsdgIjJJJHgbbs"/>



Y debemos agregar los siguientes permisos:

<permission
         android:name="com.aprendiendodeandroid.rosario.permission.MAPS_RECEIVE"
         android:protectionLevel="signature"/>
       <uses-permission android:name="com.aprendiendodeandroid.rosario.permission.MAPS_RECEIVE"/>


Por supuesto que ustedes deberán colocar allí el nombre de su package name, y reemplazar el mío ;) Una vez realizado esto, salvamos el manifest, y tenemos todo configurado para usar la API.
Por las dudas les advierto, que esta API requiere, como minimo la version de Android 2.2 y soporte para Open GL ES versión 2

Tambien les comento que estos son los permisos extra que recomienda la gente de Google:



<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

Aunque no es estrictamente necesario, y podemos usar solo los que realmente necesitemos. Y también por el requerimiento que posee de Open Gl, recomienda que agreguemos dentro de nuestro manifest:


<uses-feature
 android:glEsVersion="0x00020000"
 android:required="true"/>

Esto es bueno, porque si el smartphone no cumple con esta característica, no le va a funcionar a la persona que instale la app, lo cual puede provocar malos comentarios, lo que no es bueno para nuestra aplicaciòn :D

Ahora lo que deberemos hacer es simplemente configurar nuestro layout y la clase que lo controla, si vamos a usar una versión de Android de la 3 en adelante simplemente la clase debe extender de Activity, pero si lo queremos hacer con una versión anterior de Android, deberemos utilizar las librerías de soporte. Si ese es el caso deberemos extender de ellas, de la siguiente manera:



public class ClasePrincipal extends android.support.v4.app.FragmentActivity {

   @Override
   protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_main);
   }


Esto se debe a que debemos utilizar en el layout, fragment, si ya no debemos utilizar MapsActivitys ni nada parecido y en nuestro layout deberemos colocar un código similar a este:


<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
 android:id="@+id/map"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment"/>

Donde solo lo que haremos es colocar un fragment, y especificar la clase a la que corresponde.
Así que con eso, deberías poder ejecutar tu aplicación, y ver el mapa correspondiente.





Aclaración: se me había olvidado de aclarar, para versiones de Android anteriores a la 3 deben poseer entre las librerías de sus proyectos: android-support-v4.jar
Ademas también deberemos poseer las librerías google-play-service.jar  y google-play-service_lib.jar
Estas dos ultimas librerías las obtenemos cuando con el sdk manager descargarmos en los extras Google Play Services. Y las podemos incorporar al proyecto, realizando click boton derecho, import..., Existing Android Code Into Workspace, y allí nos movemos hasta la carpeta donde tenemos instalado el SDK de Android <carpeta-sdk-android>/extras/google/google_play_services/libproject/google-play-services_lib“.
Una vez hayamos importado esto, realizamos nuevamente click botón derecho al proyecto, vamos a propiedades, a la sección Android, bajamos y realizamos click en Add, nos va a agregar la ultima librería que acabamos de agregar al proyecto, ya con esto no deberían tener problemas ;)



Código de ejemplo:
https://github.com/Android-Hispano/android-hispano-demo


Otros post relacionados con el tema:
http://www.aprendiendodeandroidymas.com/2012/12/comenzando-con-google-maps-api-v2-parte_31.html
http://www.aprendiendodeandroidymas.com/2013/04/comenzando-con-google-maps-api-v2-parte.html

Documentación oficial:

https://developers.google.com/maps/documentation/android/?hl=es
http://developer.android.com/guide/topics/location/index.html
https://developers.google.com/maps/documentation/android/?hl=es
https://developers.google.com/maps/documentation/android/reference/index?hl=es

Bueno,esto es todo por ahora, hemos visto cómo insertar nuestro primer mapa de Google en nuestra aplicación utilizando la segunda versión de la API, espero que les alla gustado, nos vemos en otra ocasión ;) y en la próxima vamos a ver caracteristicas realmente útil, voy a ampliar mas sobre el tema, pero el post ya me quedó demasiado extenso :D

Saludos a todos, Gabriel E. Pozo

sábado, 1 de diciembre de 2012

Comenzando con Google Maps




Desarrollo sobre la plataforma Android


Hola a todos, nuevamente estoy por acá, esta vez voy a escribir sobre un tema que realmente no me había puesto a utilizar en profundidad, pero que debido a una aplicación que estoy armando, estoy leyendo bastante documentación. Y es la utilización de los mapas de Google en nuestras aplicaciones Android, asi que ahora vamos a arrancar con el mismo :D

Bueno si estan leyendo esto, imagino que ya tendrán instalado el IDE que desean utilizar, en mi caso Eclipse, el SDK de Android y la JDK. Ya con esto preparado y armado, para poder utilizar los mapas de Google, vamos a necesitar un par de cosas más, una de ellas es con el SDK Manager descargarse la versión de Android en la que queremos desarrollar, pero que trae incorporada las API de Google, ya que con la versión original de Android al no traer esto incorporado, no podremos utilizar los mapas, u otros productos de Google.



Una vez que tengamos descargado esto, también lo que deberemos hacer es crear una VM, con esa versión en particular de Android que trae incorporadas esas API de Google.



Con esto solo no basta, el último paso para poder usar los mapas es obtener una Key de Google Maps, esto no es muy complicado, este es el manual oficial:



https://developers.google.com/maps/documentation/android/mapkey

Es muy sencillo obtenerla, lo que deberemos hacer es buscar la debug.keystore (por las dudas aclaro, que si ustedes desean subir la app a un repositorio como Google Play, deberán generar una nueva Key  ya que como podrán ver por el nombre esta es solo una versión para depuración y si no lo hacen los que se bajen la app no podrán ver los mapas ),  en el caso de usuarios Linux  normalmente esta se encuentra dentro de esta carpeta:  ~/.android/ de todas maneras si no conocemos la ubicación, una forma muy sencilla de obtenerla es desde el Eclipse con el SDK configurado, ir a Windows -> Preferences -> Android -> Build y como se ve en la imagen, tenemos el path donde se encuentra dicho archivo.


Ahora se mueven a la carpeta donde se encuentra la key y con este comando:
keytool -list -v  -keystore debug.keystore   ( la opción -v les muestra todas las versiones como SHA1 y demás, yo la agregue al comando, porque a veces te muestra un hash que a nosotros no nos sirve ;))
Podrán ver los diferentes hashes de la key, ustedes necesitan el MD5, que debera ser similar a esto: Certificate fingerprint (MD5): 94:1E:43:49:87:73:BB:E6:A6:88:D7:20:F1:8E:B5:98 (que es el de ejemplo de Google)


Ahora con este hash debemos dirigirnos a la siguiente dirección:



https://developers.google.com/android/maps-api-signup

Por supuesto que debemos aceptar los términos y condiciones, y aceptamos, una vez realizado eso, como veremos en la siguiente imagen nos da unos datos, yo les recomiendo copiarlos, porque los usaremos para poder mostrar los mapas ;)
Se que diran, ufff que lio poder usar la API de Google Maps, pero como ustedes van a ver una vez realizado esto, no va a ser complicado usarla, y los beneficios para el uso de geolocalización es impresionante ;)





Así que lo que deberemos hacer ahora es crear un nuevo proyecto Android, y le diremos que use para compilar el SDK con la API de Google, en este caso yo quería usar Android 2.2 asi que lo configure con el API 8 pero con la API de Google incorporada, como pueden ver en la imagen ;)


Una vez hecho esto, vamos a la carpeta res -> layout y allí vamos a editar la vista principal del proyecto para agregarle el mapa, para eso deberemos agregar el siguiente código:


<com.google.android.maps.MapView
android:id="@+id/mapageneral"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     android:apiKey="0rxZX0FYky7Lbpa9mz5h2Q_jSfup1flv9Fo7bEw"
android:enabled="true"
android:clickable="true"
 />
Donde el android:apiKey  es la clave que les otorgó Google para su debug.keystore.(también tengan en cuenta que si no le ponen el atributo android:clickable en true, no podrán hacer nada con el mapa ;) ) Ahora lo que nos queda es agregar las librería en el manifest, para ello dentro de los tag application debemos insertar este código:
<uses-library android:name="com.google.android.maps" />

y también fuera del tag application, por convención antes del mismo debemos agregar el permiso para el uso de internet, que se hace con el siguiente código :
<uses-permission android:name="android.permission.INTERNET"/>

Ahora simplemente nos resta modificar un poco la clase Java que va a manejar esa UI, para ello vamos a nuestra clase Mapas, y modificamos lo siguiente:

  • hacemos que en vez de extender de Activity, que extienda de MapActivity
  • dentro del método onCreate() agregamos el siguiente código:

  • // Con esto tomamos la referencia de nuestro mapa en la // vista
  • MapView mapageneral = (MapView)findViewById(R.id.mapageneral);
  • // Con esto hacemos que se vean los controles de //zoom del mapa
  • mapageneral.setBuiltInZoomControls(true);
  • // y con este ultimo hacemos que la vista de los  
  • // mapas sean del tipo Street
  • mapageneral.setStreetView(true);

Bueno una vez hecho esto, podemos ver como funciona nuestra aplicación:



Documentación oficial:

Desarrollo:

http://developer.android.com/guide/topics/location/index.html

https://developers.google.com/maps/documentation/android/?hl=es


https://developers.google.com/maps/documentation/android/reference/index?hl=es



Bueno,esto es todo por ahora, hemos visto cómo insertar nuestro primer mapa de Google en nuestra aplicación, espero que les alla gustado, nos vemos en otra ocasión ;) y en la próxima seguramente estaremos ampliando sobre el tema :D


Saludos a todos, Gabriel E. Pozo