Windows Phone 8.1 位置追踪

11

我想实现一个应用程序,可以连续将设备位置发送到Web服务。在文档中查找后,我找到了Geolocation类和一些关于位置跟踪的文章:

通过实现这两篇文章中讨论的示例项目,我注意到geolocator_PositionChanged()事件并没有在每个位置更新时触发。在两次执行事件之间存在延迟(约10/15分钟)。奇怪的是,即使应用程序在前台执行(而不仅仅是在后台),这种情况也会发生。我正在使用Windows Phone模拟器。

在我的应用程序中,我有一个地图控件,需要显示用户的位置,因此我需要确保geolocator_PositionChanged()事件对于每个位置更新都能正确触发,而且没有延迟。

1)如何使用Geolocator类跟踪(无延迟)设备的位置?

在网络上搜索后,我找到了GeoCoordinateWatcher类,可以提供设备的持续位置跟踪。以下是代码:

public MainPage()
{
    InitializeComponent();
    this.GetCoordinate();
}

private void GetCoordinate()
{
    var watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High)
    {
        MovementThreshold = 1
    };
    watcher.PositionChanged += this.watcher_PositionChanged;
    watcher.Start();
}

private void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
{
    //Get position data
    var pos = e.Position.Location;
    //Update mypos object
    mypos.update(pos.Latitude, pos.Longitude);
    //Update data on the main interface
    MainMap.SetView(mypos.getCoordinate(), MainMap.ZoomLevel, MapAnimationKind.Parabolic);
}

它有效:watcher_PositionChanged()事件会立即触发,没有延迟。

2)为什么GeoCoordinateWatcher没有延迟?GeoCoordinateWatcher类和Geolocator类有什么区别?

最后,应用程序应该在不活动时将设备位置发送到Web服务。因此,我需要一个后台任务。正如Romasz在这里提出的那样,我可以使用带有某些限制的Geolocator类。

3)我可以在后台使用GeoCoordinateWhatcher吗?如果可以,怎么做?

我的目标是实现一个无延迟的位置跟踪应用程序,甚至可以在后台工作。该应用程序应该跟踪设备的位置并持续更新Web服务(即使在后台)。我该如何做?什么是最佳方法?我了解Windows Phone应用程序生命周期,并可以接受一些后台执行的限制。后台执行的限制是什么?

3个回答

11

很遗憾,Windows Phone 8.1不支持后台连续跟踪。 如果您需要此功能,您将需要开发Windows Phone 8应用程序。 希望他们会在8.2、9或下一个版本中修复此问题!


谢谢Gavin的回答。请问您能否更具体一些?是否有Microsoft的文档可以参考?如果在Windows Phone 8中可以实现,那么如何实现呢?为什么在Windows Phone 8.1中删除了这个功能? - smn.tino
在这里声明:http://msdn.microsoft.com/en-us/library/windowsphone/develop/dn642084(v=vs.105).aspx> 连续的后台执行不支持Silverlight 8.1应用程序。 - Depechie
我也找到了Silverlight 8.1的信息,但它并没有涵盖Windows Phone 8.1通用应用程序的方面,所以我继续寻找。 - Gavin
我今天做了一些测试,你是对的Gavin:位置跟踪仅适用于WP8。因此,我必须将我的应用程序降级为WP8。只有一个问题:我的WP8应用程序是否与Windows Phone 8.1兼容?我可以在WP8.1中安装并使用它吗?我在WP8.1模拟器上测试了连续跟踪,它可以工作。您知道我的WP8应用程序是否会在实际设备上(带有WP8.1)工作吗? - smn.tino
@top_broker - 是的,你的WP8应用程序可以在WP8.1上运行,不用担心 ;) - Gavin
显示剩余5条评论

6

有一种方法可以实现位置跟踪,但它有其限制。对于运动应用程序来说不够,但对于许多其他用例来说它是适合的。使用 Geofence 和带有 LocationTriggerBackgroundTask

这里是一个例子:

BackgroundAccessStatus backgroundAccessStatus = await BackgroundExecutionManager.RequestAccessAsync();

Geolocator locator = new Geolocator();
locator.DesiredAccuracyInMeters = 10;
locator.DesiredAccuracy = PositionAccuracy.High;

Geoposition currentPosition = await locator.GetGeopositionAsync(TimeSpan.FromMinutes(1),TimeSpan.FromSeconds(30));
Geocircle fenceCircle = new Geocircle(currentPosition.Coordinate.Point.Position,25);
Geofence newFence = new Geofence(GEOFENCE_NAME, fenceCircle, MonitoredGeofenceStates.Exited, false, TimeSpan.FromSeconds(1), DateTimeOffset.Now, TimeSpan.FromDays(30));
GeofenceMonitor.Current.Geofences.Add(newFence);

BackgroundTaskBuilder observerTaskBuilder = new BackgroundTaskBuilder();
observerTaskBuilder.Name = OBSERVER_TASK_NAME;
observerTaskBuilder.SetTrigger(new LocationTrigger(LocationTriggerType.Geofence));
observerTaskBuilder.TaskEntryPoint = OBSERVER_TASK_ENTRY_POINT;
observerTaskBuilder.Register();

这将添加一个以您的位置为中心,半径为25米的地理围栏圆。当您离开该指定区域时,将触发后台任务。确保将地理围栏更新到您的新位置,并在用户移动超过25米时获得通知。
但请注意,BackgroundTask不需要在您离开围栏范围后立即运行。它可能延迟几分钟(我从未注意到离开圆形后超过一分钟的延迟)。正如我所说:对于运动应用程序来说可能不够,但它可能适合您的需求。
有关更详细的信息,请参见此处: http://msdn.microsoft.com/en-us/library/windows.devices.geolocation.geofencing.aspx 有关示例项目,请参见此处: https://code.msdn.microsoft.com/windowsapps/Geofencing-and-geolocation-d7ea0ef8

备注: 我读到不建议使用小于50的半径,但在我的测试中25有效,所以最好自己检查一下。


@ThilinaAkalanka,好的,示例代码已经发布在上面了。你缺少什么? - christoph
在这个后台任务中,是否可以将位置发送到Azure移动服务? - Thilina Akalanka
@ThilinaAkalanka 实际上,我使用注册的后台任务将我的位置发送到 Azure 后端。虽然这不是移动服务,但我认为这应该可以按预期工作。 - christoph
你是怎么做到“使用注册的后台任务将位置发送到 Azure 后端”的?我在这里发了一个问题 [http://stackoverflow.com/questions/34831107/send-devices-current-location-to-azure-service-in-windows-8-1]。 - Thilina Akalanka
@ThilinaAkalanka 我曾经有一个REST/HTTP后端并使用过HttpClient。我从未使用过移动服务。你尝试使用的那种基于表格的方法对我来说是新的。也许我找到时间后可以找到一些答案。 - christoph
谢谢。运行得很好。我的更新大约每两分钟进行一次... - 130nk3r5

0

我做的和@christoph完全一样...只是我也添加了Entered事件...我的更新每2分钟发生一次,总是这样。

    Geoposition currentPosition = await locator.GetGeopositionAsync(TimeSpan.FromMinutes(1), TimeSpan.FromSeconds(30));
        Geocircle fenceCircle = new Geocircle(currentPosition.Coordinate.Point.Position, 25);
        Geofence newFence = new Geofence("CURRENT_LOC" + Guid.NewGuid(), fenceCircle, MonitoredGeofenceStates.Exited | MonitoredGeofenceStates.Entered, false, TimeSpan.FromSeconds(1), DateTimeOffset.Now, TimeSpan.FromMinutes(10));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接