Cómo llegar Localización de direcciones en una aplicación para Android

aa-codificación geográfica veces cuadrados

En los tutoriales anteriores, hemos discutido cómo obtener los datos de ubicación, así como el uso de datos de localización para implementar un sistema de seguimiento de la ubicación simple dispositivo utilizando la API ThingSpeak. Para este tutorial, vamos a utilizar el Geocoder clase para traducir una dirección que figura en su latitud y valores de longitud (geocodificación), y también se traduce una latitud y longitud de valor en una dirección (geocodificación inversa).

Preparación

De Wikipedia, Geocodificación utiliza una descripción de un lugar, como una dirección o una ciudad postal, para encontrar las coordenadas geográficas. Geocodificación inversa, por otra parte, utiliza coordenadas geográficas para encontrar una descripción de la ubicación.

Un geocodificador es o bien una pieza de software o un servicio que implementa un proceso de geocodificación. La API de Android contiene una clase Geocoder que puede utilizar un nombre de ubicación o los valores de latitud y longitud de una ubicación para obtener más detalles acerca de una dirección (se puede realizar tanto hacia adelante y geocodificación inversa). Los detalles de la dirección devueltos incluyen nombre de la dirección, nombre de país, código de país, código postal y mucho más.

App Layout

Nuestra aplicación va a utilizar hacia adelante y geocodificación inversa para obtener la dirección de ubicación y el diseño de aplicación lo refleja. La disposición contiene dos EditTexts de latitud y longitud, respectivamente, y un EditarTexto para la entrada de nombre de dirección. Debajo de ellos, tenemos dos componentes RadioButton, para seleccionar si queremos ir a buscar una dirección utilizando los valores de latitud / longitud de la localización, o utilizando el nombre de la dirección. Hay un botón, que se inicia la búsqueda de geocodificación al hacer clic, un ProgressBar, para mostrar al usuario de que la tarea de búsqueda se ejecuta en segundo plano, y un TextView para mostrar el resultado recibido.

aa-codificación geográfica-layout

lt;? xml version = "1.0" encoding = "UTF-8"> 

Obtención de la dirección

Geocoder tiene dos métodos para ir a buscar una dirección, getFromLocation (), que utiliza latitud y longitud, y getFromLocationName (), que usa el nombre de la ubicación. Ambos métodos devuelven una lista de Dirección objetos. Una dirección contiene información como el nombre de la dirección, país, latitud y longitud, mientras que Localización contiene latitud, longitud, altitud cojinete y entre otros. Recuerde que los métodos anteriores Geocoder bloque de la rosca que se ejecutan en el, y nunca deben ser llamados a partir de hilos de interfaz de usuario de la aplicación.

Para llevar a cabo una tarea de larga duración en el fondo, se puede utilizar un AsyncTask. Sin embargo, el AsyncTask no se recomienda para operaciones como la búsqueda Geocoder, ya que puede tener un potencial mucho tiempo para volver. AsyncTask de se debe utilizar para las operaciones comparativamente más cortos. Si bien podemos (y lo hizo) utilizar el AsyncTask, de acuerdo con las recomendaciones de desarrolladores de Android y las mejores prácticas, usaríamos una IntentService. Un IntentService extiende servicio, y las operaciones se ejecutan en ella puede tomar todo el tiempo necesario. Un IntentService tiene ninguna referencia a la actividad que se inició a partir, y así, la actividad puede ser reconstruido (como cuando se gira el dispositivo), sin afectar a las tareas de la IntentService, a diferencia del AsyncTask. (Nota: En realidad usó un AsyncTask, y funcionó tan bien Como beneficio adicional, la actividad, utilizando un AsyncTask es. disponible en el github proyecto como MainActivityWithAsyncTask)

Utilizando el IntentService

Extendemos IntentService y definimos GeocodeAddressIntentService. Un IntentService se inicia mucho como una actividad. Construimos una Intención, e iniciar el servicio llamando al método Context.startService ().

