How are location dependent applications implemented today? As a rule, the use of GPS devices that are capable of providing coordinates of the current location comes to mind. However, GPS devices are far from being everywhere and not always. Let's try to figure out how to implement a richer way to determine your current location.
To date, many applications - mobile and desktop - acquire new features and implement various interesting and non-standard scenarios. To such unusual today applications include applications that adapt to the current conditions in which the user is located. For example, it can be an application that changes the brightness and font size in low light or an application that changes its user interface depending on where the user is now (at home, in the office, etc.). Such applications have a common name - context-sensitive applications. One of the particular cases of context-sensitive applications is applications that depend on the geographic location of the user. For example, if an application displays a weather forecast, then it would be logical to display it for the particular location where the user is located. Similarly, it would be logical to keep counting the time in the exact time zone where the user is located. There are many examples of such scenarios, which once again proves the value of such applications in real life.
How are location dependent applications implemented today? As a rule, the use of GPS devices that are capable of providing coordinates of the current location comes to mind. However, GPS devices are far from being everywhere and not always. Moreover, the use of GPS-devices is limited by the fact that they can not be used inside buildings and enclosed spaces. Often at this stage ideas about getting the current location end. However, if you think about it, there are other sources for obtaining this information. Since in our case we are talking about Windows Mobile, and devices based on this operating system often have a GSM module, the location information can be taken from the base stations of the state operators. In addition, do not forget about location services by IP-address - on such devices, the mobile Internet is configured in most cases.
Each of the above methods has its own advantages and disadvantages. Therefore, each method can only work under certain conditions and under certain restrictions. The most correct way is to use all the methods given earlier and combine the advantages of these methods in one application.
')
Throughout this article, we will look at the process of creating an application for Windows Mobile, in which we will use several alternative sources of information and build an application that can receive location information in various conditions. Before proceeding to the implementation of the application itself, let's consider each of the ways to obtain information about the location.
GPS
GPS is the most popular way to get location information. This method works in devices equipped with a GPS receiver. For this, the GPS receiver uses several satellites at the same time (at least 4) and, based on this, it obtains the coordinates of the current location. In addition to direct coordinates, the GPS receiver also provides information on the current speed, direction (north-south-west-east), altitude, etc. In our case, only coordinates will be needed, so we will not use the other parameters.
The advantages of this method include the accuracy of the information received and the possibility of its constant updating (in the case of movement). Moreover, in general, to obtain the coordinates, no connection to the Internet or the cellular operator’s network is required. However, GPS also has disadvantages. Firstly, GPS receivers, as a rule, do not work in enclosed spaces (this is due to the peculiarities of the technology itself). Secondly, it is often necessary for a GPS receiver to take some time (from a few seconds to a few minutes) in order to establish communication with the satellites. Finally, at some point in time, the GPS receiver may simply not establish communication with the satellites due to weather conditions, your location relative to the satellites or other reasons. All this creates inconvenience when working with GPS, and in some situations may make it impossible to use this method.
Different approaches can be used to work with a GPS receiver in Windows Mobile. Usually, a GPS receiver delivers its data through a COM port. Therefore, you can connect to it and read all the necessary information. However, with this approach there may be problems with connecting several applications to the GPS receiver. In addition, in this case, we will have to manually parse the data formats that come from the receiver (a trifle, but not nice). Therefore, in this case, it is recommended to use some “layer” in Windows Mobile, which allows you to centrally obtain information from a GPS device - the GPS API. In fact, the GPS API works directly with the COM port, processes data and provides interfaces for other applications. Using the GPS API, applications can receive all the information that is available from the GPS receiver.
To work with the GPS API in Windows Mobile, there is a library gpsapi.dll, which comes with the operating system. This library is unmanaged, so you need to use PInvoke to work with it. Fortunately, Microsoft has already made a managed wrapper for this library, which comes with the Windows Mobile 6 SDK. In our case, we will take this wrapper for use in our application.
Using a manageable wrapper is quite simple. To do this, you must create a NativeWrapperGps object, subscribe to the LocationChanged event, and call the Open method. When the current location changes, a LocationChanged event will be generated. After you finish working with the GPS device, you must call the Close method. In general, work through the GPS API may look like this.
var gps = new NativeWrapperGps();
gps.LocationChanged += delegate ( object sender, NativeWrapperGps.LocationChangedEventArgs args)
{
//..
};
gps.Open();
// ..
gps.Close();
* This source code was highlighted with Source Code Highlighter .
Thus, we can work with a GPS receiver in Windows Mobile and get information about your current location.
Cellular networks
Another source of information about the current location can be information that is available from the cellular operator. Since wireless networks are based on the “cell” principle, at each moment we work with a specific base station. Each base station has a unique identifier that identifies each base station. This identifier consists of several values ​​- Cell ID (or Tower ID), Location Area Code (LAC), Mobile Country Code (MCC) and Mobile Network Code (MNC). All these values ​​can be obtained from the base station and they will be unique for each base station.
However, the identifier itself is not valuable location information. However, there are centralized databases that associate these identifiers with geographic information. It is clear that the accuracy of determining the location of the user depends on how much the base station serves. However, such accuracy can satisfy the user often enough.
Thus, the proposed method does not contain the disadvantages of the method of determining the location using GPS - no long initialization is required, the determination process does not depend on weather conditions and the position of the satellites, and the position determination occurs quickly enough. However, the above method also has disadvantages. The main disadvantage is the low accuracy of the positioning: if the GPS determines the coordinates with an accuracy of several meters, then the above method can “make a mistake” for several kilometers. In addition, centralized databases may not contain information about the base station with which you are currently working - in this case, it is impossible to determine the location. Finally, location determination requires coverage of the networks of mobile operators, as well as access to the Internet (GPRS, EDGE, 3G, etc.). Access to the global network is necessary in order to use the services of a centralized database to determine the coordinates. Thus, it is clear that this method has a rather serious limitation, but in some cases it can be applied quite successfully.
In order to receive information from the GSM module of the phone, you can use the library ril.dll (RIL, Radio Interface Layer). This library comes with the operating system and is developed on unmanaged code. For this reason, you can use its functions through PInvoke. RIL provides many interesting features that you can use. In our case, it is necessary to obtain information about the base station, this can be done using the GetCellTowerInfo function. Before using this function, you must call the initialization function, and after use - deinitialization. During initialization, the method that will be called after receiving the information is specified (the process of obtaining information about the base station is asynchronous). Thus, working with RIL will require a small wrapper over the unmanaged library.
public static class RilInterop
{
public delegate void RilResultCallback( uint dwCode, IntPtr hrCmdID, IntPtr lpData, uint cbData, uint dwParam);
public delegate void RilNotifyCallback( uint dwCode, IntPtr lpData, uint cbData, uint dwParam);
[DllImport( "ril.dll" , EntryPoint = "RIL_Initialize" )]
public static extern IntPtr Initialize( uint dwIndex, RilResultCallback pfnResult, RilNotifyCallback pfnNotify, uint dwNotificationClasses, uint dwParam, out IntPtr lphRil);
[DllImport( "ril.dll" , EntryPoint = "RIL_GetCellTowerInfo" )]
public static extern IntPtr GetCellTowerInfo( IntPtr hRil);
[DllImport( "ril.dll" , EntryPoint = "RIL_Deinitialize" )]
public static extern IntPtr Deinitialize( IntPtr hRil);
}
* This source code was highlighted with Source Code Highlighter .
After that, you need to initialize the RIL, specify the callback method, call the GetCellTowerInfo method and call the de-initialization method. The data will be received in asynchronous mode, so if you need to receive them synchronously, you need to use synchronization objects, for example, AutoResetEvent. Thus, obtaining information about the base station will be as follows.
public class RilWrapper
{
private static RilCellTowerInfo _towerDetails;
private static readonly AutoResetEvent WaitHandle = new AutoResetEvent( false );
public static CellTower GetCellTowerInfo()
{
IntPtr rilHandle;
if (RilInterop.Initialize(1, CellDataCallback, null , 0, 0, out rilHandle) != IntPtr .Zero)
{
return null ;
}
RilInterop.GetCellTowerInfo(rilHandle);
WaitHandle.WaitOne();
RilInterop.Deinitialize(rilHandle);
return new CellTower
{
TowerId = Convert .ToInt32(_towerDetails.DwCellID),
LocationAreaCode = Convert .ToInt32(_towerDetails.DwLocationAreaCode),
MobileCountryCode = Convert .ToInt32(_towerDetails.DwMobileCountryCode),
MobileNetworkCode = Convert .ToInt32(_towerDetails.DwMobileNetworkCode),
};
}
public static void CellDataCallback( uint dwCode, IntPtr hrCmdID, IntPtr lpData, uint cbData, uint dwParam)
{
_towerDetails = new RilCellTowerInfo();
Marshal.PtrToStructure(lpData, _towerDetails);
WaitHandle.Set();
}
}
* This source code was highlighted with Source Code Highlighter .
After calling the GetCellTowerInfo () method, an object will be returned containing values ​​that characterize the current base station. As mentioned above, to obtain geographic coordinates based on this information, it is necessary to use a publicly available database. For example, such information contains the open service OpenCellId (opencellid.org). Using this resource, you can get location coordinates from base station information. Using the specified URL format, you can access the service and get the answer in the form of XML. To recognize the information from this service, create a small object that performs these functions.
public class OpenCellIdProvider : ICellToGpsProvider
{
public GpsLocation GetCoordinates( int cellId, int locationAreaCode, int mobileCountryCode, int mobileNetworkCode)
{
GpsLocation result = null ;
var doc = XDocument .Load( String .Format( "http://www.opencellid.org/cell/get?key={4}&mnc={3}&mcc={2}&lac={1}&cellid={0}" , cellId, locationAreaCode, mobileCountryCode, mobileNetworkCode, Key));
if ((doc.Root != null ) && (doc.Root. Attribute (XName.Get( "stat" )).Value == "ok" ))
{
var cellInfoElem = doc.Root.Element(XName.Get( "cell" ));
if (cellInfoElem != null )
{
result = new GpsLocation
{
Latitude = Convert .ToDouble(cellInfoElem. Attribute (XName.Get( "lat" )).Value.Replace('.', ',')),
Longitude = Convert .ToDouble(cellInfoElem. Attribute (XName.Get( "lon" )).Value.Replace('.', ','))
};
}
}
return result;
}
}
* This source code was highlighted with Source Code Highlighter .
Now, after receiving information about the base station, we can access this service and get the coordinates of the current location.
Geoip
The last method that we consider as an option to get the current location is to determine the current coordinates based on the IP address. Since most devices have a GRPS connection to the Internet, this method can work quite successfully. Obtaining a location by IP address is an operation that does not always return accurate information. Due to the use of “gray” IP addresses, information can be very different from reality (for example, when a Russian IP address is determined by Irish). However, when using the mobile Internet, the probability of obtaining the correct information is higher. Therefore, we will consider this method as one of the alternatives.
The strength of this method is that it does not depend on the presence of a GPS receiver, weather conditions and the possibility of a satellite connection. In addition, this method does not depend on the availability of information in the database of base stations. However, the disadvantages of this method are present and they are quite significant. First, the accuracy of positioning often leaves much to be desired. As a rule - this is the framework of the city (not even the district). However, if this level of detail is fine, then why not? Another disadvantage is the need for an internet connection; if there is no internet connection, then this method does not work. Moreover, the majority of full-fledged location tools by IP address are either chargeable or impose restrictions on the number of hits.
However, let's take note of this method for the case when all of the listed restrictions are not significant. GeoIp-services there are a great many. Most of them are paid, others may simply require registration. In our case, we will focus on the GeoIpTool service (geoiptool.com), in the general case, you can use any one presented on the Internet. This service returns HTML when referring to its main page, within which there are coordinates corresponding to the client's IP address. In this case, we simply process the HTML code and get the coordinates from it.
public GpsLocation GetLocation()
{
double ? lat = null ;
double ? lon = null ;
var html = GetHtml( "http://www.geoiptool.com/en/" );
var lines = Regex.Matches(html.Replace( "\r" , " " ).Replace( "\n" , " " ), @"<tr>(.)+?</tr>" , RegexOptions.IgnoreCase);
foreach (Match line in lines)
{
try
{
if (line.Value.Contains( "Longitude:" ))
{
lon = Convert .ToDouble(Regex.Match(line.Value, @"<td(.)*?>(?<val>[0-9\.]+)</td>" ).Groups[ "val" ].Value.Replace('.', ','));
}
if (line.Value.Contains( "Latitude:" ))
{
lat = Convert .ToDouble(Regex.Match(line.Value, @"<td(.)*?>(?<val>[0-9\.]+)</td>" ).Groups[ "val" ].Value.Replace('.', ','));
}
}
catch (FormatException)
{
}
}
return (lat != null ) && (lon != null ) ? new GpsLocation { Latitude = ( double )lat, Longitude = ( double )lon } : null ;
}
* This source code was highlighted with Source Code Highlighter .
Thus, we can get your location by IP address.
Build the final application
Now that we can determine the current location in at least three ways, let's build an application that will use all of these methods at the same time. Since each of the methods has its own advantages and disadvantages, we will arrange these methods in order of priority. It is clear that the most accurate way is to determine the coordinates based on GPS data. Therefore, we will use it in priority. In cases where the GPS receiver is not in the device or it cannot connect to the satellites, we will use data from the base stations of the mobile network. In this case, the accuracy of the determination will be reduced, but we can find out your approximate location. Finally, if for some reason we could not find out the location in this way (for example, data on the current base station were not found in the database), then you can find out the location using the mobile Internet and IP address. In this case, the accuracy will decrease even more, but we will get the information.
To work in this mode, I would like to have a general mechanism to which we will ask a question about the current location, and it, in turn, determines the location in an accessible way. To do this, each of the methods will implement the provider interface ILocationProvider, defined as follows.
public interface ILocationProvider
{
GpsLocation GetLocation();
string ProviderName { get ; }
}
* This source code was highlighted with Source Code Highlighter .
This interface contains a method for retrieving the current location, and also returns the name of the provider. After that, it is necessary to implement this interface in the objects that implement the logic for each of the above methods. It is easy to guess how this can be done on the basis of the code provided for each of the methods. Finally, an object is needed that performs the function of coordinating all providers, a kind of manager. This object must contain a collection of available providers and, when accessing it, it must alternately poll each provider. If a higher-priority provider generated an exception or simply returned null, then you need to contact the next provider, etc. Thus, the following class description for such an object is obtained.
public class LocationManager : ILocationProvider
{
private readonly List <ILocationProvider> _providers = new List <ILocationProvider>();
private string _lastProviderName = null ;
public void ClearProviders()
{
_providers.Clear();
}
public void RegisterProvider(ILocationProvider provider)
{
if (_providers.Contains(provider)== false )
{
_providers.Add(provider);
}
}
public void RemoveProvider(ILocationProvider provider)
{
if (_providers.Contains(provider) == true )
{
_providers.Remove(provider);
}
}
#region ILocationProvider Members
public GpsLocation GetLocation()
{
GpsLocation result = null ;
_lastProviderName = null ;
foreach ( var provider in _providers)
{
try
{
result = provider.GetLocation();
if (result != null )
{
_lastProviderName = provider.ProviderName;
break ;
}
}
catch (Exception ex)
{
continue ;
}
}
return result;
}
public string ProviderName
{
get { return _lastProviderName; }
}
#endregion
}
* This source code was highlighted with Source Code Highlighter .
Thus, in order to use this mechanism, it is necessary to register all the necessary providers, and then contact the manager object with the question “where am I?”. For example, this code may look like this.
LocationManager manager = new LocationManager();
manager.RegisterProvider( new GpsLocationProvider());
manager.RegisterProvider( new CellLocationProvider( new OpenCellIdProvider()));
manager.RegisterProvider( new GeoIpLocationProvider());
var location = manager.GetLocation();
* This source code was highlighted with Source Code Highlighter .
In the case when it is necessary to exclude any of the providers from the process, we simply do not register it. Finally, you can display the received coordinates on the map and display them to the user.

Thus, we received an application that uses several alternative sources of information to obtain its location: if at the moment you can use GPS, then this method is used, if GPS is not available, then alternative methods are used, albeit less accurate.
Instead of conclusion
Applications that respond to context changes are becoming increasingly popular in the midst of the development of modern applications. Mobile applications are no exception. However, many developers still consider a GPS receiver as the only means of obtaining information about their current location. Here we looked at the way in which it is possible to obtain such information in case of impossibility of using GPS and even without a GPS receiver. Often, alternative methods are less accurate in determining location, but accuracy is not needed everywhere and not always - a large number of scenarios are perfectly implemented based on the information about the city in which I am or even the country. Therefore, you do not need to limit yourself to such opportunities, but simply turn on the fantasy and start using context-sensitive scripts in your applications.
Thank you for reading to the end and good luck in building your applications! :)
Source codes of the application:
LocationAwareApp.zip