Datos de ubicación incorrecta de Android GPS en consulta

No estoy usando ubicaciones simuladas para esto … De hecho, el código funcionaba bien la semana pasada.

Tengo una aplicación que reúne datos de GPS y escupe un enlace de Google Maps usando las coordenadas X, Y generadas por la aplicación en sí. No estoy 100% seguro de por qué no funciona como debería pero cuando solicito la aplicación para hacer un enlace de Google Maps basado en la ubicación del GPS proporcionada por el teléfono, me dice que estoy a 5 – 6 cuadras de mi punto de origen (donde en realidad estoy en ese momento) No es exactamente lo que quiero que haga

Knowns:

  • Tengo los permisos adecuados configurados
  • Todo el código funcionó la semana pasada bien

Aquí está el código para recostackr la información del GPS:

Toast.makeText(context, "Gathering GPS Data...", Toast.LENGTH_SHORT).show(); gps = new gpsTracker(Settings.this); if(gps.canGetLocation()){ try{ gps.getLocation(); lon = gps.getLongitude(); lat = gps.getLatitude(); Toast.makeText(getApplicationContext(), "Your location is - \nlat: " + lat + "\nlon: " + lon, Toast.LENGTH_LONG).show(); } catch(Exception e){} } else{ gps.showSettingsAlert(); } 

La clase de todo lo anterior está extrayendo de:

 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; } 

De lo que se especifica [diferencia de 4-5 bloques], puede obtener la location únicamente de networkProvider .

Con este código gpsTracker mencionado en la pregunta,
se requieren algunas modificaciones, en lugar de usar el código tal como está:

1. Hay 2 bucles if que verifican que la fuente de la location esté habilitada o no y No ‘ else ‘:

  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(); } } } } 

Esto significa que la aplicación hará el doble del trabajo cuando pueda obtener la location de ambas fonts. Además, la fuente de location obtenida siempre permanece ambigua.

Esto es bueno cuando solo necesitas una location aproximada que no debería ser nula de manera importante.

Si desea usar solo esta clase para obtener la location , intente estructurar el if-else acuerdo con los requisitos y asegúrese de que no se repita si se obtiene la location .
P.ej. si el GPS tiene una preferencia más alta, se aplica en su caso, cambie eso if arriba y ponga la condición de la red con otra else como:

 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(); } } } } else 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(); } } } 

Para su requerimiento, sugiero eliminar la parte del proveedor de la red y obtener la location solo del GPS, especialmente si la línea de visión no es un problema.

Cuando el código funcionaba correctamente, debe buscar la ubicación del GPS y configurarla en el objeto. Pero debido a los dos ” if ” y “ningún else “, nunca sabrá si la location obtenida es de red o GPS: puede verificar location.getProvider () dentro de la condición de canGetLocation()

2. Además, puede registrar el mensaje o solicitar alguna acción para una fuente en particular … como:
En esta parte:

  if (!isGPSEnabled && !isNetworkEnabled) { // no network provider is enabled } 

solo sepárelo en dos if (s) diferentes y codifique en consecuencia. A partir de ahora, no sucede nada aquí, por lo que no sabría si ambos están deshabilitados a menos que lo verifique externamente.

Sugerencia: pruebe el LocationClient que usa GooglePlayServices para recuperar la ubicación actual . Lo he encontrado más confiable y útil. Verifique este ejemplo de proveedor de ubicación fusionada , estableciendo el objeto LocationRequest de acuerdo con sus requisitos es la clave.

Otra actualización: acaba de encontrar: preguntas útiles sobre el desbordamiento de stack: una buena forma de obtener la ubicación de los usuarios


Actualización para cualquiera que busque esta pregunta / respuesta
En cuanto a la sugerencia de LocationClient;
LocationClient ya no se encuentra en com.google.android.gms.location , consulte:
Android play services 6.5: LocationClient falta

Debería consultar http://developer.android.com/guide/topics/location/strategies.html . Existen algunas buenas estrategias para obtener ubicaciones precisas en esta página. Aquí hay un código de ejemplo que he tomado del sitio:

 private static final int TWO_MINUTES = 1000 * 60 * 2; /** 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); }