位置感知电话簿






4.80/5 (6投票s)
一篇关于使用 Microsoft Live Search API 创建位置感知电话簿的文章
引言
微软向公众提供了一个用于接入 Windows Live Search 的 API。该 API 允许搜索网页、新闻和其他类型的信息。对于本项目,我主要关注电话搜索,以便在我的 Windows Mobile 通信设备上创建一个位置感知的电话簿。
硬件要求
要利用此程序,需要两件硬件。一件是运行至少 Windows Mobile 2003 操作系统的 Windows Mobile 设备,另一件是 GPS 接收器。Windows Mobile 5 设备也可以工作,但您可能会收到有关代码未签名的警告。您还可以使用 Visual Studio .NET 中包含的 Windows Mobile 模拟器之一,但需要记住将其中一个虚拟端口映射到主机上的 GPS 端口,并确保它可以连接到互联网。GPS 接收器可以是内置的或外部的,只需将其映射到 COM 端口即可。Windows Mobile 设备必须通过 WiFi 或通过电话服务提供商的数据订阅访问互联网。
如果您没有 GPS 接收器,程序仍然可以工作,但您需要选择一个城市作为所有搜索的参考点。
软件要求
我使用 Visual Studio .NET 2005 开发本项目。虽然我在过去 10 多年里一直偏爱 C 语言作为开发语言,但本文附带的示例是用 VB.NET 编写的。
Windows Mobile 设备还需要安装 2.0 Compact Framework。如果未安装,Visual Studio 将在部署时安装它。如果您的 GPS 接收器映射到 COM9 以上的端口,则首选带有 SP2 的 2.0 Framework。
入门
要针对 Microsoft Live Search Web 服务进行开发,您需要为您的项目请求一个应用程序 ID。获取它既快速、简单又免费。只需访问此网站即可请求 ID。
创建项目
对于本项目,我首先创建了一个新的“智能设备”项目,目标是“Pocket PC 2003”设备。这将是一个“设备应用程序”项目。由于此项目依赖于 Microsoft Live Search Web 服务,下一步是添加对该Web 服务的引用。一旦添加了 Web 服务,执行搜索就只是构建一个搜索请求对象并提交它。
构建搜索请求
Live Search API 允许您在单个请求中搜索多个数据源。每个数据源都将由一个“SourceRequest
”对象描述。尽管搜索请求可以包含多个SourceRequest
对象,但我们只搜索电话号码,因此我们的搜索将始终只有一个SourceRequest
对象。
我就是这样创建SearchRequest
和SourceRequest
对象,然后关联源的
Dim searchRequest As SearchRequest = New SearchRequest
Dim sourceRequest() As SourceRequest = {New SourceRequest()}
searchRequest.Requests = sourceRequest
搜索必须设置一些通用设置。这包括您的应用程序 ID、搜索的语言/文化、您希望获得的结果数量、搜索类型以及您希望在搜索结果中填充的字段。
searchRequest.AppID = "__YOUR_APP_ID_GOES_HERE__"
searchRequest.CultureInfo = "en-US"
sourceRequest(0).Count = 50
sourceRequest(0).Source = SourceType.PhoneBook
sourceRequest(0).SortBy = SortByType.Distance
sourceRequest(0).ResultFields = ResultFieldMask.Phone Or _
ResultFieldMask.Address Or ResultFieldMask.Location Or ResultFieldMask.Title
当然,您需要在此代码中放置您自己的应用程序 ID。剩下要做的就是指定我们要搜索的内容以及我们希望围绕哪个位置进行搜索
searchRequest.Location = currentLocation
searchRequest.Query = txtName.Text
这里的“currentLocation
”对象包含一个位置(纬度、经度和半径)。我稍后会评论这个字段。txtName.Text
是指用户输入他们正在搜索内容的文本字段。
提交搜索很容易。创建一个对MSNSearchService
对象的引用,使用搜索请求调用其搜索方法,并保存响应。单个搜索结果位于一个名为Responses
的集合中。此集合中对象的字段不言自明(Phone
、Address
等等……)
Dim searchService As MSNSearchService = New MSNSearchService()
Dim searchResponse As SearchResponse
searchResponse = searchService.Search(searchRequest)
读取 GPS 设备
NMEA GPS 设备传统上使用 RS232 接口(串行端口)进行通信。因此,您将使用SerialPort
对象从 GPS 设备读取数据。此类设备输出许多有趣的数据,包括 UTC 时间、速度等。我们只需要知道我们的位置。我实现了一个最小的 GPS 读取类。它读取 GPS 接收器输出的每一行,查找包含经度和纬度的消息,并使用以下正则表达式提取信息
Dim gpsExpression As Regex = New Regex( _
"\$GPRMC,\d*(\.\d*)?,\w,(?<LatitudeDegrees>\d+)_
(?<LatitudeMinutes>(\d{2}\.\d+)?),(?<latDir>N|S)," + _
"(?<LongitudeDegrees>\d+)(?<LongitudeMinutes>(\d{2}\.\d*)?),_
(?<longDir>E|W)")
该类有自己的线程。一旦实例化,它就会不断地从 GPS 接收器读取当前位置,并通过事件传递新坐标。对这个对象必须特别小心。由于它有自己的线程,如果主窗体关闭但此线程未停止,它可能会阻止程序从内存中卸载。调用对象的Dispose
方法将导致线程中止。
当尝试检测 GPS 端口时,我枚举可用的 COM 端口并尝试从每个端口读取,直到其中一个产生看起来像 GPS 字符串的字符串(再次使用正则表达式)。如果 GPS 设备出现故障(在我测试外部 GPS 接收器电池耗尽时发生过),GpsReader
的线程将终止。
计算到结果位置的距离
搜索结果包含结果的地理坐标,但不包含到结果的距离。距离是在窗体代码中计算的。该方程基本上是计算球体上大圆弧的长度。该函数将计算公里或英里(尽管我对该函数的调用只请求英里)。如果您想使用其他单位的距离,您只需要知道地球在该单位中的半径并将该值设置为“earthRadius
”变量。
下一步?
我为了这篇写作简化了这个程序,但我已经开始着手下一组我希望它拥有的功能。此处实现的 GPS 阅读器类将不复存在,并将被插件系统取代,允许使用不同类型的定位服务(例如辅助 GPS)或来自其他服务的定位信息)。我希望用户的搜索查询能够保存,以便可以从下拉列表中选择常用搜索。最终,我希望能够在地图上显示结果,并可能提供行车路线。虽然这最终可能会成为另一个项目的一部分,但我也希望运行此程序的同事能够使用它来找到彼此。
结论
Microsoft Live Search API 易于使用,可用于快速制作需要利用互联网搜索信息的应用程序。虽然我只使用该程序执行通用电话簿搜索,但该 API 还可以限制对商业或住宅实体的搜索。当然,该 API 还可以用于搜索其他内容,例如图像、新闻和拼写校正。微软提供了一个页面,允许任何人尝试可以执行的不同类型的搜索。
历史
- 2007 年 5 月 5 日 - 文章提交
- 2007 年 8 月 18 日 - 增加了部署项目和 Windows Mobile 中 COM 端口枚举问题的解决方法