Interested in writing a location-aware app with .Net? This excerpt from Kiriaty, Moroney, Goldshtein, & Fliess' Introducing Windows® 7 for Developers will get you started on your way.
Throughout the book, we used the Windows API Code Pack for the .NET Framework as our main .NET library for supporting new Windows 7 features. We used the Windows API Code Pack in Chapter 9, Introduction to the Sensor and Location Platform to work with the Sensor API. Unlike the Sensor API, the .NET version of the Location API was left out of the Windows API Code Pack. However, there is a set of .NET Location API wrappers that can be found on the Sensor and Location Web page on MSDN Developer for Windows 7 Web site (http://code.msdn.mic...sorsAndLocation). From this Web site, you can download the Windows 7 Sensor and Location .NET Interop Sample Library, which is a fully working set of .NET assemblies for working with the Windows 7 Sensor and Location Platform. If you need to use sensors in your application, it is highly recommended that you use the Windows API Code Pack. However, because the Location API didn't make it into the Windows API Code Pack, it is recommended that you use this library for .NET location-aware applications. This is exactly what we are going to do right now. We are going to write a .NET console application that is similar in functionality to the native application we've seen so far.
In the .NET library, you will find Windows7.SensorAndLocation.dll, which holds the .NET location API namespace. The main namespace for the .NET Location API is Windows7.Location. Within that namespace, you can find the LocationProvider abstract class, which is the base class for the other location providers. This is the main difference between the .NET Location API and the native one. There is no equivalent .NET "Location Manager" class in the form of the native ILocation. LocationProvider is an abstract class that exposes the .NET methods, functions, and events equivalent to the native Location API that you saw earlier in this chapter. But you can't create a new instance of the LocationProvider. Instead, you have to use one of the location provider implementations: LatLongLocationProvider or CivicAddressLocationProvider.
By working with a specific location provider, the .NET API enables the creation of strongly typed objects in the form of specific location providers. Basically, these strongly typed location providers are a location report type that is a customized version of the native ILocation interface, which performs all the functions of a "location manager" for the specific location report type, such as Civic Address or Lat-Long.
Note that these .NET wrappers are just a thin layer of .NET glue and a little bit of logic to make it easy for .NET developers to work in a .NET-natural way with the Location API. Underneath the surface, everything that we described so far in this chapter still applies; that is, you still need to obtain a specific location provider, make sure the location sensors are enabled and, if they are not, ask permission to enable them. Next, you need to verify the status of the location provider, verifying its ability to provide a valid location report. Then you can read location information synchronously or register for location events for an asynchronous programming model.
LocationProvider includes the following public functions, events, and .NET properties you need to see before starting to program with the specific location provider:
ReportStatus Returns the current provider status. Similar to the way you used ILocation::GetReportStatus to check the availability of the Location API to provide the desired location report. This property provides the enumeration values for the specific report you are working with.
GetReport Synchronously returns a location report class, LocationReport, which is an abstract base class you need to cast to the desired location report type.
ReportInterval Gets or sets the desired update frequency of the location report interval, in milliseconds.
RequestPermission Requests the user's permission to access the given report types and location providers if the location sensors are disabled.
Locationchanged The event that generates notifications about location changes.
StatusChanged The event that generates notifications about provider status changes. For example, this event is called when a GPS location sensor loses all its satellites and can't provide a location report. LatLongLocationProvider sends this event, and LatLongLocationProvider.Status changes to reflect this change.
Looking into the LocationProvider class, you might notice a few functions that we did not mention yet—for example, LocationProvider.GetDesiredAccuracy and LocationProvider.SetDesiredAccuracy. These are used when you want to set the accuracy of the location report notification—that is, set the maximum error radius that you are willing to tolerate. Any report with a larger error radius will not be reported to your application; for example, if a given location sensor has a new location report, the new location report error radius value is 100, and you have set (using LocationProvider.DesiredAccuracy) the maximum error radius to 50, you will not receive the Locationchanged event. By default, the accuracy value is not set and any new location report, with any error radius, triggers the Locationchanged event. This is true for both the native and managed APIs.
As we already mentioned, when using .NET you are using a strongly typed location provider. These are just regular classes that you can initiate. After you obtain such a location provider class, you can simply start using it. In our example, we use the CivicAddressLocationProvider, as shown in the following code snippet:
CivicAddressLocationProvider civicAddressLocationProivder = new CivicAddressLocationProvider(1000); ReportStatus locationReportStatus = civicAddressLocationProivder.ReportStatus; if (locationReportStatus == ReportStatus.Running) { locationListener.PrintLocationReport( (CivicAddressLocationReport) civicAddressLocationProvider.GetReport()); } //register for location events civicAddressLocationProvider.Locationchanged += locationListener.LocationchangedEventHandler; civicAddressLocationProvider.StatusChanged += locationListener.StatusChangedEventHandler;
The locationListener class will soon be used as our event handler for handling the location events. This class also includes several helper functions for printing location reports.
First, you need to create a new instance of CivicAddressLocationProvider. The constructor of all location providers expects an integer (uint) value that defines the initial value of the minimum report interval. You can later change this value using the ReportInterval property.
Next, you can check the status of the report. Any location provider has a ReportStatus value that indicates the operational state of the location provider. We already covered the exact states in the the section called “Understanding the Location Report Status” section earlier in this chapter. Similar to the native API, the Civic Address location report status might be in a ReportStatus.NotSupported state—that is, if the default location is not set.
However, assuming the default location is defined, you can call the location provider GetReport function. This function returns a LocationReport that is the base class for all the reports—again, it's equivalent to the native ILocationReport interface. Therefore, you need to cast the return value to the desired report type, which in our case is CivicAddressLocationReport. Then you pass this location report to a helper function that prints the report to the console application.
The last two lines in the code snippet register an event listener to the two events that CivicAddressLocationProvider exposes. Again, these events are identical to the native events defined in the ILocationEvents interface. The following code snippet shows the implementation of LocationchangedEventHandler in our .NET console application:
public void LocationchangedEventHandler
(LocationProvider locationProvider, LocationReport newLocation)
{
if (locationProvider.ReportStatus == ReportStatus.Running)
{
LatLongLocationReport latLongLocationReport
= newLocation as LatLongLocationReport;
if (latLongLocationReport != null)
{
Console.WriteLine("new Lat Long Location");
PrintLatLongLocationReport(latLongLocationReport);
return;
}
CivicAddressLocationReport civicAddressReport
= newLocation as CivicAddressLocationReport;
if (civicAddressReport != null)
{
Console.WriteLine("New Civic Address Location");
PrintCivicAddressLocationReport(civicAddressReport);
}
}
else
{
//handle error
}
}Here you can see that LocationchangedEventHandler, called when the Locationchanged event fires, receives two input parameters: a location provider and a location report. Both are abstract base classes for more specific classes. Therefore, you use this function as a more generic event handler that handles events for both the Lat-Long and Civic Address location providers.
First, you need to check the status of the report. Assuming the status of the location provider is in its running state, you can next cast to the desired report type. In this case, you simply try to cast the input location report object, newLocation, into both location report types, using the .NET as statement. First in order is the Lat-Long location report type. If the newLocation object is of type CivicAddressLocationReport, the newLocation as LatLongLocationReport returns null and you try your luck with the second cast, which is the Civic Address report. Then you call the relevant print function to print the report values.
You can test this application in the exact same way we tested the native application shown earlier. However, there is a much cooler way to do so: use the enhanced default location provider.
The enhanced default location provider (eDLP) tool is a Windows Presentation Foundation (WPF) open-source example that the Windows Sensor and Location team put together to illustrate the use of the .NET Location API. The binaries of this tool can be found with the rest of the code samples for this chapter. The entire source code of the eDLP and the .NET Location API, can be found at the MSDN Developer for Windows 7 site (http://code.msdn.mic...sorsAndLocation).
The eDLP displays Virtual Earth maps within a Web browser control, as shown in the following image. You can right-click any location on the map to set the location values. You will see the geographic coordinates (latitude and longitude) change each time you right-click on a different location on the map. The Address values will be set only if you right-click within the boundaries of any known city or town.
The Save Address button saves the current address as your Default Location value in the Location And Other Sensors Default Location dialog, shown in the the section called “Default Location” section earlier in this chapter. Therefore, if you run the eDLP tool alongside your application, each time you save a new address you will see the new address in your console application as a result of handling the location change event. This application requires administrator rights because you are changing the value of the default location.
Get your first look at Windows 7 and see how much more productive and efficient the development life cycle can be. Guided by three Windows programming experts, you'll examine new Windows 7 capabilities and get a head start exploiting them to build better user experiences and applications. Topics include multi-touch gesture support, graphics and video enhancements, the Ribbon user interface (including the difference between Windows 7 Ribbon and Windows Presentation Foundation (WPF) Ribbon), federated search, the Libraries feature, Taskbar functionality, the new Windows Sensor and Location platform, and more.




Help









