在移动设备上使用GPS定位功能时,经常会遇到所谓的“冷启动”问题。为了节省电池寿命,GPS接收器在不使用时会被关闭。与标准GPS设备不同,移动GPS芯片在断电后不会保存数据,每次使用时都需要进行“冷启动”,这意味着需要保持手机静止长达10分钟,直到它锁定到卫星。Windows Mobile 5和6的标准/智能手机版本并不提供用户可访问的配置选项来更改此设置。
然而,如果GPS保持开启状态,即使在失去定位(例如进入室内)后,它也能在几秒钟内重新获取位置,只要被放置在有信号的区域。此外,一旦锁定到信号,接收器即使进入无法从冷启动锁定信号的区域,也能保持信号。
最初,通过在后台一直运行Google Maps来解决这个烦恼。这个解决方案并不完美,因为它使用了大量的内存和CPU资源,并且需要从互联网下载数据来更新地图,这在许多移动设备上是非常昂贵的。设计了这个实用程序在后台运行,保持GPS开启,并在用户定义的时间间隔内轮询其状态。
如果想要快速测试GPS是否配置正确和/或有信号,这个程序也是非常有用的。
这个应用程序使用的库是Windows Mobile 6标准SDK中免费提供的开源示例。它封装了API钩子,允许使用C#托管代码快速轻松地访问手机的GPS。
已经包含了库的必要源代码;如果有Windows Mobile 6标准SDK,这些文件也可以在"\program files\Windows Mobile 6 SDK\Samples\Smartphone\CS\GPS"中找到。将整个文件夹添加到项目中(不包括演示应用程序),并添加...
using Microsoft.WindowsMobile.Samples.Location;
...(或VB等价物)到需要GPS访问的类中。
重要:Microsoft .NET Compact GPS库的已知问题
一个原因是在此处和其他地方发布了不必要的复杂解决方案,是因为:
THE WINDOWS MOBILE 6 SDK LIBRARY DOES NOT WORK PROPERLY IN THE WINDOWS MOBILE 6 EMULATOR. HOWEVER, IT WORKS PERFECTLY ON AN ACTUAL PHONE.
SDK中包含了一些NMEA文件,用于在模拟器上模拟导航...当与“FakeGPS”驱动程序(用于在模拟器中测试GPS应用程序)一起使用时,纬度和经度交替无效或荒谬(接近南极)。MSDN博客上有一个地方为此错误道歉,并给出了可能的修复方案(一个将十进制度数转换为标准纬度-经度的方程,这绝对无法解决问题)。
尽管如此,使用该库。它比打开文本文件更容易获取GPS数据,如下所示。问题在于模拟器。建议是,在模拟器中,测试适合方式输入模拟的纬度和经度(例如数组中的值,文本文件等),然后将位置获取方法连接到库,并部署到实际的GPS设备上。它将按预期工作。
伴随本文的项目虽然小而简单,但演示了在构建GPS应用程序时实际会使用的核心技术:
Start the GPS:
C#
Gps g = new Gps(); Gps.Open();
Determine if the GPS is ready and knows its location:
C#
if (g.GetPosition().LatitudeValid)
{
// Has position: do something with the data
}
Get latitude / longitude:
C#
double latitude = g.GetPosition().Latitude;
double longitude = g.GetPosition().Longitude;
Stop the GPS:
C#
gps.Close();
了解所有这些,可以在不到4小时内轻松构建一个准备进行普通用户beta测试的应用程序。
这个应用程序的代码包含在"form1.cs"及其关联文件中。与项目捆绑的其他源文件是由Microsoft提供的GPS对象。
它非常简单,以至于微不足道 - 整个应用程序在主窗口form1的代码后面运行。当程序启动时,用户可以选择打开GPS并开始定期轮询它。以下是如何停止和启动设备:
public bool isTurnedOn = false; // tracks state
public int pollInterval = 5; // keep-alive interval
public Gps gps; // the phone's internal GPS
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
gps = new Gps(); // Create the handle, but don't turn it on yet.
}
private void mnuTurnOn_Click(object sender, EventArgs e)
{
if (!isTurnedOn) // Turn on GPS
{
try
{
isTurnedOn = true;
mnuTurnOn.Text = "Turn Off";
gps.Open();
timer1.Interval = pollInterval * 60 * 1000;
UpdateStatus();
timer1.Enabled = true;
}
catch (Exception ex)
{
MessageBox.Show("Error: could not find GPS device");
}
}
else // Turn off GPS
{
isTurnedOn = false;
gps.Close();
UpdateStatus();
mnuTurnOn.Text = "Turn On";
timer1.Enabled = false;
}
}
访问GPS位置数据几乎太容易了。以下是UpdateStatus()方法,它是程序的核心,检查GPS是否锁定到足够数量的卫星,然后获取其纬度和经度。
private void UpdateStatus()
{
if (!isTurnedOn)
{
lblState.Text = "GPS Turned Off";
label1.Visible = label2.Visible = lblStatus.Visible = lblLastFix.Visible = lblLastUpdate.Visible = false;
}
else
{
lblState.Text = "GPS is turned on.";
label1.Visible = label2.Visible = lblStatus.Visible = lblLastFix.Visible = lblLastUpdate.Visible = true;
lblLastUpdate.Text = DateTime.Now.ToString();
if (gps.GetPosition().LatitudeValid)
lblLastFix.Text = "Locked on to satellites: " + gps.GetPosition().Latitude.ToString() + " - " + gps.GetPosition().Longitude.ToString();
else
lblLastFix.Text = "No signal";
}
}
由于"FakeGPS"仿真不起作用,应该尽早开始对使用这些库构建的任何应用程序进行设备测试。在这里构建的应用程序将产生一个EXE和一个DLL。将两者都放在移动设备上的同一个文件夹中,应该就可以开始了。
不幸的是,大多数设备在出厂时没有安装更新版本的.NET Compact Framework。如果有Windows Mobile SDK,将会有一个CAB适用于不同的处理器。不用担心选择错误的一个会破坏手机 - 它将简单地拒绝安装。也可以从Microsoft单独下载框架。
该项目目前设置为使用Windows Mobile 6标准构建目标(如Motorola Q9H或Samsung Jack II等智能手机。它还将构建为Windows Mobile 6专业版(触摸屏PDAs / PocketPCs)。
它已经在Motorola Q9H上进行了实际测试,标准配置,但应该可以在上述任何设备类别上工作,前提是存在并正确配置了GPS芯片组。
Windows Mobile 5设备也应该接受这个,以及其他使用中间GPS驱动程序的应用程序。在Visual Studio中切换构建目标,并在编译时查找警告:如果使用的组件(主要是UI组件)在5上不允许(例如可以由主机应用程序操作的嵌入式Web浏览器控件),将在构建时收到通知,并可以进行适当的(小的)更改。