Windows Phone Location Service

Location information in your Windows Phone applications is managed by the Windows Phone Location Service, which allows you to use your device's Wi-Fi, GPS, or cellular network to determine location. As we discussed earlier, Microsoft lays strong emphasis on location, so much that it is a basic hardware requirement for all Windows Phones.

The main class that handles the Location Service is the GeoCoordinateWatcher class. Perform the following steps and make sure you import the DLL in your solution:

  1. Create a new Windows Phone Application project in Microsoft Visual Studio 2010 Express for Windows Phone by selecting the Visual C# template. Name it PhoneApp1 as shown in the following screenshot:
    Windows Phone Location Service
  2. Now select your project name in Solution Explorer, and add the System.Device reference as shown in the following screenshot:
    Windows Phone Location Service
  3. In your MainPage.xaml.cs file import the following location namespace by using the using keyword:
    using System.Device.Location;
    

    Tip

    Downloading the example code

    You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

    Windows Phone Location Service

Starting and using the Location Service

Now that we know how to import the Location Service, let us now learn how to start using it.

To start the Location Service, the Start method of the GeoCoordinateWatcher class needs to be called. Continuing from our previous example, open the MainPage.xaml.cs file and create a variable of type GeoCoordinateWatcher in your MainPage() constructor as:

var locationManager = new GeoCoordinateWatcher();

And declare the locationManager variable in the global scope, by declaring it as a field right after the class initialization.

public partial class MainPage : PhoneApplicationPage
{
GeoCoordinateWatcher locationManager;

Now we call the Start method as:

locationManager.Start();

To quickly get the latitude/longitude data (assuming the application can access location information), add two TextBlock elements to your main XAML file (MainPage.xaml) and name them latitudeText and longitudeText respectively. This is shown in the following screenshot:

Starting and using the Location Service

Add the following code to MainPage.xaml.cs in the MainPage() constructor, after the locationManager.Start() line:

latitudeText.Text=
locationManager.Position.Location.Latitude.ToString("0.000");
longitudeText.Text =
locationManager.Position.Location.Longitude.ToString("0.000");

Running the example in the emulator will produce the following result:

Starting and using the Location Service

In the previous example, we assumed that the GPS or other location-determining hardware was ready to return the location information as soon as we requested it. However, this is not true in a real-world scenario, GPS devices may take a few seconds to get a good signal in a remote place. The GeoCoordinateWatcher class implements the StatusChanged event to handle this, returning the status (of type GeoPositionStatus), which could be any of the following based on the device's status:

Status

Description

Initialising

The Windows Phone Location Service is trying to acquire data

Ready

The Location Service is ready with data

Disabled

Service disabled or not supported

NoData

The device can fetch location information, but no data available (due to poor reception or otherwise)

We define the StatusChanged event handler function immediately after creating the locationManager variable in the MainPage() constructor as:

locationManager.StatusChanged += new
EventHandler<GeoPositionStatusChangedEventArgs>
(locationManager_getStatus);

locationManager_getStatus is our custom-defined function where we handle the statuses for the GeoCoordinateWatcher class, which is defined as:

void locationManager_getStatus(object sender,
GeoPositionStatusChangedEventArgs e)
{
switch (e.Status)
{
case GeoPositionStatus.Initializing:
statusText.Text = "Loading ...";
break;
case GeoPositionStatus.Ready:
latitudeText.Text =
locationManager.Position.Location.Latitude.ToString();
longitudeText.Text =
locationManager.Position.Location.Longitude.ToString();
statusText.Text = "Location Available";
break;
case GeoPositionStatus.Disabled:
statusText.Text = "Disabled";
break;
case GeoPositionStatus.NoData:
statusText.Text = "No Data at this time";
break;
}// end of switch
} // end of locationManager_getStatus

In most cases, you should be able to get the location; however, there could be two reasons for location being disabled:

