简体   繁体   中英

Windows Phone 8.1 location-tracking

I want to realize an App that continuously send device's position to a web service. Looking in the documentation, I've found Geolocation class and some articles where position-tracking is discussed:

Implementing both example projects discussed in these articles, I've noticed that the geolocator_PositionChanged() event is not fired at every position update. There is a delay (about 10/15 minutes) between 2 execution of the event. The strange thing is that this happens even when the App executes in foreground (not only in background). I'm using Windows Phone emulator.

In my App I have a map control where I need to show user's position and, so, I need that the geolocator_PositionChanged() event be correctly fired for each position update, without delays.

1) How can I track (without delays) the device's position using Geolocator class?

Searching over the network, I've found the GeoCoordinateWatcher class, that provides continuosly position-tracking of the device. This is the code:

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

It works: watcher_PositionChanged() event is fired without delays.

2) Why the GeoCoordinateWatcher does not have delays? What is the difference between GeoCoordinateWatcher class and Geolocator class?

Finally, the App should send device's position to the web service even when it is not active. So, I need a background task. As proposed here by Romasz, I can use Geolocator class with some limitations.

3) Can I use GeoCoordinateWhatcher in background? If yes, how?

My goal is to realize a position-tracking App without delays, that even works in background. What is the best way to do this? The App should track the device's position and continuously update the web service (even when in background). How can I do this? What is the best approach? I know about the Windows Phone Apps lifecycle and I can accept some limitations for the background execution. What are the background limits?

Unfortunately Windows Phone 8.1 doesn't support continuous tracking in the background. If you want this feature you'll have to develop a Windows Phone 8 app instead. Hopefully they'll fix this for 8.2, 9 or whatever's next!

There is a way you can achieve a location tracking, but it has its limitations. It won´t be enough for a sports app, but for many other use cases it will fit. Use Geofence and a BackgroundTask with LocationTrigger

Here an example:

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

This will add a geofence circle with the center of your position and a radius of 25 meter. When you exit that specified area the background task is triggered. Make sure you update the geofence to your new position and you will be informed when ever the user moves more than 25 meter.

But keep in mind that the BackgroundTask must not need to run as soon as you leave the bounds of the fence. It could have a delay up to a few minutes (I never noticed a delay of more than a minute after I left the circle). As I said: not enough for a sports app but it may suits your needs.

For more detailed information look here: http://msdn.microsoft.com/en-us/library/windows.devices.geolocation.geofencing.aspx

For a sample project look here: https://code.msdn.microsoft.com/windowsapps/Geofencing-and-geolocation-d7ea0ef8

Remarks: I read that it is highly recommended to not use a radius smaller than 50. But in my tests 25 worked well, so you better check that yourself as well.

I did exactly the same as @christoph... I just added the Entered event as well... My updates occurs every 2 minutes, ALWAYS.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM