2009-10-03 17 views
577

Necesito obtener mi ubicación actual usando GPS programáticamente. ¿Cómo puedo lograrlo?¿Cómo obtengo la ubicación actual de GPS programáticamente en Android?

+4

He publicado mi código de ejemplo [aquí] (http://stackoverflow.com/questions/3145089/what -is-the-simples-and-robust-way-to-get-the-users-current-location-in-an/3145655 # 3145655) – Fedor

+4

[Aquí] (http: //www.rdcworld-android. blogspot.in/2012/01/get-current-location-coordinates-city.html) puede encontrar tutorial paso a paso con código de muestra para GPS, ¡¡¡¡aplausos !! – swiftBoy

+0

Puede usar la biblioteca [Android-SimpleLocation] (https://github.com/delight-im/Android-SimpleLocation) (Licencia Apache) para facilitar el acceso a la ubicación – caw

Respuesta

357

He creado una pequeña aplicación con descripción paso a paso para obtener las coordenadas de GPS de la ubicación actual.

El código fuente del ejemplo completo está en Get Current Location coordinates , City name - in Android.


ver cómo funciona:

  • Todo lo que tenemos que hacer es añadir este permiso en el archivo de manifiesto:

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 
    
  • y crear una instancia LocationManager como esto :

    LocationManager locationManager = (LocationManager) 
    getSystemService(Context.LOCATION_SERVICE); 
    
  • Compruebe si el GPS está habilitado o no.

  • y luego implementar LocationListener y obtener coordenadas:

    LocationListener locationListener = new MyLocationListener(); 
    locationManager.requestLocationUpdates(
    LocationManager.GPS_PROVIDER, 5000, 10, locationListener); 
    
  • Aquí está el código de ejemplo para hacerlo


/*---------- Listener class to get coordinates ------------- */ 
private class MyLocationListener implements LocationListener { 

    @Override 
    public void onLocationChanged(Location loc) { 
     editLocation.setText(""); 
     pb.setVisibility(View.INVISIBLE); 
     Toast.makeText(
       getBaseContext(), 
       "Location changed: Lat: " + loc.getLatitude() + " Lng: " 
        + loc.getLongitude(), Toast.LENGTH_SHORT).show(); 
     String longitude = "Longitude: " + loc.getLongitude(); 
     Log.v(TAG, longitude); 
     String latitude = "Latitude: " + loc.getLatitude(); 
     Log.v(TAG, latitude); 

     /*------- To get city name from coordinates -------- */ 
     String cityName = null; 
     Geocoder gcd = new Geocoder(getBaseContext(), Locale.getDefault()); 
     List<Address> addresses; 
     try { 
      addresses = gcd.getFromLocation(loc.getLatitude(), 
        loc.getLongitude(), 1); 
      if (addresses.size() > 0) { 
       System.out.println(addresses.get(0).getLocality()); 
       cityName = addresses.get(0).getLocality(); 
      } 
     } 
     catch (IOException e) { 
      e.printStackTrace(); 
     } 
     String s = longitude + "\n" + latitude + "\n\nMy Current City is: " 
      + cityName; 
     editLocation.setText(s); 
    } 

    @Override 
    public void onProviderDisabled(String provider) {} 

    @Override 
    public void onProviderEnabled(String provider) {} 

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

+20

Esto significa que debe mudarse antes de que haya una actualización de ubicación ? ¿Por qué no muestra su ubicación actual la primera vez que intenta después de la instalación? –

+9

@NiiLaryea porque obtengo la ubicación usando el método "** onLocationChanged() **" que brinda una ubicación nueva cada vez que se muda, , pero si solo desea una vez, debe llamar a "** getLastKnownLocation() ** " – swiftBoy

+0

Si solo hay una dirección en' direcciones', la línea que comienza con 'cityName =' fallará con una excepción. El uso de llaves lo arreglaría. – Carrotman42

108

Aquí se presenta información adicional para Otras respuestas.

Dado que Android tiene

GPS_PROVIDER and NETWORK_PROVIDER 

puede registrarse para ambos y comenzar recuperan eventos de onLocationChanged(Location location) de dos al mismo tiempo. Hasta aquí todo bien. Ahora la pregunta ¿necesitamos dos resultados o deberíamos tomar lo mejor? Como sé GPS_PROVIDER, los resultados tienen mejor precisión que NETWORK_PROVIDER.

Definamos Location campo:

private Location currentBestLocation = null; 

Antes de empezar a escuchar en Ubicación cambio vamos a implementar el método siguiente. Este método devuelve la última ubicación conocida, entre el GPS y la red. Para este método, lo más nuevo es lo mejor.

/** 
* @return the last know best location 
*/ 
private Location getLastBestLocation() { 
    Location locationGPS = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
    Location locationNet = mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 

    long GPSLocationTime = 0; 
    if (null != locationGPS) { GPSLocationTime = locationGPS.getTime(); } 

    long NetLocationTime = 0; 

    if (null != locationNet) { 
     NetLocationTime = locationNet.getTime(); 
    } 

    if (0 < GPSLocationTime - NetLocationTime) { 
     return locationGPS; 
    } 
    else { 
     return locationNet; 
    } 
} 

Cada vez que recuperamos una nueva ubicación, la comparamos con nuestro resultado anterior.

... 
static final int TWO_MINUTES = 1000 * 60 * 2; 
... 

agrego un nuevo método para onLocationChanged:

@override 
public void onLocationChanged(Location location) { 

    makeUseOfNewLocation(location); 

    if(currentBestLocation == null){ 
     currentBestLocation = location; 
    } 

    .... 
} 


/** 
* This method modify the last know good location according to the arguments. 
* 
* @param location The possible new location. 
*/ 
void makeUseOfNewLocation(Location location) { 
    if (isBetterLocation(location, currentBestLocation)) { 
     currentBestLocation = location; 
    } 
} 

.... 

/** Determines whether one location reading is better than the current location fix 
* @param location The new location that you want to evaluate 
* @param currentBestLocation The current location fix, to which you want to compare the new one. 
*/ 
protected boolean isBetterLocation(Location location, Location currentBestLocation) { 
    if (currentBestLocation == null) { 
     // A new location is always better than no location 
     return true; 
    } 

    // Check whether the new location fix is newer or older 
    long timeDelta = location.getTime() - currentBestLocation.getTime(); 
    boolean isSignificantlyNewer = timeDelta > TWO_MINUTES; 
    boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES; 
    boolean isNewer = timeDelta > 0; 

    // If it's been more than two minutes since the current location, use the new location, 
    // because the user has likely moved. 
    if (isSignificantlyNewer) { 
     return true; 
     // If the new location is more than two minutes older, it must be worse. 
    } else if (isSignificantlyOlder) { 
     return false; 
    } 

    // Check whether the new location fix is more or less accurate 
    int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy()); 
    boolean isLessAccurate = accuracyDelta > 0; 
    boolean isMoreAccurate = accuracyDelta < 0; 
    boolean isSignificantlyLessAccurate = accuracyDelta > 200; 

    // Check if the old and new location are from the same provider 
    boolean isFromSameProvider = isSameProvider(location.getProvider(), 
               currentBestLocation.getProvider()); 

    // Determine location quality using a combination of timeliness and accuracy 
    if (isMoreAccurate) { 
     return true; 
    } else if (isNewer && !isLessAccurate) { 
     return true; 
    } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) { 
     return true; 
    } 
    return false; 
} 

/** Checks whether two providers are the same */ 
private boolean isSameProvider(String provider1, String provider2) { 
    if (provider1 == null) { 
     return provider2 == null; 
    } 
    return provider1.equals(provider2); 
} 

.... 
+0

Hola, ese es un buen ejemplo ... pero ¿podría darme por favor? un ejemplo más completo? Tengo problemas para integrarlo en mi código existente. Además, estoy usando solo GPS como proveedor. – beerBear

+1

@quantumstates Creo que es bastante completo. Simplemente cree el campo 'private Location currentBestLocation = null;' y agregue 'makeUseOfNewLocation (location);' al método onLocationChanged (..) –

+0

Gracias Maxim. Tengo una pregunta. ¿Dónde usas el método 'getLastBestLocation'? –

72

Usted puede encontrar la ubicación, ya sea por GPS_PROVIDER or NETWORK_PROVIDER.

Descripción general de location services en Android.

Aquí hay un ejemplo que intenta encontrar la ubicación usando el GPS. Si su GPS no está disponible, intente utilizar la red para encontrar la ubicación.

GPSTracker.java

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; 
       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 latitude/longitude 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/Wi-Fi enabled 
    * @return boolean 
    * */ 
    public boolean canGetLocation() { 
     return this.canGetLocation; 
    } 


    /** 
    * Function to show settings alert dialog. 
    * On pressing the Settings button it will launch 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 the 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 the 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; 
    } 
} 

Actividad -AndroidGPSTrackingActivity.java

public class AndroidGPSTrackingActivity extends Activity { 

    Button btnShowLocation; 

    // GPSTracker class 
    GPSTracker gps; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

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

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

      @Override 
      public void onClick(View arg0) { 
       // Create class object 
       gps = new GPSTracker(AndroidGPSTrackingActivity.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(); 
       } 
      } 
     }); 
    } 
} 

main.xml de Formato-

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout 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/btnShowLocation" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Show Location" 
     android:layout_centerVertical="true" 
     android:layout_centerHorizontal="true"/> 
</RelativeLayout> 

AndroidManifest.xml

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

Creo que hay un problema con este ejemplo, nunca parece usar el oyente de ubicación. Siempre está usando GetLastKnownLocation() que podría no ser el último –

+12

. Tiene que downvote por sobrevalorado. El código aquí es decente, pero es utilizado por mucha gente que no lo entiende, y tiene algunas fallas en el uso de getLastKnownLocation: recibimos muchas preguntas de las personas que lo usan y obtienen ubicaciones obsoletas, sin saber estan rancios Además, el valor de canGetLocation es incorrecto, usted lo establece en función de si el proveedor está habilitado pero no verifica si getLastKnownLocation devuelve un valor real; usted solo asume que lo hará. Creo que esto podría arreglarse, pero no recomendaría que nadie lo use como está. –

+5

¿Por qué instanciaste un servicio en lugar de usar el método 'startService()' ???? –

10
class MyLocation { 
    Timer timer1; 
    LocationManager lm; 
    LocationResult locationResult; 
    boolean gps_enabled = false; 
    boolean network_enabled = false; 

    public boolean getLocation(Context context, LocationResult result) { 
     // I use LocationResult callback class to pass location value from 
     // MyLocation to user code. 
     locationResult = result; 
     if (lm == null) 
      lm = (LocationManager) context 
        .getSystemService(Context.LOCATION_SERVICE); 

     // Exceptions will be thrown if the provider is not permitted. 
     try { 
      gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER); 
     } 
     catch (Exception ex) { 
     } 
     try { 
      network_enabled = lm 
        .isProviderEnabled(LocationManager.NETWORK_PROVIDER); 
     } 
     catch (Exception ex) { 
     } 

     // Don't start listeners if no provider is enabled. 
     if (!gps_enabled && !network_enabled) 
      return false; 

     if (gps_enabled) 
      lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, 
        locationListenerGps); 
     if (network_enabled) 
      lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, 
        locationListenerNetwork); 
     timer1 = new Timer(); 
     timer1.schedule(new GetLastLocation(), 5000); 
     return true; 
    } 

    LocationListener locationListenerGps = new LocationListener() { 
     public void onLocationChanged(Location location) { 
      timer1.cancel(); 
      locationResult.gotLocation(location); 
      lm.removeUpdates(this); 
      lm.removeUpdates(locationListenerNetwork); 
     } 

     public void onProviderDisabled(String provider) { 
     } 

     public void onProviderEnabled(String provider) { 
     } 

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

    LocationListener locationListenerNetwork = new LocationListener() { 
     public void onLocationChanged(Location location) { 
      timer1.cancel(); 
      locationResult.gotLocation(location); 
      lm.removeUpdates(this); 
      lm.removeUpdates(locationListenerGps); 
     } 

     public void onProviderDisabled(String provider) { 
     } 

     public void onProviderEnabled(String provider) { 
     } 

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

    class GetLastLocation extends TimerTask { 
     @Override 
     public void run() { 
      lm.removeUpdates(locationListenerGps); 
      lm.removeUpdates(locationListenerNetwork); 

      Location net_loc = null, gps_loc = null; 
      if (gps_enabled) 
       gps_loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
      if (network_enabled) 
       net_loc = lm 
         .getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 

      // If there are both values, use the latest one. 
      if (gps_loc != null && net_loc != null) { 
       if (gps_loc.getTime() > net_loc.getTime()) 
        locationResult.gotLocation(gps_loc); 
       else 
        locationResult.gotLocation(net_loc); 
       return; 
      } 

      if (gps_loc != null) { 
       locationResult.gotLocation(gps_loc); 
       return; 
      } 
      if (net_loc != null) { 
       locationResult.gotLocation(net_loc); 
       return; 
      } 
      locationResult.gotLocation(null); 
     } 
    } 

    public static abstract class LocationResult { 
     public abstract void gotLocation(Location location); 
    } 
} 

espero que esto le ayudará a ...

+1

No olvide agregar la siguiente línea a su archivo AndroidManifest: '' –

3

Si va a crear nuevos proyectos de localización para Android que puedes usar las nuevas Google Play servicios de localización. Es mucho más preciso y mucho más simple de usar.

He estado trabajando en an open source GPS tracker project, GpsTracker, durante varios años. Lo actualicé recientemente para manejar actualizaciones periódicas de teléfonos Android, iOS, Windows Phone y Java ME. Es completamente funcional y hace lo que necesita y tiene el MIT License.

El proyecto de Android dentro de GpsTracker utiliza los nuevos servicios de Google Play y también hay dos pilas de servidores (ASP.NET y PHP) que le permiten rastrear esos teléfonos.

+3

El problema es que no todos los dispositivos tienen servicios de Google Play, incluida cualquier ROM personalizada eso no es piratearlo Si va a usarlo, tenga listo un respaldo para LocationManager. –

5

Ahora que Google Play locations services están aquí, recomiendo a los desarrolladores que comiencen a usar el nuevo proveedor de ubicación fusionada. Le resultará más fácil de usar y más preciso. Mire el video Google I/OBeyond the Blue Dot: New Features in Android Location por los dos tipos que crearon la nueva API de servicios de ubicación de Google Play.

He estado trabajando con API de ubicación en varias plataformas móviles, y creo que lo que han hecho estos dos tipos es realmente revolucionario. Se ha eliminado una gran cantidad de las complejidades de usar los diversos proveedores. Stack Overflow está plagado de preguntas sobre qué proveedor usar, si usar la última ubicación conocida, cómo configurar otras propiedades en el LocationManager, etc. Esta nueva API que han creado elimina la mayoría de esas incertidumbres y hace que los servicios de ubicación sean un placer para utilizar.

He escrito una aplicación de Android que recibe periódicamente la ubicación usando los servicios de ubicación de Google Play y envía la ubicación a un servidor web donde se almacena en una base de datos y se puede ver en Google Maps.He escrito tanto el software del cliente (para Android, iOS, Windows Phone y Java ME) como el software del servidor (para ASP.NET y SQL Server o PHP y MySQL). El software está escrito en el idioma nativo de cada plataforma y funciona correctamente en segundo plano en cada una. Por último, el software tiene el MIT License. Usted puede encontrar el cliente de Android aquí:

https://github.com/nickfox/GpsTracker/tree/master/phoneClients/android

32

Dado que no me gustaba una parte del código en las otras respuestas, aquí está mi solución simple. Esta solución está destinada a ser utilizada en una Actividad o Servicio para rastrear la ubicación. Se asegura de que nunca devuelva datos demasiado obsoletos a menos que solicite datos obsoletos. Se puede ejecutar en modo de devolución de llamada para obtener actualizaciones a medida que las recibimos, o en el modo de encuesta para sondear la información más reciente.

Interfaz de LocalTracker genérica. Nos permite disponer de múltiples tipos de rastreadores ubicación y enchufe el apropiado con facilidad:

package com.gabesechan.android.reusable.location; 

import android.location.Location; 

public interface LocationTracker { 
    public interface LocationUpdateListener{ 
     public void onUpdate(Location oldLoc, long oldTime, Location newLoc, long newTime); 
    } 

    public void start(); 
    public void start(LocationUpdateListener update); 

    public void stop(); 

    public boolean hasLocation(); 

    public boolean hasPossiblyStaleLocation(); 

    public Location getLocation(); 

    public Location getPossiblyStaleLocation(); 

} 

ProviderLocationTracker- esta clase realizará el seguimiento de la ubicación, ya sea para GPS o red.

package com.gabesechan.android.reusable.location; 

import android.content.Context; 
import android.location.Location; 
import android.location.LocationListener; 
import android.location.LocationManager; 
import android.os.Bundle; 

public class ProviderLocationTracker implements LocationListener, LocationTracker { 

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

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

    private LocationManager lm; 

    public enum ProviderType{ 
     NETWORK, 
     GPS 
    };  
    private String provider; 

    private Location lastLocation; 
    private long lastTime; 

    private boolean isRunning; 

    private LocationUpdateListener listener; 

    public ProviderLocationTracker(Context context, ProviderType type) { 
     lm = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE); 
     if(type == ProviderType.NETWORK){ 
      provider = LocationManager.NETWORK_PROVIDER; 
     } 
     else{ 
      provider = LocationManager.GPS_PROVIDER; 
     } 
    } 

    public void start(){ 
     if(isRunning){ 
      //Already running, do nothing 
      return; 
     } 

     //The provider is on, so start getting updates. Update current location 
     isRunning = true; 
     lm.requestLocationUpdates(provider, MIN_UPDATE_TIME, MIN_UPDATE_DISTANCE, this); 
     lastLocation = null; 
     lastTime = 0; 
     return; 
    } 

    public void start(LocationUpdateListener update) { 
     start(); 
     listener = update; 

    } 


    public void stop(){ 
     if(isRunning){ 
      lm.removeUpdates(this); 
      isRunning = false; 
      listener = null; 
     } 
    } 

    public boolean hasLocation(){ 
     if(lastLocation == null){ 
      return false; 
     } 
     if(System.currentTimeMillis() - lastTime > 5 * MIN_UPDATE_TIME){ 
      return false; //stale 
     } 
     return true; 
    } 

    public boolean hasPossiblyStaleLocation(){ 
     if(lastLocation != null){ 
      return true; 
     } 
     return lm.getLastKnownLocation(provider)!= null; 
    } 

    public Location getLocation(){ 
     if(lastLocation == null){ 
      return null; 
     } 
     if(System.currentTimeMillis() - lastTime > 5 * MIN_UPDATE_TIME){ 
      return null; //stale 
     } 
     return lastLocation; 
    } 

    public Location getPossiblyStaleLocation(){ 
     if(lastLocation != null){ 
      return lastLocation; 
     } 
     return lm.getLastKnownLocation(provider); 
    } 

    public void onLocationChanged(Location newLoc) { 
     long now = System.currentTimeMillis(); 
     if(listener != null){ 
      listener.onUpdate(lastLocation, lastTime, newLoc, now); 
     } 
     lastLocation = newLoc; 
     lastTime = now; 
    } 

    public void onProviderDisabled(String arg0) { 

    } 

    public void onProviderEnabled(String arg0) { 

    } 

    public void onStatusChanged(String arg0, int arg1, Bundle arg2) { 
    } 
} 

El es el FallbackLocationTracker, que hará un seguimiento tanto por GPS y la red, y utilizar cualquier ubicación es más precisa.

package com.gabesechan.android.reusable.location; 

import android.content.Context; 
import android.location.Location; 
import android.location.LocationManager; 

public class FallbackLocationTracker implements LocationTracker, LocationTracker.LocationUpdateListener { 


    private boolean isRunning; 

    private ProviderLocationTracker gps; 
    private ProviderLocationTracker net; 

    private LocationUpdateListener listener; 

    Location lastLoc; 
    long lastTime; 

    public FallbackLocationTracker(Context context) { 
     gps = new ProviderLocationTracker(context, ProviderLocationTracker.ProviderType.GPS); 
     net = new ProviderLocationTracker(context, ProviderLocationTracker.ProviderType.NETWORK); 
    } 

    public void start(){ 
     if(isRunning){ 
      //Already running, do nothing 
      return; 
     } 

     //Start both 
     gps.start(this); 
     net.start(this); 
     isRunning = true; 
    } 

    public void start(LocationUpdateListener update) { 
     start(); 
     listener = update; 
    } 


    public void stop(){ 
     if(isRunning){ 
      gps.stop(); 
      net.stop(); 
      isRunning = false; 
      listener = null; 
     } 
    } 

    public boolean hasLocation(){ 
     //If either has a location, use it 
     return gps.hasLocation() || net.hasLocation(); 
    } 

    public boolean hasPossiblyStaleLocation(){ 
     //If either has a location, use it 
     return gps.hasPossiblyStaleLocation() || net.hasPossiblyStaleLocation(); 
    } 

    public Location getLocation(){ 
     Location ret = gps.getLocation(); 
     if(ret == null){ 
      ret = net.getLocation(); 
     } 
     return ret; 
    } 

    public Location getPossiblyStaleLocation(){ 
     Location ret = gps.getPossiblyStaleLocation(); 
     if(ret == null){ 
      ret = net.getPossiblyStaleLocation(); 
     } 
     return ret; 
    } 

    public void onUpdate(Location oldLoc, long oldTime, Location newLoc, long newTime) { 
     boolean update = false; 

     //We should update only if there is no last location, the provider is the same, or the provider is more accurate, or the old location is stale 
     if(lastLoc == null){ 
      update = true; 
     } 
     else if(lastLoc != null && lastLoc.getProvider().equals(newLoc.getProvider())){ 
      update = true; 
     } 
     else if(newLoc.getProvider().equals(LocationManager.GPS_PROVIDER)){ 
      update = true; 
     } 
     else if (newTime - lastTime > 5 * 60 * 1000){ 
      update = true; 
     } 

     if(update){ 
      if(listener != null){ 
       listener.onUpdate(lastLoc, lastTime, newLoc, newTime);     
      } 
      lastLoc = newLoc; 
      lastTime = newTime; 
     } 

    } 
} 

Dado que ambos implementan la interfaz de LocationTracker, puede cambiar fácilmente de opinión sobre cuál usar. Para ejecutar la clase en modo encuesta, solo llame a start(). Para ejecutarlo en modo de actualización, llame a start (Listener).

también echar un vistazo a mi blog post en el código

+0

Para alguien curioso: la razón por la que no uso los tiempos integrados en el objeto Ubicación es porque la API no existe hasta la API 17. Como quiero mantener la compatibilidad en 14, solo uso la hora actual. También es por eso que no llamo getLastKnownLocation temprano, porque no podemos obtener un momento y ver si está desactualizado. –

+0

Su código es la mejor y más completa solución que he encontrado en los últimos dos días de búsqueda sobre este tema. Funciona sin errores y, como un amuleto, es impresionante. Solo una cosa, cambié FallbackLocationTracker (Contexto contextual, tipo ProviderType), a público FallbackLocationTracker (Contexto contextual) ya que no necesitamos enviar un proveedor a esta clase, tiene en cuenta tanto el GPS como la Red, ¿estoy en lo cierto? – zeeshan

+0

@zeeshan Estás en lo correcto, y actualicé el código aquí. Lo haré en mi blog la próxima vez que encuentre algo de tiempo (un recurso difícil de conseguir para mí en estos días). Como probablemente hayas adivinado, creé el repliegue copiando las copias de la otra clase y nunca hice esa limpieza. –

3

Para comprobar simplemente ubicación puede utilizar el código siguiente. Puedes ponerlo en tu onStart() de actividad principal y mostrar el cuadro de diálogo de alerta si return es falso.

private boolean isLocationAccurate() 
    { 
     if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) 
     { 
      String provider = Settings.Secure 
        .getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED); 
      if (provider != null && !provider.contains("gps")) 
      { 
       return false; 
      } 
     } 
     else 
     { 
      try 
      { 
       int status = Settings.Secure 
         .getInt(this.getContentResolver(), Settings.Secure.LOCATION_MODE); 
       if (status != Settings.Secure.LOCATION_MODE_HIGH_ACCURACY) 
       { 
        return false; 
       } 
      } 
      catch (Settings.SettingNotFoundException e) 
      { 
       Log.e(TAG, e.getMessage()); 
      } 
     } 

     return true; 
    } 
14

obtener la ubicación de GPS por -

LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); 

LocationListener locationListener = new LocationListener() 
{ 

      @Override 
      public void onStatusChanged(String provider, int status, Bundle extras) { 
       // TODO Auto-generated method stub 

      } 

      @Override 
      public void onProviderEnabled(String provider) { 
       // TODO Auto-generated method stub 

      } 

      @Override 
      public void onProviderDisabled(String provider) { 
       // TODO Auto-generated method stub 

      } 

      @Override 
      public void onLocationChanged(Location location) { 
       // TODO Auto-generated method stub 
       double latitude = location.getLatitude(); 
       double longitude = location.getLongitude(); 
       double speed = location.getSpeed(); //spedd in meter/minute 
       speed = (speed*3600)/1000;  // speed in km/minute    Toast.makeText(GraphViews.this, "Current speed:" + location.getSpeed(),Toast.LENGTH_SHORT).show(); 
      } 
     }; 

     locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener); 

} 
+2

El objetivo es siempre un código menos preciso y no exagerar la verificación de ubicación simple como muchas otras respuestas. Gracias por responder la pregunta que se hizo. – SmulianJulian

+0

welcome @SmulianJulian –

+0

Cómo obtener ubicación cada 1 segundo –

12

Es necesario utilizar más reciente/más reciente

GoogleApiClient Api

Básicamente lo que hay que hacer es:

private GoogleApiClient mGoogleApiClient; 
mGoogleApiClient = new GoogleApiClient.Builder(this) 
       .addApi(LocationServices.API) 
       .addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this) 
       .build(); 

Entonces

@Override 
    public void onConnected(Bundle connectionHint) { 
     mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
       mGoogleApiClient); 
     if (mLastLocation != null) { 
      mLatitudeText.setText(String.valueOf(mLastLocation.getLatitude())); 
      mLongitudeText.setText(String.valueOf(mLastLocation.getLongitude())); 
     } 
    } 

para la ubicación más exacta y fiable. Ver mi post aquí:

https://stackoverflow.com/a/33599228/2644905

No utilice LocationListener que no es exacta y ha retrasado la respuesta. Para ser sincero, esto es más fácil de implementar. Lea también la documentación: https://developers.google.com/android/reference/com/google/android/gms/common/api/GoogleApiClient

+1

Esta es la mejor respuesta para la última API. – dramzy

+0

Sí. Esta es la forma correcta de hacerlo, en estos días. @nickfox proporcionó algunos buenos enlaces en [su segunda respuesta a esta pregunta] (http://stackoverflow.com/a/21545885/178433), de los creadores originales de la API de servicios de ubicación, que vale la pena consultar. – gMale

5

LocationManager es una clase que proporciona métodos in-build para conseguir última saben ubicación

PASO 1: Crear un objeto LocationManager como a continuación

LocationManager locationManager = (LocationManager) context.getSystemService (Context.LOCATION_SERVICE);

Paso 2: Agregar criterios

*Criteria is use for setting accuracy* 

Criteria criteria = new Criteria(); 
int currentapiVersion = android.os.Build.VERSION.SDK_INT; 

if (currentapiVersion >= android.os.Build.VERSION_CODES.HONEYCOMB) { 

    criteria.setSpeedAccuracy(Criteria.ACCURACY_HIGH); 
    criteria.setAccuracy(Criteria.ACCURACY_FINE); 
    criteria.setAltitudeRequired(true); 
    criteria.setBearingRequired(true); 
    criteria.setSpeedRequired(true); 

} 

Paso 3: Proveedor Avaliable

threre dos tipos de proveedor de GPS y la red

String provider = locationManager.getBestProvider(criteria, true); 

PASO 4: Obtener Última conocemos la ubicación

Location location = locationManager.getLastKnownLocation(provider); 

PASO 5: Obtener latitud y longitud

Si ubicación objeto es nulo, entonces no trate de llamar a continuación método s

getLatitude and getLongitude is methods which returns double values

34

Ya hay muchas respuestas allí, pero quiero mostrar última forma de obtener la ubicación utilizando la API de Google, por lo que los nuevos programadores pueden utilizar nuevo método:

He escrito tutorial detallado sobre current location in android en mi blog demonuts.com También puede encontrar el código fuente completo desarrollado con android studio.

En primer lugar, poner esto en el archivo Gradle

compile 'com.google.android.gms:play-services:9.0.2' 

luego implementar interfaces necesarias

public class MainActivity extends BaseActivitiy implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener 

declaran casos

private GoogleApiClient mGoogleApiClient; 
    private Location mLocation; 
    private LocationManager locationManager; 
    private LocationRequest mLocationRequest; 

poner esto en onCreate()

mGoogleApiClient = new GoogleApiClient.Builder(this) 
       .addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this) 
       .addApi(LocationServices.API) 
       .build(); 
     locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 

Finalmente, reemplazar los métodos necesarios

@Override 
    public void onConnected(Bundle bundle) { 
     if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
      // TODO: Consider calling 
      // ActivityCompat#requestPermissions 
      // here to request the missing permissions, and then overriding 
      // public void onRequestPermissionsResult(int requestCode, String[] permissions, 
      //           int[] grantResults) 
      // to handle the case where the user grants the permission. See the documentation 
      // for ActivityCompat#requestPermissions for more details. 
      return; 
     } startLocationUpdates(); 
     mLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 
     if(mLocation == null){ 
      startLocationUpdates(); 
     } 
     if (mLocation != null) { 
      double latitude = mLocation.getLatitude(); 
      double longitude = mLocation.getLongitude(); 
     } else { 
      // Toast.makeText(this, "Location not Detected", Toast.LENGTH_SHORT).show(); 
     } 
    } 

    protected void startLocationUpdates() { 
     // Create the location request 
     mLocationRequest = LocationRequest.create() 
       .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) 
       .setInterval(UPDATE_INTERVAL) 
       .setFastestInterval(FASTEST_INTERVAL); 
     // Request location updates 
     if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
      // TODO: Consider calling 
      // ActivityCompat#requestPermissions 
      // here to request the missing permissions, and then overriding 
      // public void onRequestPermissionsResult(int requestCode, String[] permissions, 
      //           int[] grantResults) 
      // to handle the case where the user grants the permission. See the documentation 
      // for ActivityCompat#requestPermissions for more details. 
      return; 
     } 
     LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, 
       mLocationRequest, this); 
     Log.d("reque", "--->>>>"); 
    } 

    @Override 
    public void onConnectionSuspended(int i) { 
     Log.i(TAG, "Connection Suspended"); 
     mGoogleApiClient.connect(); 
    } 

    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) { 
     Log.i(TAG, "Connection failed. Error: " + connectionResult.getErrorCode()); 
    } 

    @Override 
    public void onStart() { 
     super.onStart(); 
     mGoogleApiClient.connect(); 
    } 

    @Override 
    public void onStop() { 
     super.onStop(); 
     if (mGoogleApiClient.isConnected()) { 
      mGoogleApiClient.disconnect(); 
     } 
    } 
    @Override 
    public void onLocationChanged(Location location) { 

    } 

No se olvide de iniciar el GPS en su dispositivo antes de ejecutar la aplicación.

+0

Utilicé su método para mostrar las coordenadas, pero no puedo ver las coordenadas ¿puede consultar mi [pregunta] (http://stackoverflow.com/q/42297618/6854117)? – faisal1208

+0

'mLocation' siempre da nulo. Intenté lo mismo que mencioné – DharanBro

+0

Vaya a este enlace: http://demonuts.com/2016/12/30/get-current-gps-location-android-studio/ y descargue el código fuente desde allí y compruebe si el código fuente es trabajando en tu PC o no –

3

He realizado un proyecto desde el cual podemos obtener la ubicación exacta usando Google Play Services, GPS y proveedores de red. Este proyecto se puede encontrar here.

La estrategia para encontrar la mejor ubicación es que primero obtenga la ubicación de los servicios de google play si encuentra la ubicación y compruebe si es mejor o no, si la ubicación es nula reinicie los servicios de google play e intente buscar la ubicación de Android API de ubicación Registre la ubicación en los oyentes de cambio y, cuando se encuentre la mejor ubicación, la devolución de llamada la devuelve a la actividad principal.

Es muy sencillo de utilizar y aplicar en el código de sólo dos clases que necesitamos para incrustar decir LocationManagerInterface y SmartLocationManager, LocationActivity está implementando la interfaz y el uso de SmartLocationManager a buscar ubicación.

/** 
* Created by Syed Raza Mehdi Naqvi on 8/10/2016. 
*/ 
public interface LocationManagerInterface { 
    String TAG = LocationManagerInterface.class.getSimpleName(); 

    void locationFetched(Location mLocation, Location oldLocation, String time, String locationProvider); 

} 

aquí es la clase de jefe de locación

import android.Manifest; 
import android.app.Activity; 
import android.content.Context; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.content.IntentSender; 
import android.content.pm.PackageManager; 
import android.location.Location; 
import android.location.LocationManager; 
import android.os.Build; 
import android.os.Bundle; 
import android.support.v4.app.ActivityCompat; 
import android.support.v4.content.ContextCompat; 
import android.support.v7.app.AlertDialog; 
import android.util.Log; 
import android.widget.Toast; 

import com.google.android.gms.common.ConnectionResult; 
import com.google.android.gms.common.GooglePlayServicesUtil; 
import com.google.android.gms.common.api.GoogleApiClient; 
import com.google.android.gms.location.LocationListener; 
import com.google.android.gms.location.LocationRequest; 
import com.google.android.gms.location.LocationServices; 

import java.text.DateFormat; 
import java.util.Date; 

/** 
* Created by Syed Raza Mehdi Naqvi on 8/9/2016. 
*/ 
public class SmartLocationManager implements 
     GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener { 

    private static final String TAG = SmartLocationManager.class.getSimpleName(); 

    private static final int TWO_MINUTES = 1000 * 60 * 2; 
    private static final int PERMISSION_REQUEST_CODE = 1000; 
    private static final int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000; 

    // default value is false but user can change it 
    private String mLastLocationUpdateTime;               // fetched location time 
    private String locationProvider;                // source of fetched location 

    private Location mLastLocationFetched;               // location fetched 
    private Location mLocationFetched;                // location fetched 
    private Location networkLocation; 
    private Location gpsLocation; 

    private int mLocationPiority; 
    private long mLocationFetchInterval; 
    private long mFastestLocationFetchInterval; 

    private Context mContext;                  // application context 
    private Activity mActivity;                  // activity context 
    private LocationRequest mLocationRequest; 
    private GoogleApiClient mGoogleApiClient; 
    private LocationManagerInterface mLocationManagerInterface; 

    private android.location.LocationManager locationManager; 
    private android.location.LocationListener locationListener; 

    boolean isGPSEnabled; 
    boolean isNetworkEnabled; 

    private int mProviderType; 
    public static final int NETWORK_PROVIDER = 1; 
    public static final int ALL_PROVIDERS = 0; 
    public static final int GPS_PROVIDER = 2; 

// private final double STANDARD_LOCATION_ACCURACY = 100.0; 
// private final double STANDARD_LOCATION_SEED_LIMIT = 6.95; 

    public static final int LOCATION_PROVIDER_ALL_RESTICTION = 1; 
    public static final int LOCATION_PROVIDER_RESTRICTION_NONE = 0; 
    public static final int LOCATION_PROVIDER_GPS_ONLY_RESTICTION = 2; 
    public static final int LOCATION_PROVIDER_NETWORK_ONLY_RESTICTION = 3; 
    private int mForceNetworkProviders = 0; 

    public SmartLocationManager(Context context, Activity activity, LocationManagerInterface locationInterface, int providerType, int locationPiority, long locationFetchInterval, long fastestLocationFetchInterval, int forceNetworkProviders) { 
     mContext = context; 
     mActivity = activity; 
     mProviderType = providerType; 

     mLocationPiority = locationPiority; 
     mForceNetworkProviders = forceNetworkProviders; 
     mLocationFetchInterval = locationFetchInterval; 
     mFastestLocationFetchInterval = fastestLocationFetchInterval; 

     mLocationManagerInterface = locationInterface; 

     initSmartLocationManager(); 
    } 


    public void initSmartLocationManager() { 

     // 1) ask for permission for Android 6 above to avoid crash 
     // 2) check if gps is available 
     // 3) get location using awesome strategy 

     askLocationPermission();       // for android version 6 above 
     checkNetworkProviderEnable(mForceNetworkProviders);      // 

     if (isGooglePlayServicesAvailable())    // if googleplay services available 
      initLocationObjts();       // init obj for google play service and start fetching location 
     else 
      getLocationUsingAndroidAPI();     // otherwise get location using Android API 
    } 

    private void initLocationObjts() { 
     // Create the LocationRequest object 
     mLocationRequest = LocationRequest.create() 
       .setPriority(mLocationPiority) 
       .setInterval(mLocationFetchInterval)     // 10 seconds, in milliseconds 
       .setFastestInterval(mFastestLocationFetchInterval);  // 1 second, in milliseconds 

     if (mGoogleApiClient == null) { 
      mGoogleApiClient = new GoogleApiClient.Builder(mActivity) 
        .addConnectionCallbacks(this) 
        .addOnConnectionFailedListener(this) 
        .addApi(LocationServices.API) 
        .build(); 
     } 

     startLocationFetching();          // connect google play services to fetch location 
    } 

    @Override 
    public void onConnected(Bundle connectionHint) { 
     Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 
     startLocationUpdates(); 
     if (location == null) { 
      LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); 
      getLocationUsingAndroidAPI(); 
     } else { 
      setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched); 
     } 
    } 

    @Override 
    public void onLocationChanged(Location location) { 
     if (location == null) { 
      getLastKnownLocation(); 
     } else { 
      setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched); 
     } 
    } 

    @Override 
    public void onConnectionSuspended(int i) { 
     Log.i(TAG, "Connection suspended"); 
    } 

    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) { 
     if (connectionResult.hasResolution()) { 
      try { 
       connectionResult.startResolutionForResult(mActivity, CONNECTION_FAILURE_RESOLUTION_REQUEST); // Start an Activity that tries to resolve the error 
       getLocationUsingAndroidAPI();                // try to get location using Android API locationManager 
      } catch (IntentSender.SendIntentException e) { 
       e.printStackTrace(); 
      } 
     } else { 
      Log.i(TAG, "Location services connection failed with code " + connectionResult.getErrorCode()); 
     } 
    } 

    private void setNewLocation(Location location, Location oldLocation) { 
     if (location != null) { 
      mLastLocationFetched = oldLocation; 
      mLocationFetched = location; 
      mLastLocationUpdateTime = DateFormat.getTimeInstance().format(new Date()); 
      locationProvider = location.getProvider(); 
      mLocationManagerInterface.locationFetched(location, mLastLocationFetched, mLastLocationUpdateTime, location.getProvider()); 
     } 
    } 

    private void getLocationUsingAndroidAPI() { 
     // Acquire a reference to the system Location Manager 
     locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); 

     setLocationListner(); 
     captureLocation(); 
    } 

    public void captureLocation() { 
     if (Build.VERSION.SDK_INT >= 23 && 
       ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && 
       ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
      return; 
     } 
     try { 
      if (mProviderType == SmartLocationManager.GPS_PROVIDER) { 
       locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener); 
      } else if (mProviderType == SmartLocationManager.NETWORK_PROVIDER) { 
       locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener); 
      } else { 
       locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener); 
       locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener); 
      } 
     } catch (Exception e) { 
      Log.e(TAG, e.getMessage()); 
     } 
    } 

    private void setLocationListner() { 
     // Define a listener that responds to location updates 
     locationListener = new android.location.LocationListener() { 
      public void onLocationChanged(Location location) { 
       // Called when a new location is found by the network location provider. 
       if (location == null) { 
        getLastKnownLocation(); 
       } else { 
        setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched); 
//     if (isLocationAccurate(location) && location.getAccuracy() < STANDARD_LOCATION_ACCURACY && location.getSpeed() < STANDARD_LOCATION_SEED_LIMIT) {// no use of this if 
//      setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched); 
//     } else { 
//      setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched); 
//     } 
       } 
      } 

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

      public void onProviderEnabled(String provider) { 
      } 

      public void onProviderDisabled(String provider) { 
      } 
     }; 
    } 

    public Location getAccurateLocation() { 
     if (Build.VERSION.SDK_INT >= 23 && 
       ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && 
       ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
      return null; 
     } 
     try { 
      gpsLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
      networkLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
      Location newLocalGPS, newLocalNetwork; 
      if (gpsLocation != null || networkLocation != null) { 
       newLocalGPS = getBetterLocation(mLocationFetched, gpsLocation); 
       newLocalNetwork = getBetterLocation(mLocationFetched, networkLocation); 
       setNewLocation(getBetterLocation(newLocalGPS, newLocalNetwork), mLocationFetched); 
      } 
     } catch (Exception ex) { 
      Log.e(TAG, ex.getMessage()); 
     } 
     return mLocationFetched; 
    } 

    protected void startLocationUpdates() { 
     LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); 
    } 

    public void startLocationFetching() { 
     mGoogleApiClient.connect(); 
     if (mGoogleApiClient.isConnected()) { 
      startLocationUpdates(); 
     } 
    } 

    public void pauseLocationFetching() { 
     if (mGoogleApiClient.isConnected()) { 
      LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); 
      mGoogleApiClient.disconnect(); 
     } 

    } 

    public void abortLocationFetching() { 
     mGoogleApiClient.disconnect(); 

     // Remove the listener you previously added 
     if (locationManager != null && locationListener != null) { 
      if (Build.VERSION.SDK_INT >= 23 && 
        ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && 
        ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
       return; 
      } 
      try { 
       locationManager.removeUpdates(locationListener); 
       locationManager = null; 
      } catch (Exception ex) { 
       Log.e(TAG, ex.getMessage()); 

      } 
     } 
    } 

    public void resetLocation() { 
     mLocationFetched = null; 
     mLastLocationFetched = null; 
     networkLocation = null; 
     gpsLocation = null; 
    } 

    // Android M Permission check 
    public void askLocationPermission() { 

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 


      if (ContextCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED 
        || ContextCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED 
        ) { 
       if (ActivityCompat.shouldShowRequestPermissionRationale(mActivity, Manifest.permission.ACCESS_COARSE_LOCATION) 
         || ActivityCompat.shouldShowRequestPermissionRationale(mActivity, Manifest.permission.ACCESS_FINE_LOCATION)) { 

        final AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); 
        builder.setMessage("Please allow all permissions in App Settings for additional functionality.") 
          .setCancelable(false) 
          .setPositiveButton("Allow", new DialogInterface.OnClickListener() { 
           public void onClick(@SuppressWarnings("unused") final DialogInterface dialog, @SuppressWarnings("unused") final int id) { 
            Toast.makeText(mContext, "Welcome", Toast.LENGTH_SHORT).show(); 
           } 
          }) 
          .setNegativeButton("Deny", new DialogInterface.OnClickListener() { 
           public void onClick(final DialogInterface dialog, @SuppressWarnings("unused") final int id) { 
            mActivity.finish(); 
           } 
          }); 
        final AlertDialog alert = builder.create(); 
        alert.show(); 

       } else 
        ActivityCompat.requestPermissions(mActivity, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION 
          , Manifest.permission.ACCESS_FINE_LOCATION 
        }, PERMISSION_REQUEST_CODE); 

      } 
     } 
    } 

    public void checkNetworkProviderEnable(int enforceActive) { 
     locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); 

     isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); 
     isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); 

     if (!isGPSEnabled && !isNetworkEnabled) { 
      buildAlertMessageTurnOnLocationProviders("Your location providers seems to be disabled, please enable it", "OK", "Cancel"); 
     } else if (!isGPSEnabled && mForceNetworkProviders == LOCATION_PROVIDER_GPS_ONLY_RESTICTION) { 
      buildAlertMessageTurnOnLocationProviders("Your GPS seems to be disabled, please enable it", "OK", "Cancel"); 
     } else if (!isNetworkEnabled && mForceNetworkProviders == LOCATION_PROVIDER_NETWORK_ONLY_RESTICTION) { 
      buildAlertMessageTurnOnLocationProviders("Your Network location provider seems to be disabled, please enable it", "OK", "Cancel"); 
     } 
     // getting network status 

     if (!isGPSEnabled && !isNetworkEnabled) { 
      Toast.makeText(mContext, "Location can't be fetched!", Toast.LENGTH_SHORT).show(); // show alert 
      mActivity.finish(); 
     } 
    } 

    private void buildAlertMessageTurnOnLocationProviders(String message, String positiveButtonText, String negativeButtonText) { 
     final AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); 
     builder.setMessage(message) 
       .setCancelable(false) 
       .setPositiveButton(positiveButtonText, new DialogInterface.OnClickListener() { 
        public void onClick(@SuppressWarnings("unused") final DialogInterface dialog, @SuppressWarnings("unused") final int id) { 
         Intent mIntent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS); 
         mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
         mContext.startActivity(mIntent); 
        } 
       }) 
       .setNegativeButton(negativeButtonText, new DialogInterface.OnClickListener() { 
        public void onClick(final DialogInterface dialog, @SuppressWarnings("unused") final int id) { 
         mActivity.finish(); 
        } 
       }); 
     final AlertDialog alert = builder.create(); 
     alert.show(); 
    } 


    public Location getLastKnownLocation() { 
     locationProvider = LocationManager.NETWORK_PROVIDER; 
     Location lastKnownLocation = null; 
     // Or use LocationManager.GPS_PROVIDER 
     if (Build.VERSION.SDK_INT >= 23 && 
       ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && 
       ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
      return lastKnownLocation; 
     } 
     try { 
      lastKnownLocation = locationManager.getLastKnownLocation(locationProvider); 
      return lastKnownLocation; 
     } catch (Exception e) { 
      Log.e(TAG, e.getMessage()); 
     } 
     return lastKnownLocation; 
    } 

    public boolean isGooglePlayServicesAvailable() { 
     int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(mContext); 

     if (status == ConnectionResult.SUCCESS) { 
      return true; 
     } else { 
      return false; 
     } 
    } 

    /** 
    * Determines whether one Location reading is better than the current Location fix 
    * 
    * @param location   The new Location that you want to evaluate 
    * @param currentBestLocation The current Location fix, to which you want to compare the new one 
    */ 
    protected Location getBetterLocation(Location location, Location currentBestLocation) { 
     if (currentBestLocation == null) { 
      // A new location is always better than no location 
      return location; 
     } 

     // Check whether the new location fix is newer or older 
     long timeDelta = location.getTime() - currentBestLocation.getTime(); 
     boolean isSignificantlyNewer = timeDelta > TWO_MINUTES; 
     boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES; 
     boolean isNewer = timeDelta > 0; 

     // If it's been more than two minutes since the current location, use the new location 
     // because the user has likely moved 
     if (isSignificantlyNewer) { 
      return location; 
      // If the new location is more than two minutes older, it must be worse 
     } else if (isSignificantlyOlder) { 
      return currentBestLocation; 
     } 

     // Check whether the new location fix is more or less accurate 
     int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy()); 
     boolean isLessAccurate = accuracyDelta > 0; 
     boolean isMoreAccurate = accuracyDelta < 0; 
     boolean isSignificantlyLessAccurate = accuracyDelta > 200; 

     // Check if the old and new location are from the same provider 
     boolean isFromSameProvider = isSameProvider(location.getProvider(), 
       currentBestLocation.getProvider()); 

     // Determine location quality using a combination of timeliness and accuracy 
     if (isMoreAccurate) { 
      return location; 
     } else if (isNewer && !isLessAccurate) { 
      return location; 
     } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) { 
      return location; 
     } 
     return currentBestLocation; 
    } 

    /** 
    * Checks whether two providers are the same 
    */ 

    private boolean isSameProvider(String provider1, String provider2) { 
     if (provider1 == null) { 
      return provider2 == null; 
     } 
     return provider1.equals(provider2); 
    } 

    public boolean isLocationAccurate(Location location) { 
     if (location.hasAccuracy()) { 
      return true; 
     } else { 
      return false; 
     } 
    } 

    public Location getStaleLocation() { 
     if (mLastLocationFetched != null) { 
      return mLastLocationFetched; 
     } 
     if (Build.VERSION.SDK_INT >= 23 && 
       ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && 
       ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
      return null; 
     } 
     if (mProviderType == SmartLocationManager.GPS_PROVIDER) { 
      return locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
     } else if (mProviderType == SmartLocationManager.NETWORK_PROVIDER) { 
      return locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
     } else { 
      return getBetterLocation(locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER), locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)); 
     } 
    } 
} 

