Android: servicios basados ​​en la ubicación

Las API de ubicación de Android le facilitan la creación de aplicaciones con reconocimiento de ubicación, sin necesidad de centrarse en los detalles de la tecnología de ubicación subyacente.

Esto es posible con la ayuda de Google Play services, que facilita agregar conocimiento de ubicación a su aplicación con rastreo de ubicación automatizado, geofencing y reconocimiento de actividad.

Este tutorial le muestra cómo usar los servicios de ubicación en su aplicación para obtener la ubicación actual, obtener actualizaciones periódicas de ubicación, buscar direcciones, etc.

El objeto de ubicación

los LocationEl objeto representa una ubicación geográfica que puede consistir en una latitud, longitud, marca de tiempo y otra información como rumbo, altitud y velocidad. Existen los siguientes métodos importantes que puede utilizar con el objeto Ubicación para obtener información específica de la ubicación:

No Señor. Método y descripción
1

float distanceTo(Location dest)

Devuelve la distancia aproximada en metros entre esta ubicación y la ubicación dada.

2

float getAccuracy()

Obtenga la precisión estimada de esta ubicación, en metros.

3

double getAltitude()

Obtenga la altitud, si está disponible, en metros sobre el nivel del mar.

4

float getBearing()

Obtenga el rumbo, en grados.

5

double getLatitude()

Obtenga la latitud, en grados.

6

double getLongitude()

Obtenga la longitud, en grados.

7

float getSpeed()

Obtenga la velocidad si está disponible, en metros / segundo sobre el suelo.

8

boolean hasAccuracy()

Verdadero si esta ubicación tiene una precisión.

9

boolean hasAltitude()

Verdadero si esta ubicación tiene una altitud.

10

boolean hasBearing()

Es cierto si esta ubicación tiene relación.

11

boolean hasSpeed()

Es cierto si esta ubicación tiene una velocidad.

12

void reset()

Borra el contenido de la ubicación.

13

void setAccuracy(float accuracy)

Establezca la precisión estimada de esta ubicación, metros.

14

void setAltitude(double altitude)

Establezca la altitud, en metros sobre el nivel del mar.

15

void setBearing(float bearing)

Establezca el rumbo, en grados.

dieciséis

void setLatitude(double latitude)

Configure la latitud, en grados.

17

void setLongitude(double longitude)

Configure la longitud, en grados.

18

void setSpeed(float speed)

Establezca la velocidad, en metros / segundo sobre el suelo.

19

String toString()

Devuelve una cadena que contiene una descripción concisa y legible por humanos de este objeto.

Obtener la ubicación actual

Para obtener la ubicación actual, cree un cliente de ubicación que sea LocationClient objeto, conéctelo a los servicios de ubicación utilizando connect() método, y luego llamar a su getLastLocation()método. Este método devuelve la ubicación más reciente en forma deLocationobjeto que contiene coordenadas de latitud y longitud y otra información como se explicó anteriormente. Para tener una funcionalidad basada en la ubicación en su actividad, deberá implementar dos interfaces:

  • GooglePlayServicesClient.ConnectionCallbacks
  • GooglePlayServicesClient.OnConnectionFailedListener

Estas interfaces proporcionan los siguientes métodos de devolución de llamada importantes, que debe implementar en su clase de actividad:

No Señor. Métodos de devolución de llamada y descripción
1

abstract void onConnected(Bundle connectionHint)

Este método de devolución de llamada se llama cuando el servicio de ubicación se conecta correctamente al cliente de ubicación. Usarásconnect() método para conectarse al cliente de ubicación.

2

abstract void onDisconnected()

Este método de devolución de llamada se llama cuando se desconecta el cliente. Usarásdisconnect() método para desconectarse del cliente de ubicación.

3

abstract void onConnectionFailed(ConnectionResult result)

Este método de devolución de llamada se llama cuando se produce un error al conectar el cliente al servicio.

Debe crear el cliente de ubicación en onCreate() método de su clase de actividad, luego conéctelo en onStart(), para que los Servicios de ubicación mantengan la ubicación actual mientras su actividad sea completamente visible. Debes desconectar el cliente en onStop()método, de modo que cuando su aplicación no sea visible, los Servicios de ubicación no mantengan la ubicación actual. Esto ayuda a ahorrar energía de la batería en gran medida.