  • The application does not have the permission for location (lock-down by carrier/ app developer or country-wise restrictions)
  • The device can access location, but the user has disabled the location services from the phone setting

We cannot help in the first case; however, in the second case we can use the Permission property of the GeoCoordinateWatcher class. Modify the GeoPositionStatus.disabled case from the previous example to the following one:

case GeoPositionStatus.Disabled:
if (locationManager.Permission == GeoPositionPermission.Denied)
{
statusText.Text = "User has disabled location settings";
}
else
statusText.Text = "Disabled";
break;

To display the status of the Location Service, we added one more TextBlock to the UI (via the MainPage.xaml file) and named it statusText, and placed it near the footer of the app as shown in the following screenshot:

Starting and using the Location Service

There is no way to disable the location settings on the emulator yet, so we tested this example on the phone itself. The following screenshot shows how the application will behave with location settings turned off (see Chapter 1, The Location-based World on how to turn location settings on/off):

Starting and using the Location Service

You can also specify accuracy for the GeoCoordinateWatcher object by passing an argument of type GeoPositionAccuracy. There are two accuracy levels:

  • High: For highest accurate positioning information. It uses high battery power consumption.
  • Default: Optimized for power and performance.

We will modify our GeoCoordinateWatcher object to use the high accuracy level by using the following arguments at the object creation time:

locationManager = new
GeoCoordinateWatcher(GeoPositionAccuracy.High);

It is also a good practice to use the Stop() method wherever possible to turn off the Location Service when not needed, to maximize the battery life of the device.

You can find this example project in the code files for the book under Chapter 2, titled PhoneApp1.

Note

Your application must inform users on how location information is used in your app. This is part of the privacy policy Microsoft ensures for applications using location data. If you fail to provide the same, the application might be rejected.

Continuous monitoring of the Location Service

In our previous example we saw how to fetch the location data when the service is ready. We saw a simple way to access the location data from the GeoCoordinateWatcher object; however, there is another event exposed by the GeoCoordinateWatcher class – the PositionChanged event that is fired when the location service detects a change in the position of the Windows Phone device.

Let us now build our Hello Location example that uses both the StatusChanged and PositionChanged events:

  1. Open Visual Studio 2010 Express and create a new project by clicking on the File | New Project menu option. Provide the application name as Hello Location as shown in the following screenshot:
    Continuous monitoring of the Location Service
  2. Make sure to select your Target Windows Phone Platform as 7.1 as shown in the following screenshot:
    Continuous monitoring of the Location Service
  3. Add the System.Device reference library to your project and import it in your MainPage.xaml.cs file by adding the following line:
    using System.Device.Location;
    
  4. Do not forget to define the location manager in the global class context:
    GeoCoordinateWatcher locationManager;
    
  5. We add two buttons to our UI, one for starting the location service and another for stopping the same. We also add four TextBlocks, two for the latitude/longitude labels and two more for their respective values. The following screenshot shows how our UI should now look:
    Continuous monitoring of the Location Service
  6. Note the XAML view for your project and the highlighted text shown in the previous screenshot. Make sure you align the UI elements properly using the Margin property. Name the elements properly so that you can access them in your code.
    <Grid x:Name="ContentPanel" Grid.Row="1"Margin="12,0,12,0">
    <TextBlock Height="30" HorizontalAlignment="Left"
    Margin="10,575,0,0" Name="statusText" Text="Status: "
    VerticalAlignment="Top" Width="444" />
    <TextBlock Height="30" HorizontalAlignment="Left"
    Margin="12,118,0,0" Name="latitudeLabel" Text="Latitude: "
    VerticalAlignment="Top" />
    <TextBlock Height="30" HorizontalAlignment="Left"
    Margin="12,175,0,0" Name="longitudeLabel" Text="Longitude: "
    VerticalAlignment="Top" />
    <TextBlock Height="30" HorizontalAlignment="Left"
    Margin="155,118,0,0" Name="latitudeText" Text="Value"
    VerticalAlignment="Top" />
    <TextBlock Height="30" HorizontalAlignment="Left"
    Margin="155,175,0,0" Name="longitudeText" Text="Value"
    VerticalAlignment="Top" />
    <Button Content="Start" Height="72"
    HorizontalAlignment="Left" Margin="0,35,0,0"
    Name="startButton" VerticalAlignment="Top" Width="160"
    Click="startButton_Click" />
    
    <Button Content="Stop" Height="72" HorizontalAlignment="Left"
    Margin="0,256,0,0" Name="stopButton" VerticalAlignment="Top"
    Width="160" Click="stopButton_Click" />
    