podemos usarlo con una actividad o un fragmento, aquí lo estoy usando con la actividad

import android.location.Location; 
import android.os.Bundle; 
import android.support.v7.app.AppCompatActivity; 
import android.widget.TextView; 
import android.widget.Toast; 

import com.example.raza.locationaware.location.LocationManagerInterface; 
import com.example.raza.locationaware.location.SmartLocationManager; 
import com.google.android.gms.location.LocationRequest; 

public class LocationActivity extends AppCompatActivity implements LocationManagerInterface { 

    public static final String TAG = LocationActivity.class.getSimpleName(); 

    SmartLocationManager mLocationManager; 
    TextView mLocalTV, mLocationProviderTV, mlocationTimeTV; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_location); 
     mLocationManager = new SmartLocationManager(getApplicationContext(), this, this, SmartLocationManager.ALL_PROVIDERS, LocationRequest.PRIORITY_HIGH_ACCURACY, 10 * 1000, 1 * 1000, SmartLocationManager.LOCATION_PROVIDER_RESTRICTION_NONE); // init location manager 
     mLocalTV = (TextView) findViewById(R.id.locationDisplayTV); 
     mLocationProviderTV = (TextView) findViewById(R.id.locationProviderTV); 
     mlocationTimeTV = (TextView) findViewById(R.id.locationTimeFetchedTV); 
    } 

    protected void onStart() { 
     super.onStart(); 
     mLocationManager.startLocationFetching(); 
    } 

    protected void onStop() { 
     super.onStop(); 
     mLocationManager.abortLocationFetching(); 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     mLocationManager.pauseLocationFetching(); 
    } 

    @Override 
    public void locationFetched(Location mLocal, Location oldLocation, String time, String locationProvider) { 
     Toast.makeText(getApplication(), "Lat : " + mLocal.getLatitude() + " Lng : " + mLocal.getLongitude(), Toast.LENGTH_LONG).show(); 
     mLocalTV.setText("Lat : " + mLocal.getLatitude() + " Lng : " + mLocal.getLongitude()); 
     mLocationProviderTV.setText(locationProvider); 
     mlocationTimeTV.setText(time); 
    } 
} 