Obtenga la ubicación actualizada

Si está dispuesto a recibir actualizaciones de ubicación, además de las interfaces mencionadas anteriormente, deberá implementar LocationListenerinterfaz también. Esta interfaz proporciona el siguiente método de devolución de llamada, que debe implementar en su clase de actividad:

No Señor. Método y descripción de devolución de llamada
1

abstract void onLocationChanged(Location location)

Este método de devolución de llamada se utiliza para recibir notificaciones de LocationClient cuando la ubicación ha cambiado.

Ubicación Calidad de servicio

los LocationRequest El objeto se utiliza para solicitar una calidad de servicio (QoS) para actualizaciones de ubicación del LocationClient. Existen los siguientes métodos de establecimiento útiles que puede utilizar para manejar QoS. Hay métodos de obtención equivalentes disponibles que puede consultar en la documentación oficial de Android.

No Señor. Método y descripción
1

setExpirationDuration(long millis)

Establezca la duración de esta solicitud, en milisegundos.

2

setExpirationTime(long millis)

Establezca el tiempo de caducidad de la solicitud, en milisegundos desde el inicio.

3

setFastestInterval(long millis)

Establezca explícitamente el intervalo más rápido para las actualizaciones de ubicación, en milisegundos.

4

setInterval(long millis)

Establezca el intervalo deseado para las actualizaciones de ubicación activas, en milisegundos.

5

setNumUpdates(int numUpdates)

Establezca la cantidad de actualizaciones de ubicación.

6

setPriority(int priority)

Establezca la prioridad de la solicitud.

Ahora, por ejemplo, si su aplicación desea una ubicación de alta precisión, debe crear una solicitud de ubicación con setPriority(int) establecido en PRIORITY_HIGH_ACCURACY y setInterval(long)a 5 segundos. También puede usar un intervalo más grande y / u otras prioridades como PRIORITY_LOW_POWER para solicitar precisión de nivel de "ciudad" o PRIORITY_BALANCED_POWER_ACCURACY para precisión de nivel de "bloque".

Las actividades deben considerar seriamente eliminar todas las solicitudes de ubicación al ingresar en segundo plano (por ejemplo, en onPause ()), o al menos cambiar la solicitud a un intervalo más grande y de menor calidad para ahorrar consumo de energía.

Visualización de una dirección de ubicación

Una vez que tengas Location objeto, puedes usar Geocoder.getFromLocation()método para obtener una dirección para una latitud y longitud determinadas. Este método es sincrónico y puede tardar mucho en hacer su trabajo, por lo que debe llamar al método desde eldoInBackground() método de un AsyncTask clase.

los AsyncTask debe ser una subclase para ser utilizada y la subclase anulará doInBackground(Params...) método para realizar una tarea en segundo plano y onPostExecute(Result)El método se invoca en el subproceso de la interfaz de usuario después de que finaliza el cálculo en segundo plano y en el momento de mostrar el resultado. Hay un método más importante disponible en AyncTask que esexecute(Params... params), este método ejecuta la tarea con los parámetros especificados.

Ejemplo

El siguiente ejemplo le muestra en la práctica cómo usar los servicios de ubicación en su aplicación para obtener la ubicación actual y sus direcciones equivalentes, etc.

Para experimentar con este ejemplo, necesitará un dispositivo móvil real equipado con el último sistema operativo Android; de lo contrario, tendrá que luchar con el emulador que puede no funcionar.

Crear aplicación de Android

Paso Descripción
1 Utilizará Android Studio IDE para crear una aplicación de Android y nombrarla como Tutorialspoint en un paquete com.example.tutorialspoint7.myapplication .
2 agregue el archivo src / GPSTracker.java y agregue el código requerido.
3 Modifique el archivo src / MainActivity.java y agregue el código requerido como se muestra a continuación para obtener la ubicación actual y su dirección equivalente.
4 Modifique el archivo XML de diseño res / layout / activity_main.xml para agregar todos los componentes GUI que incluyen tres botones y dos vistas de texto para mostrar la ubicación / dirección.
5 Modifique res / values ​​/ strings.xml para definir los valores constantes requeridos
6 Modifique AndroidManifest.xml como se muestra a continuación
7 Ejecute la aplicación para iniciar el emulador de Android y verifique el resultado de los cambios realizados en la aplicación.

