我正在使用the official site中的代码,并且我一直在多个测试设备上看到相同的行为 - 它不是获取设备的当前位置,而是获取之前的位置(距离最远30英里) ,我一小时前的地方)。
private void setupMaps()
{
watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);
watcher.MovementThreshold = 10.0f;
watcher.StatusChanged += new EventHandler<GeoPositionStatusChangedEventArgs>(watcher_statusChanged);
watcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged);
new Thread(startLocServInBackground).Start();
}
void startLocServInBackground()
{
watcher.TryStart(true, TimeSpan.FromSeconds(60));
}
void watcher_statusChanged(object sender, GeoPositionStatusChangedEventArgs e)
{
switch (e.Status)
{
case GeoPositionStatus.Disabled:
// The Location Service is disabled or unsupported.
// Check to see if the user has disabled the location service.
if (watcher.Permission == GeoPositionPermission.Denied)
{
// the user has disabled LocServ on their device.
showMessage("Location is required but it is disabled. Turn it on in Settings");
}
else
{
showMessage("Location is not functioning on this phone. Sorry, Crux cannot run");
}
break;
case GeoPositionStatus.Initializing:
// The location service is initializing.
LoadingInfo.Text = "finding location";
break;
case GeoPositionStatus.NoData:
// The Location Service is working, but it cannot get location data
// due to poor signal fidelity (most likely)
// this fired intermittently when data was coming back :/
//MessageBox.Show("Location data is not available.");
break;
case GeoPositionStatus.Ready:
// The location service is working and is receiving location data.
//statusTextBlock.Text = "Location data is available.";
LoadingInfo.Text = "Location found";
// THIS FIRES AFTER POSITION CHANGED HAS STOPPED FIRING
break;
}
}
private void initPostPanel()
{
PostPanel.Visibility = Visibility.Visible;
}
void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
{
// update the textblock readouts.
latitude = e.Position.Location.Latitude.ToString("0.0000000000");
longitude = e.Position.Location.Longitude.ToString("0.0000000000");
// THIS FIRES TWICE, BEFORE STATUS IS FIRED AS READY. THEN THIS DOESN'T CALL AGAIN
}
我期望发生的事情是在状态为就绪状态下调用StatusChanged后,连续一系列调用PositionChanged。如果在Ready之后呼叫继续,我希望我最终会得到正确的坐标 - 但是在那之后它永远不会调用。
仿真器不会出现这种情况,只会在实际设备上发生(这使得测试非常困难 - 因为它实际上涉及在每次测试之间进行驱动!)
我也在运行教程中的源代码,它大致相同。
任何人都可以告诉我更多关于此处的预期行为以及我如何得到我需要的东西 - 这只是当使用该应用时当前位置的设备坐标集。
答案 0 :(得分:2)
我自己也有同样的问题 - 这有两个部分。
原来GeoCoordinateWatcher返回最后一个已知的好位置 - 几乎总是过时的。我做的是这样的: 检查状态是否为GeoPositionStatus.Ready,然后确保该位置的日期时间是最近的(在最后5分钟内)。然后你可以进一步检查e.Position.Location.HorizontalAccuracy&lt; = 350(所以在350米以下) - 但是使用日期时间检查这样做会导致手机需要很长时间才能获得较低的位置设置准确性,因此最好通过日期检查获得初始位置,然后继续尝试通过准确性检查获得更好的位置。一旦应用程序开始获得更快的结果,我也会启动观察者。
另一个问题是MovementThreshold。如果按照我上面的说法进行操作,在获得准确位置之前可能还需要一段时间,并且您可能会遇到第二次无法触发的间歇性问题(最终会出现这种情况,具体取决于您等待多长时间 - 这可能是几分钟)。我发现的最好的事情是启动GeoCoordinateWatcher并将阈值设置为0.一旦你有一个准确的位置,停止观察者,将阈值设置为你想要的实际值(例如10),然后再次启动它。如果您先设置此项而不先停止,则不会使用新值。
<!-- language: c# -->
GeoPositionStatus = CurrentGeoDeviceStatus;
static void geoCoordWatcher_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e)
{
CurrentGeoDeviceStatus = e.Status;
}
void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
{
if (gpsReady && e.Position.Timestamp.DateTime.AddMinutes(5) > DateTime.Now)
{
latitude = e.Position.Location.Latitude.ToString("0.0000000000");
longitude = e.Position.Location.Longitude.ToString("0.0000000000");
locReady = true;
}
}
答案 1 :(得分:0)
看起来修复是阻止它使用第一个值并从第二个事件中获取它:
bool gpsReady = false;
void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
{
if (gpsReady)
{
latitude = e.Position.Location.Latitude.ToString("0.0000000000");
longitude = e.Position.Location.Longitude.ToString("0.0000000000");
locReady = true;
}
gpsReady = true;
}
我仍然感到困惑的是为什么我没有得到更多的事件或为什么它首先触发错误的值,但上面的代码似乎正在运作。
对于其他尝试此操作的人来说,其中一个注意事项是,您可能会认为获取StatusChanged事件中的值会起作用,如下所示:
case GeoPositionStatus.Ready:
latitude = watcher.Position.Location.Latitude.ToString("0.0000000000");
longitude = watcher.Position.Location.Longitude.ToString("0.0000000000");
break;
我不知道为什么,但是当我运行连接到调试器然后经常挂起(即事件永远不会被触发,我的UI似乎挂起)时,上面的代码似乎工作得很完美。我连接到调试器时从未设法重现该问题。
更新:看起来这一直无法正常工作。在某些情况下,它不会第二次触发,因此我的代码永远不会完成运行。如果有人可以提供更多关于此的信息让我更接近于简单地确保设备的实际当前位置,我肯定会将您的答案标记为答案。谢谢!