creo que sirve, si puede sugerir cualquier mejora, publíquelo amablemente en git. Gracias.

4

más simples que usted puede encontrar

package com.javapapers.android.geolocationfinder; 

    import android.os.Bundle; 
    import android.app.Activity; 
    import android.content.Context; 
    import android.location.Location; 
    import android.location.LocationListener; 
    import android.location.LocationManager; 
    import android.widget.TextView; 

    import android.util.Log; 

    public class MainActivity extends Activity implements LocationListener{ 
    protected LocationManager locationManager; 
    protected LocationListener locationListener; 
    protected Context context; 
    TextView txtLat; 
    String lat; 
    String provider; 
    protected String latitude,longitude; 
    protected boolean gps_enabled,network_enabled; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    txtLat = (TextView) findViewById(R.id.textview1); 

    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); 
    } 
    @Override 
    public void onLocationChanged(Location location) { 
    txtLat = (TextView) findViewById(R.id.textview1); 
    txtLat.setText("Latitude:" + location.getLatitude() + ", Longitude:" + location.getLongitude()); 
    } 

    @Override 
    public void onProviderDisabled(String provider) { 
    Log.d("Latitude","disable"); 
    } 

    @Override 
    public void onProviderEnabled(String provider) { 
    Log.d("Latitude","enable"); 
    } 

    @Override 
    public void onStatusChanged(String provider, int status, Bundle extras) { 
    Log.d("Latitude","status"); 
    } 
    } 