A continuación se muestra el contenido del archivo de actividad principal modificado MainActivity.java.

package com.example.tutorialspoint7.myapplication;

import android.Manifest;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.test.mock.MockPackageManager;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {

   Button btnShowLocation;
   private static final int REQUEST_CODE_PERMISSION = 2;
   String mPermission = Manifest.permission.ACCESS_FINE_LOCATION;

   // GPSTracker class
   GPSTracker gps;

   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
		
      try {
         if (ActivityCompat.checkSelfPermission(this, mPermission)
            != MockPackageManager.PERMISSION_GRANTED) {

            ActivityCompat.requestPermissions(this, new String[]{mPermission}, 
               REQUEST_CODE_PERMISSION);

            // If any permission above not allowed by user, this condition will
               execute every time, else your else part will work
         }
      } catch (Exception e) {
         e.printStackTrace();
      }

      btnShowLocation = (Button) findViewById(R.id.button);

      // show location button click event
      btnShowLocation.setOnClickListener(new View.OnClickListener() {

         @Override
         public void onClick(View arg0) {
            // create class object
            gps = new GPSTracker(MainActivity.this);

            // check if GPS enabled
            if(gps.canGetLocation()){

               double latitude = gps.getLatitude();
               double longitude = gps.getLongitude();

               // \n is for new line
               Toast.makeText(getApplicationContext(), "Your Location is - \nLat: "
                  + latitude + "\nLong: " + longitude, Toast.LENGTH_LONG).show();
            }else{
               // can't get location
               // GPS or Network is not enabled
               // Ask user to enable GPS/network in settings
               gps.showSettingsAlert();
            }

         }
      });
   }
}

A continuación se muestra el contenido del archivo de actividad principal modificado GPSTracker.java.

package com.example.tutorialspoint7.myapplication;

import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Log;

public class GPSTracker extends Service implements LocationListener {

   private final Context mContext;

   // flag for GPS status
   boolean isGPSEnabled = false;

   // flag for network status
   boolean isNetworkEnabled = false;

   // flag for GPS status
   boolean canGetLocation = false;

   Location location; // location
   double latitude; // latitude
   double longitude; // longitude

   // The minimum distance to change Updates in meters
   private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters

   // The minimum time between updates in milliseconds
   private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute

   // Declaring a Location Manager
   protected LocationManager locationManager;

   public GPSTracker(Context context) {
      this.mContext = context;
      getLocation();
   }