Antes de definir la clase, incluimos nuestra GeocodeAddressIntentService en el AppManifest. No te olvides de incluir también el permiso INTERNET. En mi caso, mientras que el desarrollo / pruebas en un dispositivo Nexus 5 Lollipop, la red de llamadas simplemente en silencio fracasó antes de incluir el permiso INTERNET. Así pues, si usted no recibe ninguna respuesta, primero confirme que usted ha solicitado el permiso INTERNET.

 

Para utilizar nuestro IntentService, debemos implementar el método onHandleIntent (Intención). Este es el punto de entrada para IntentService de, al igual que el onCreate () es el punto de entrada para la actividad de. En el fragmento de código a continuación, tomar nota del objeto ResultReceiver. Cuando su IntentService ha completado la tarea, debe tener una forma de enviar los resultados a la actividad de invocación. Ahí es donde el ResultReceiver entra, y vamos a discutir su implementación en un rato.

public class GeocodeAddressIntentService extiende IntentService {protected static TAG ResultReceiver resultReceiver-final privado String = "FetchAddyIntentService" GeocodeAddressIntentService -públicos () {super ("GeocodeAddressIntentService") -} ... @ Overrideprotected vacío onHandleIntent (intención Intención) {Geocoder geocodificador = new Geocoder (esto, Locale.getDefault ()) - Lista
direcciones = null-resultReceiver = intent.getParcelableExtra (Constants.RECEIVER) -INT fetchType = intent.getIntExtra (Constants.FETCH_TYPE_EXTRA, 0) -...}}

El siguiente fragmento de código contiene el avance real o revertir geocodificación llamadas de consulta. Determinamos si la búsqueda utiliza nombre de la ubicación, o los valores de latitud / longitud de ubicación, y llamar al método apropiado. Si el uso de nombre de la ubicación, que llamamos el método Geocoder.getFromLocationName (), y si el uso de latitud / longitud, que llamamos Geocoder.getFromLocation () método. Se puede especificar un número máximo de direcciones para ser devueltos. En nuestra muestra, solicitamos por un máximo de una (1) dirección. Tenga en cuenta que el nombre de la dirección puede referirse a más de una ubicación, se extendió a través de múltiples países. En una aplicación de producción, es posible que desee a buscar a más de uno, y tienen un algoritmo determina que es la dirección más probable es que se requiera.

si (fetchType == Constants.USE_ADDRESS_NAME) {String nombre = intent.getStringExtra (Constants.LOCATION_NAME_DATA_EXTRA) -Trate {direcciones = geocoder.getFromLocationName (nombre, 1) -} catch (IOException e) {errorMessage = "Servicio no disponible" - Log.e (TAG, errorMessage, e) -}} else if (fetchType == Constants.USE_ADDRESS_LOCATION) {Location location = intent.getParcelableExtra (Constants.LOCATION_DATA_EXTRA) -Trate {direcciones = geocoder.getFromLocation (location.getLatitude (), location.getLongitude (), 1) -} catch (IOException IOException) {errorMessage = "Servicio no disponible" -Log.e (TAG, errorMessage, IOException) -} catch (IllegalArgumentException IllegalArgumentException) {errorMessage = "Latitud válido o Longitud Usado "(. -Log.e TAG, errorMessage +" "+" La latitud = "+ location.getLatitude (+)", Longitud = "+ location.getLongitude (), IllegalArgumentException) -}} else {errorMessage =" Desconocido Tipo " -} if (direcciones == null || addresses.size () == 0) {if (errorMessage.isEmpty ()) {errorMessage = "Not Found" -} deliverResultToReceiver (Constants.FAILURE_RESULT, errorMessage, null) -} else {for (Dirección Dirección: direcciones) {Cadena outputAddress = "" -para (int i = 0- i lt; address.getMaxAddressLineIndex () - i ++) {outputAddress + = "---" + address.getAddressLine (i) -}} Direccion direccion = addresses.get (0) -ArrayList addressFragments = new ArrayList() -para (int i = 0- i lt; address.getMaxAddressLineIndex () - i ++) {addressFragments.add(address.getAddressLine(i))-}(R.string.address_found))-deliverResultToReceiver(Constants.SUCCESS_RESULT,TextUtils.join(System.getProperty("line.separator"),addressFragments), dirección)-}