2

He publicado una pequeña biblioteca que puede hacer que sea fácil de obtener los datos de localización en Android, que incluso se encarga de los permisos de ejecución de Android M.

Puede consultarlo aquí: https://github.com/julioromano/RxLocation y utilizarlo o su código fuente como ejemplos para su implementación.

+0

Es una buena solución, pero no la mejor, no funciona la mayor parte del tiempo. No obtengo resultados instantáneamente después de hacer clic en el botón. –

+0

@AsifAli Si encuentra un error, abra un problema o envíe un mensaje de prensa. –

5

Obtener actualizaciones de ubicación requiere una gran cantidad de código bolierplate en Android, lo que necesita para cuidar de

  • servicios de Google Play disponibilidad Registro,
  • actualización de Google Play Service si es viejo o no está disponible
  • Diálogo Creación de GoogleApiClient y sus devoluciones de llamada conectadas, desconectadas, etc.
  • Detención y liberación de recursos para actualizaciones de ubicación
  • Manejo Permiso de ubicación escenarios
  • Comprobación de los servicios de localización son Sí o No.
  • obtener la ubicación para lastknown no es tan fácil, ya sea
  • Retorno a la última ubicación conocida, si no conseguir ubicación después de cierta duración

Al objeto de facilitar a cabo todos estos pasos i han creado Android-EasyLocation (small android library) que se ocupará de todo esto y podrá enfocarse en la lógica de negocios.