   public Location getLocation() {
      try {
         locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);

         // getting GPS status
         isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

         // getting network status
         isNetworkEnabled = locationManager
            .isProviderEnabled(LocationManager.NETWORK_PROVIDER);

         if (!isGPSEnabled && !isNetworkEnabled) {
            // no network provider is enabled
         } else {
            this.canGetLocation = true;
            // First get location from Network Provider
            if (isNetworkEnabled) {
               locationManager.requestLocationUpdates(
                  LocationManager.NETWORK_PROVIDER,
                  MIN_TIME_BW_UPDATES,
                  MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
						
               Log.d("Network", "Network");
               if (locationManager != null) {
                  location = locationManager
                     .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
							
                  if (location != null) {
                     latitude = location.getLatitude();
                     longitude = location.getLongitude();
                  }
               }
            }
				
            // if GPS Enabled get lat/long using GPS Services
            if (isGPSEnabled) {
               if (location == null) {
                  locationManager.requestLocationUpdates(
                     LocationManager.GPS_PROVIDER,
                     MIN_TIME_BW_UPDATES,
                     MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
							
                  Log.d("GPS Enabled", "GPS Enabled");
                  if (locationManager != null) {
                     location = locationManager
                        .getLastKnownLocation(LocationManager.GPS_PROVIDER);
								
                     if (location != null) {
                        latitude = location.getLatitude();
                        longitude = location.getLongitude();
                     }
                  }
               }
            }
         }

      } catch (Exception e) {
         e.printStackTrace();
      }

      return location;
   }

   /**
      * Stop using GPS listener
      * Calling this function will stop using GPS in your app
   * */
	
   public void stopUsingGPS(){
      if(locationManager != null){
         locationManager.removeUpdates(GPSTracker.this);
      }
   }

   /**
      * Function to get latitude
   * */
	
   public double getLatitude(){
      if(location != null){
         latitude = location.getLatitude();
      }

      // return latitude
      return latitude;
   }

   /**
      * Function to get longitude
   * */
	
   public double getLongitude(){
      if(location != null){
         longitude = location.getLongitude();
      }

      // return longitude
      return longitude;
   }

   /**
      * Function to check GPS/wifi enabled
      * @return boolean
   * */
	
   public boolean canGetLocation() {
      return this.canGetLocation;
   }

   /**
      * Function to show settings alert dialog
      * On pressing Settings button will lauch Settings Options
   * */
	
   public void showSettingsAlert(){
      AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);

      // Setting Dialog Title
      alertDialog.setTitle("GPS is settings");

      // Setting Dialog Message
      alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?");

      // On pressing Settings button
      alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
         public void onClick(DialogInterface dialog,int which) {
            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            mContext.startActivity(intent);
         }
      });

      // on pressing cancel button
      alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
         public void onClick(DialogInterface dialog, int which) {
            dialog.cancel();
         }
      });

      // Showing Alert Message
      alertDialog.show();
   }

   @Override
   public void onLocationChanged(Location location) {
   }

   @Override
   public void onProviderDisabled(String provider) {
   }

   @Override
   public void onProviderEnabled(String provider) {
   }

   @Override
   public void onStatusChanged(String provider, int status, Bundle extras) {
   }

   @Override
   public IBinder onBind(Intent arg0) {
      return null;
   }
}

A continuación se mostrará el contenido de res/layout/activity_main.xml archivo -

<?xml version = "1.0" encoding = "utf-8"?>
<LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
   android:layout_width = "fill_parent"
   android:layout_height = "fill_parent"
   android:orientation = "vertical" >


   <Button
      android:id = "@+id/button"
      android:layout_width = "fill_parent"
      android:layout_height = "wrap_content"
      android:text = "getlocation"/>

</LinearLayout>

A continuación se mostrará el contenido de res/values/strings.xml para definir dos nuevas constantes -

<?xml version = "1.0" encoding = "utf-8"?>
<resources>
   <string name = "app_name">Tutorialspoint</string>
</resources>

A continuación se muestra el contenido predeterminado de AndroidManifest.xml -

<?xml version = "1.0" encoding = "utf-8"?>
<manifest xmlns:android = "http://schemas.android.com/apk/res/android"
   package = "com.example.tutorialspoint7.myapplication">
   <uses-permission android:name = "android.permission.ACCESS_FINE_LOCATION" />
   <uses-permission android:name = "android.permission.INTERNET" />
   <application
      android:allowBackup = "true"
      android:icon = "@mipmap/ic_launcher"
      android:label = "@string/app_name"
      android:supportsRtl = "true"
      android:theme = "@style/AppTheme">
		
      <activity android:name = ".MainActivity">
         <intent-filter>
            <action android:name = "android.intent.action.MAIN" />

            <category android:name = "android.intent.category.LAUNCHER" />
         </intent-filter>
      </activity>
   </application>

</manifest>

Intentemos ejecutar tu Tutorialspointsolicitud. Supongo que ha conectado su dispositivo móvil Android real con su computadora. Para ejecutar la aplicación desde Android Studio, abra uno de los archivos de actividad de su proyecto y haga clic en el icono Ejecutar en la barra de herramientas. Antes de iniciar su aplicación, el instalador de Android Studio mostrará la siguiente ventana para seleccionar una opción donde desea ejecutar su aplicación de Android.

Ahora, para ver la ubicación, seleccione el botón Obtener ubicación que mostrará la información de ubicación de la siguiente manera: