Location-Based Services Using CellID in Windows Mobile

ast articles have discussed how to interface with GPS receivers to obtain the geographical position of a device and then transmit the information over to a server for mapping purposes. However, not all mobile devices today have built-in GPS receivers. Moreover, GPS does not work in-doors. This seriously limits the usefulness of applications built around GPS technologies.

If you don’t have GPS, or it’s unvailable, a good alternative is to obtain the ID (often known as the CellID) of the base station to which your device is currently connected. As the mobile device moves from one position to another, it generally connects to a base station that offers the best signal (though this decision can be based on a number of criteria). Once the CellID is obtained, you reference a database to obtain the geographical location of a base station and thus deduce the position of a mobile device (to a certain degree of accuracy).

There are two steps involved in using CellID to find a device’s location:

  • Obtain the CellID of the base station to which the device is connected.
  • Resolve the CellID into latitude and longitude.

This article will show you how to build an LBS application using a Windows Mobile device and Google Maps.

Obtaining the CellID
First, launch Visual Studio 2008 and create a new Smart Device project (Windows Mobile 6 Professional platform using the .NET CF 3.5). Name the project LBS.

Populate the default Form1 with the controls shown in Figure 1.

Figure 1. Form1: Populating the default Form1.

To obtain the CellID of a Windows Mobile device, use the RIL (Radio Interface Layer) API in the Windows CE operating system. The Radio Interface Layer (RIL) provides an interface that handles the communication between the CellCore system software and the radio hardware. Instead of writing your own P/Invoke code to use the RIL API, a fellow blogger, Dale Lane, has written a C# wrapper that invokes the RIL API. You’ll be using a slightly modified version of his code in this project.

Add a new Class item to the project and name it RIL.cs. Code the RIL.cs file as shown in Listing 1.

Basically, the RIL class is a wrapper for the RIL API and it exposes a static method, GetCellTowerInfo(), that returns the CellID of a base station in the following format:

CellID – Location Area Code – Mobile Country Code

A sample string returned by the GetCellTowerInfo() method might look like this:

15581-41-525

Click here to see the complete list of mobile country codes (MCC).

In the code-behind of Form1, import the following namespaces:

using System;using System.Windows.Forms;using System.IO;Define the following member variable:namespace LBS{    public partial class Form1 : Form    {        Timer t;        //---log file for CellID data---        const string FILE_NAME = @"CellIDs.txt";        StreamWriter sw;

Because you’re invoking the GetCellTowerInfo() method only periodically, you’ll use a Timer object to do so. Also, all the CellIDs you obtain will be logged in a text file for processing later.

In the Form1 constructor, add the following line of code:

        public Form1()        {            InitializeComponent();            sw = new StreamWriter(FILE_NAME, true,                 System.Text.Encoding.ASCII);        }

In the Form1_Load event handler, initialize the Timer object, and wire up the event handler for the Tick event:

private void Form1_Load(object sender, EventArgs e)        {            t = new Timer() {                 Interval = 2000,   //---fired every 2 seconds                Enabled = true             };            t.Tick += new EventHandler(t_Tick);        }

In the Tick event’s handler, you will obtain the CellID of the device by calling the the RIL class’s GetCellTowerInfo() static method. This displays the CellID and the current time in the Label control, and simultaneously logs the information into the text file:

        void t_Tick(object sender, EventArgs e)        {            string cellid = RIL.GetCellTowerInfo();            string txt = cellid + "-" + DateTime.Now.ToString();            //---display in textbox control---            lblCellID.Text = txt;            //---write to file---                       sw.WriteLine(txt);            sw.Flush();        }

The Start menu’s item control has a Click event handler that enables the Timer object to trigger the Tick event every two seconds:

Figure 2. Located! Displaying the CellID information obtained by the device.

        private void mnuStart_Click(object sender, EventArgs e)        {            t.Enabled = true;            sw = new StreamWriter(FILE_NAME, true,                 System.Text.Encoding.ASCII);        }

Likewise, the Stop menu’s item control also has a Click event handler that disables the Timer object: private void mnuStop_Click(object sender, EventArgs e) { t.Enabled = false; sw.Close(); }That’s it! Press F5 to deploy the application onto a Windows Mobile Professional device (remember to ensure that you have a valid SIM card). Figure 2 shows the CellID information you’ve obtained. Notice that, as you move from one location to another, the CellID information may change).

A snapshot of the CellIDs.txt file (saved in the root directory of the device) looks like Listing 2.

Obtaining the CellID of a device is only part of the story. CellIDs are nothing more than strings of numbers; they are useful only when you have a way to translate these numbers into latitude and longitude information. That’s where Google Maps comes in handy.

If you have ever used Google Maps for Mobile, you should be familiar with the My Location feature. This feature allows you to show your current location on the map, even if you don’t have GPS on the device. How does Google Maps do this? The trick lies in the use of the CellID obtained by Google Maps on your device. Once the CellID is obtained, it is sent back to a secret API at Google Maps at www.google.com/glm/mmap, which will then return the latitude and longitude to which the CellID corresponds. Apparently, Google Maps has a huge database containing all the world’s CellIDs (at least it worked pretty well for me in Singapore).

Some really intelligent folks actually analyzed the packets returned by Google Maps and write some C# code that allows you to pass in a CellID to Google Maps to obtain the latitude and longitude of a location. One of them is Neil Young, who published his C# code here.

In this article, you’ll modify that code and package it into a class. Add a new Windows Forms application project to the current solution and name it GoogleMaps. Add a new Class item to the project and name it GMM.cs. Populate the class as follows shown in Listing 3.

Basically, the GMM class contains a static method called GetLatLng(), that accepts an array parameter containing Mobile Country Code (MCC), Mobile Network Code (MNC), Location Area Code (LAC), and CellID (CID). The GetLatLng() method returns the latitude and longitude separated by a “|” character, like this:

1,368943|103,845447

Once the geographical location of a CellID is obtained, you want to display the location using Google Maps. Because Google Maps is hosted within a web browser, you will use a WebBrowser control to contain it.

First, populate the default Form1 with the controls shown in Figure 3.

Figure 3. Form1: Populating the default Form1.

When the user clicks the Load Cell IDs button, load the log file containing the CellIDs and display them in the ListBox control:

        private void btnLoadCellIDs_Click(object sender, EventArgs e)        {            OpenFileDialog openFileDialog1 = new OpenFileDialog()            {                Filter = "Text files (*.txt)|*.txt"            };            if (openFileDialog1.ShowDialog() == DialogResult.OK)            {                System.IO.StreamReader sr =                   System.IO.File.OpenText(openFileDialog1.FileName);                string strCellIDs = sr.ReadToEnd();                string[] cellIDs = strCellIDs.Split('
');                foreach (string str in cellIDs)                {                    lstCellIDs.Items.Add(str.Replace('
', ' '));                }            }        }

When the user selects a CellID in the ListBox control, extract the CellID from the ListBox control, and send the appropriate parameters into the GetLatLng() static method. When the latitude and longitude information is returned, set the WebBrowser control to navigate to the Google Maps application by feeding the latitude and longitude information in the query string (see Listing 4).

That’s it! You can now test the application by setting the GoogleMaps project as the startup project and then pressing F5. Perform the following steps to test the application:

Figure 4. Location! Displaying the location for the particular CellID.
  1. Capture a series of CellIDs by running the LBS project created in the first part of this article. The beauty of using CellIDs is that it works in-door as well. In fact, so long as you have a phone signal, you can obtain the CellID. A good way to capture CellIDs is to leave it in your car as you drive. You will be able to pick up a good series of different CellIDs.
  2. Copy the CellIDs.txt log file from your Windows Mobile device onto your computer.
  3. In the GoogleMaps application, click on the Load Cell IDs button to load the CellIDs.txt file. Once this is done, you should see the list of CellIDs and the time each CellID was taken displayed in the ListBox control.
  4. Click on each CellID and the WebBrowser control will automatically display the location for the particular CellID (see Figure 4)!

Use the techniques in this article, to make your own exciting, location-based service applications!

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

Recent Articles: