Android GPS在查询中的位置数据不正确

我没有使用这个模拟位置…事实上,上个星期的代码工作正常。

我有一个应用程序,收集GPS数据,并吐出一个谷歌地图链接使用应用程序本身生成的X,Y坐标。 我不是100%确定它为什么不按照它应该的方式工作,但是当我要求应用程序根据手机提供的GPS位置创build谷歌地图链接时,它告诉我我距离我的5到6个街区起源(我当时在哪里)不是我想做的事情

的已知,:

  • 我有适当的权限设置
  • 所有的代码上周工作得很好

以下是收集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(); } 

以上所有课程都是从以下课程中抽取的:

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

Solutions Collecting From Web of "Android GPS在查询中的位置数据不正确"

从指定的[4-5块的差异],您可能只从networkProvider获取location

有了这个问题中提到的这个gpsTracker代码,
有一些需要的修改,而不是像这样使用代码:

1.有2个循环validationlocation的来源是否启用, 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(); } } } } 

这意味着应用程序将从两个来源获取location时执行两次工作。 此外,获得的location源始终保持不明确。

这是很好的,当你只需要大致的location ,不应该为空。

如果只想使用这个类来获取location ,可以尝试根据需要构造if-else ,并确保在获取location不会重复。
例如。 如果GPS具有更高的优先级,则适用于您的情况, if以上情况发生移动,并将networking状况与else类似:

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

为了您的要求,我build议删除networking提供商的一部分,并从GPS获得的location ,特别是如果视线不是问题。

当你的代码工作正常时,它必须从GPS获取位置并将其设置在对象中。 但是由于两个“ if ”而不是“ else ”,你永远不知道获得的location是来自Network还是GPS–你可以在canGetLocation()的条件内检查location.getProvider canGetLocation()

另外,你可以logging消息或者提示某个特定源的某个动作…例如:
在这个部分:

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

只要把它分成两个不同的if (s)和相应的代码。 到目前为止,这里什么也没有发生,所以你不知道两者是否被禁用,除非你在外部检查。

build议:尝试使用GooglePlayServices 检索当前位置的LocationClient 。 我发现它更可靠和有用。 检查此Fused Location Provider示例 ,根据您的要求设置LocationRequest对象是关键。

另一个更新:刚刚碰到: 堆栈溢出有用的问题 – 获取用户位置的好方法


更新任何人查找这个问题/答案
关于LocationClient的build议;
com.google.android.gms.location下找不到LocationClient,请参阅:
Android播放服务6.5:LocationClient丢失

你应该看看http://developer.android.com/guide/topics/location/strategies.html 。 有一些很好的策略,以获得在这个网页上的准确位置。 以下是我从站点获取的一些示例代码:

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