In Chapter 17 you saw how a Geolocator
provides geographic location updates. In this section you see how the custom IGeoLocator
(presented in that chapter) can be used to track the location of the phone using a Map control.
The MapViewModel
class’s StartTracking
method instantiates either a GeolocatorProxy
or a MockGeoLocator
, depending on whether the class is executing within the emulator (see Listing 18.2).
When the GeoLocatorSampler
object’s PropertyChanged
event is raised, the Location
, Center
, and PositionStatus
properties are updated. Changing the Center
property changes the visible center point of the Map
control and pans the map to the new GeoCoordinate
.
An AppBarToggleButton
in the view is data-bound to the viewmodel’s ToggleTrackingCommand
property, as shown:
<u:AppBarToggleButton
Icon1Uri="/Mapping/Images/Track.png"
Icon2Uri="/Mapping/Images/TrackOff.png"
Command1="{Binding ToggleTrackingCommand}"
Text1="track"
Text2="track off"
Toggled="{Binding Tracking}" />
When executed, the command calls the StartTracking
method of the viewmodel. The StartTracking
method uses a Boolean tracking field to prevent tracking if it is already underway.
Before tracking can take place, the app prompts the user to confirm the use of location services. This is achieved by using the ViewModelBase
class’s IMessageService
. If the AskYesNoQuestion
method returns true, the location tracking is allowed to proceed.
Note
To pass the Windows Phone Marketplace Certification, your app must seek the user’s consent to use location services. Additionally, you must provide an option in the settings page of your app to allow the user to disable location services.
For more information regarding the IMessageService
see Chapter 2, “Fundamental Concepts in Windows Phone Development.”
LISTING 18.2. MapViewModel.StartTracking
Method
void StartTracking()
{
if (tracking)
{
return;
}
/* Before using geo location, it is a certification requirement
* that you seek permission from the user first. */
bool canTrack = MessageService.AskYesNoQuestion(
"Is it OK to use the geographic location system on your phone?");
if (!canTrack)
{
return;
}
IGeoLocator geoLocator
= EnvironmentValues.UsingEmulator
? new MockGeoLocator()
: (IGeoLocator)new GeolocatorProxy()
{
MovementThreshold = 20
};
sampler = new GeoLocatorSampler(geoLocator, 500);
sampler.PropertyChanged
+= (o, args) =>
{
if (sampler.Location == null)
{
return;
}
Location = sampler.Location;
Center = location;
PositionStatus = sampler.Status;
};
ZoomLevel = ZoomLevelForTracking;
geoLocator.Start();
Tracking = true;
}
During tracking, if the user taps the tracking AppBarToggleButton
, the viewmodel’s StopTracking
method is called (see Listing 18.3). This halts tracking and disposes the GeoLocatorSampler
to free resources.
LISTING 18.3. MapViewModel.StopTracking
Method
void StopTracking()
{
if (!tracking)
{
return;
}
Tracking = false;
if (sampler != null)
{
sampler.Dispose();
sampler = null;
}
}
Tapping the Track button causes the IGeoLocator
to begin raising events. The map center is moved to the location as reported by the PositionChangedEventArgs
.
18.189.189.63