    </Grid>
    
  7. Note the Click="startButton_Click" and Click="stopButton_Click" code in XAML shown in the previous step. These are click event functions that are called when the user hits the start and stop buttons. From your UI, double-clicking on the buttons will open up the code editor for modifying these function calls.
    private void startButton_Click(object sender,
    RoutedEventArgs e)
    {
    locationManager.Start();
    }
    private void stopButton_Click(object sender,
    RoutedEventArgs e)
    {
    locationManager.Stop();
    }
    
  8. We saw the StatusChanged event of the GeoCoordinateWatcher class earlier, now we will implement the PositionChanged event. In your MainPage() constructor, after creating an object locationManager of type GeoCoordinaeWatcher, we declare the PositionChanged event as:
    locationManager = new
    GeoCoordinateWatcher(GeoPositionAccuracy.High);
    
    locationManager.StatusChanged += new
    EventHandler<GeoPositionStatusChangedEventArgs>
    (locationManager_getStatus);
    locationManager.PositionChanged += new
    EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>
    (locationManager_getPosition);
    
  9. Note, for our Hello Location example, we define the accuracy as high as shown in the previous code.
  10. Now we define the locationManager_getPosition function as:
    void locationManager_getPosition(object sender,
    GeoPositionChangedEventArgs<GeoCoordinate>newLoc)
    {
    latitudeText.Text =
    newLoc.Position.Location.Latitude.ToString();
    longitudeText.Text =
    newLoc.Position.Location.Longitude.ToString();
    }
    
  11. The locationManager_getPosition function exposes the device's current location via the<GeoCoordinate> parameter in the function declaration. We use this in our implementation via the newLoc variable, and pass the current latitude and longitude values to the respective TextBlock for display.
  12. Running the Hello Location example produces the following result:
    Continuous monitoring of the Location Service
  13. Click on the Start button to get the location values from the device as shown in the following screenshot:
    Continuous monitoring of the Location Service

You can find this example project in the code files for the book under Chapter 2, titled Hello Location.

Note

We used the Nokia Lumia 800 skin on our emulator; get yours from http://www.developer.nokia.com/Community/Wiki/How_to_use_skins_of_Nokia_Lumia_on_Windows_Phone_emulator. For multiple skin choices head to http://wp7emuskinswitcher.codeplex.com/, which allows you to switch skins for a couple of phones, and yes there is a white Nokia Lumia 800 skin too!

Working with the Windows Phone location simulator

Having played with our Hello Location example app, let us now dig more into the Windows Phone location simulator to understand how we can simulate location data in our application.

Open the Hello Location example and run it in Windows Phone Emulator. The Emulator comes with an Additional Tools sidebar, which is activated from the Emulator home screen via the Additional Tools button (>>) as shown in the following screenshot:

Working with the Windows Phone location simulator

Within the Additional Tools sidebar open, select the Location tab, as shown in the following screenshot:

Working with the Windows Phone location simulator

When you run the Hello Location example, the values you get for the latitude/longitude pair by default would be 47.64483 and -122.141197, which is Microsoft's Redmond office. Playing around with the location simulator and the Hello Location application side by side, you will find the location updates happen immediately on the Hello Location app.

You can also search for places using the search input box. A cool feature of the simulator is the ability to save the maps points you have added on the maps. This can be loaded back from the saved file or by manually adding points to simulate your app behavior, by loading the saved locations file (Locations.xml in our case) and hitting the Play all points button as shown in the following screenshot:

Working with the Windows Phone location simulator

The Location.xml file is shown as follows; we added two different cities' latitude/longitude data to it and checked the Hello Location app against it.

<?xml version="1.0" encoding="utf-8"?>
<WindowsPhoneEmulator xmlns=
"http://schemas.microsoft.com/WindowsPhoneEmulator/2009/08/
SensorData">
<SensorData>
<Header version="1" />
<GpsData latitude="48.8596434322625"
longitude="1.49173867702484" />
<GpsData latitude="48.645964012732"
longitude="1.49723184108734" />
<GpsData latitude="19.0227245363093"
longitude="72.8413543701172" />
</SensorData>
</WindowsPhoneEmulator>
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.166.124