Todo lo que necesita es extender EasyLocationActivity y necesitaba esta

requestSingleLocationFix(easyLocationRequest); 

o

requestLocationUpdates(easyLocationRequest); 

Pedido aplicación de ejemplo y los pasos aquí en https://github.com/akhgupta/Android-EasyLocation

1

Simple Buscar escribir código en En Situación Método

public void onLocationChanged(Location location) { 
    if (mCurrLocationMarker != null) { 
     mCurrLocationMarker.remove(); 
    } 


    //Place current location marker 
    LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude()); 
    MarkerOptions markerOptions = new MarkerOptions(); 
    markerOptions.position(latLng); 
    markerOptions.title("Current Position"); 
    markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)); 
    mCurrLocationMarker = mMap.addMarker(markerOptions); 

    //move map camera 
    mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng)); 
    mMap.animateCamera(CameraUpdateFactory.zoomTo(18)); 

    PolylineOptions pOptions = new PolylineOptions() 
      .width(5) 
      .color(Color.GREEN) 
      .geodesic(true); 
    for (int z = 0; z < routePoints.size(); z++) { 
     LatLng point = routePoints.get(z); 
     pOptions.add(point); 
    } 
    line = mMap.addPolyline(pOptions); 
    routePoints.add(latLng); 
} 
5

GoogleSamples tiene un ejemplo detallado utilizando la última FusedLocationProviderApi. Lamentablemente, las respuestas más votadas no están actualizadas.

siguen a los ejemplos siguientes para implementar los servicios de localización utilizando FusedLocationProviderApi

https://github.com/googlesamples/android-play-location/tree/master/LocationUpdates

https://github.com/googlesamples/android-play-location/blob/master/LocationUpdates/app/src/main/java/com/google/android/gms/location/sample/locationupdates/MainActivity.java

Cuestiones relacionadas