deliverResultToReceiver es un método simple, que maneja la devolución de los resultados de la operación a la Actividad de invocación, a través de la ResultReceiver.

void deliverResultToReceiver privada (int resultCode, String mensaje, dirección Dirección) {paquete paquete = new Bundle () - bundle.putParcelable (Constants.RESULT_ADDRESS, dirección) -bundle.putString (Constants.RESULT_DATA_KEY, mensaje) -resultReceiver.send (resultCode, haz)-}

Implementamos el ResultReceiver como una clase interna en el MainActivity.

clase AddressResultReceiver extiende ResultReceiver {AddressResultReceiver público (manejador Manejador) {super (manejador) -} @ Overrideprotected onReceiveResult void (int resultCode, última Bundle resultData) {if (resultCode == Constants.SUCCESS_RESULT) {Dirección Dirección final = resultData.getParcelable (Constantes .RESULT_ADDRESS) -runOnUiThread (nueva Ejecutable () {Overridepublic void run () {progressBar.setVisibility (View.INVISIBLE) -infoText.setText ("Latitud:" + address.getLatitude () + " n" "Longitud +: "+ address.getLongitude () +" n "+" Dirección: "+ resultData.getString (Constants.RESULT_DATA_KEY)) -}}) -} else {runOnUiThread (nueva Ejecutable () {Overridepublic void run () {progressBar.setVisibility(View.INVISIBLE)-infoText.setText(resultData.getString(Constants.RESULT_DATA_KEY))-}})-}}

aa-codificación geográfica-el-louvre

Inicio del IntentService es bastante similar a iniciar una nueva actividad. Construimos una intención, poner en los extras necesarios, y llamamos Context.startService (Intención). Los Extras nos bulto en el Intento depende de si estamos realizando una búsqueda directa o inversa.

public void onButtonclicked (Ver vista) {intención Intención = new Intent (esto, GeocodeAddressIntentService.class) -intent.putExtra (Constants.RECEIVER, mResultReceiver) -intent.putExtra (Constants.FETCH_TYPE_EXTRA, fetchType) -si (Constantes fetchType ==. USE_ADDRESS_NAME) {if (addressEdit.getText () longitud () == 0) {Toast.makeText (this, "Por favor, introduzca un nombre de dirección", Toast.LENGTH_LONG) .Show () -. retornables} intent.putExtra (Constantes . .LOCATION_NAME_DATA_EXTRA, addressEdit.getText toString () ()) -..} else {if (latitudeEdit.getText () longitud () == 0 || longitudeEdit.getText () longitud () == 0) {Toast.makeText (this, "Por favor, introduzca los valores de latitud / longitud", Toast.LENGTH_LONG) .show () - Regresar-} ubicación Ubicación = new Location("")-location.setLatitude(Double.parseDouble(latitudeEdit.getText().toString()))-location.setLongitude(Double.parseDouble(longitudeEdit.getText().toString()))-intent.putExtra(Constants.LOCATION_DATA_EXTRA, ubicación) -} progressBar.setVisibility (View.VISIBLE) -Log.e (TAG, "Inicio de Servicio") - StartService (intención) -}

aa-codificación geográfica veces cuadrados

Conclusión

Si bien es muy bien el seguimiento de la ubicación de un usuario, para su aplicación a sorprender de verdad, que muestra a los usuarios un nombre de dirección de un lugar determinado casi siempre será más útil que los valores de latitud y longitud correspondientes.

El código fuente completo es disponible en GitHub, y pueden ser en forma de horquilla, descargado, copiado y usado si lo deseas.

Si has seguido nuestros tutoriales anteriores sobre utilizando la API ThingSpeak para rastrear la ubicación de un dispositivo, y cómo obtener y utilizar la ubicación de un dispositivo Android, tratar de integrar la geocodificación y obtener dirección de ubicación en ambas aplicaciones. Diviértete codificación y compartir sus desafíos y éxitos en los comentarios abajo.


» » » Cómo llegar Localización de direcciones en una aplicación para Android