4.1 Geolocation API基础
在HTML5 Geolocation API之前,基于IP地址的地理定位方法是获得位置信息的唯一方式,但其返回的位置信息通常并不正确。基于IP地址的地理定位的实现方式是自动查找用户的IP地址,然后检索其注册的物理地址。
4.1.1 Geolocation API应用场景
应用场景1:设计一个Web应用程序,向用户提供附近商店打折优惠信息。使用HTML5 Geolocation API可以请求用户共享他们的位置,如果他们同意,应用程序就可以向其提供相关信息,告诉用户去附近哪家商店可以挑选到打折的商品。
应用场景2:构建计算行走(跑步)路程的应用程序。想象一下,用户在开始跑步时通过手机浏览器启动应用程序的记录功能。在用户移动过程中,应用程序会记录已跑过的距离,还可以把跑步过程对应的坐标显示在地图上,甚至可以显示出海拔信息。如果用户正在和其他选手一起参加跑步比赛,应用程序甚至可以显示其对手的位置。
应用场景3:基于GPS导航的社交网络应用,可以用它看到好友们当前所处的位置。知道了好友的方位,就可以挑选合适的咖啡馆。此外,还有很多特殊的应用。
4.1.2 位置信息来源
HTML5 Geolocation API未指定设备使用哪种底层技术来定位应用程序的用户。相反,它只是用于检索信息的API,而且该API检索到的数据只具有某种程度的准确性,它并不能保证设备返回的实际位置是精确的。设备可以使用下列数据。
IP地址
三维坐标
GPS全球定位系统。
从RFID、Wi-Fi和蓝牙到Wi-Fi的MAC地址。
GSM或CDMA手机的ID。
用户自定义数据
为了保证更高的准确度,许多设备使用一个或多个数据源的组合。
4.1.3 位置信息表示方式
位置信息主要由一对纬度和经度坐标组成,例如:
Latitude: 39.17222, Longitude: -120.13778
在这里,纬度(距离赤道以北或以南的数值表示)是39.172 22,经度(距离英国格林威治以东或以西的数值表示)是120.137 78,经纬度坐标可以用以下两种方式表示。
十进制格式,如39.172 22。
DMS角度格式,如39°20'。
HTML5 Geolocation API返回坐标的格式为十进制格式。
除了纬度和经度坐标之外,HTML5 Geolocation还提供位置坐标的准确度,并提供其他一些元数据,具体情况取决于浏览器所在的硬件设备。这些元数据包括海拔、海拔准确度、行驶方向和速度等。如果这些元数据不存在则返回null。
4.1.4 获取位置信息
HTML5 Geolocation API的使用方法相当简单。请求一个位置信息,如果用户同意,浏览器就会返回位置信息,该位置信息是通过支持HTML5地理定位功能的底层设备,例如,通过笔记本电脑或手机提供给浏览器。位置信息由纬度、经度坐标和一些其他元数据组成。有了这些位置信息就可以构建引人注目的位置感知类应用程序。
HTML5为window.navigator对象新增了一个geolocation属性,可以使用Geolocation API访问该属性,window.navigator对象的geolocation属性包含三个方法,利用这些方法可以实现位置信息的读取。
使用getCurrentPosition方法可以取得用户当前的地理位置信息,该方法的用法如下所示。
void getCurrentPosition(onSuccess, onError, options) ;
第一个参数为获取当前地理位置信息成功时所执行的回调函数,第二个参数为获取当前地理位置信息失败时所执行的回调函数,第三个参数为一些可选属性的列表。其中,第二、第三个参数为可选属性。
getCurrentPosition方法中的第一个参数为获取当前地理位置信息成功时所执行的回调函数,该参数的使用方法如下所示。
获取地理位置信息成功时执行的回调函数用到了一个参数position,它代表一个position对象,我们将在后面小节中对这个对象进行具体介绍。
getCurrentPosition方法中的第2个参数为获取当前地理位置信息失败时所执行的回调函数。如果获取地理位置信息失败,可以通过该回调函数把错误信息提示给用户。当在浏览器中打开使用了Geolocation API来获得用户当前位置信息的页面时,浏览器会询问用户是否共享位置信息。如果在该画面中拒绝共享的话,也会引起错误的发生。
该回调函数使用一个error对象作为参数,该对象具有以下两个属性。
1)code属性
code属性包含三个值,简单说明如下。
属性值为1表示用户拒绝了位置服务。
属性值为2表示获取不到位置信息。
属性值为3表示获取信息超时错误。
2)message属性
1个字符串,该字符串包含了错误信息,这个错误信息在开发和调试时将很有用。因为有些浏览器中不支持message属性,如Firefox。
在getCurrentPosition方法中使用第2个参数捕获错误信息的具体使用方法如下所示。
getCurrentPosition方法中的第3个参数可以省略,它是一些可选属性的列表,这些可选属性说明如下。
1)enableHighAccuracy
是否要求高精度的地理位置信息,这个参数在很多设备上设置了不使用,因为使用在设备上时需要结合设备电量、具体地理情况来综合考虑。因此,多数情况下将该属性设为默认,由设备自身来调整。
2)timeout
对地理位置信息的获取操作做一个超时限制(单位为毫秒)。如果在该时间内未获取到地理位置信息,则返回错误。
3)maximumAge
对地理位置信息进行缓存的有效时间的单位为毫秒,例如,maximumAge: 120000(1分钟是60000)。如果10点整的时候获取过一次地理位置信息,10:01的时候再次调用navigator.geolocation.getCurrentPosition重新获取地理位置信息,则返回的依然为10:00时的数据(因为设置的缓存有效时间为2分钟)。超过这个时间,缓存的地理位置信息被废弃,尝试重新获取地理位置信息。如果该值被指定为0,则无条件重新获取新的地理位置信息。
这些可选属性的具体设置方法如下所示。
4.1.5 浏览器兼容性
各浏览器对HTML5 Geolocation的支持程度不同,并且还在不断更新。在HTML5的所有功能中,HTML5 Geolocation是第一批被全部接受和实现的功能之一,这对于开发人员来说是个好消息。相关规范已达到一个非常成熟的阶段,不太可能有大的改变。各浏览器对HTML5 Geolocation的支持情况如表4.1所示。
表4.1 浏览器支持概述
由于浏览器对它的支持程度不同,使用之前最好先检查浏览器是否支持HTML5 Geolocation API,确保浏览器支持其所要完成的所有工作。这样当浏览器不支持时,HTML5 Geolocation API就可以提供一些替代文本,提示用户升级浏览器或安装插件来增强现有浏览器的功能。
在上面的代码中,loadDemo函数测试了浏览器的支持情况,这个函数是在页面加载的时候调用的。如果存在地理定位对象,navigator.geolocation调用将返回该对象,否则将触发错误。页面上预先定义的support元素会根据检测结果显示支持情况的提示信息。
4.1.6 监测位置信息
使用watchPosition方法可以持续获取用户的当前地理位置信息,它会定期地自动获取。watchPosition方法的基本语法如下所示。
int watchCurrentPosition(onSuccess, onError, options) ;
该方法参数的说明和使用与getCurrentPosition方法相同。调用该方法后会返回一个数字,这个数字的用法与JavaScript脚本中setInterval方法的返回值用法类似,可以被clearWatch方法使用,以停止对当前地理位置信息的监视。
4.1.7 停止获取位置信息
使用clearWatch方法可以停止对当前用户的地理位置信息的监视,具体用法如下所示。
void clearWatch(watchId);
参数watchId为调用watchCurrentPosition方法监视地理位置信息时的返回参数。
4.1.8 保护隐私
HTML5 Geolocation规范提供了一套保护用户隐私的机制。除非得到用户明确许可,否则不可获取位置信息。
【操作步骤】
第1步,用户从浏览器中打开位置感知应用程序。
第2步,应用程序加载Web页面,然后调用Geolocation函数请求位置坐标。浏览器拦截这一请求,然后请求用户授权。
第3步,如果用户允许,浏览器从其宿主设备中检索坐标信息,如IP地址、Wi-Fi或GPS坐标,这是浏览器的内部功能。
第4步,浏览器将坐标发送给受信任的外部定位服务,它返回一个详细位置信息,并将该位置信息发回给HTML5 Geolocation应用程序。
提示,应用程序不能直接访问设备,它只能请求浏览器代表它访问设备。
访问使用HTML5 Geolocation API的页面会触发隐私保护机制。如果仅仅是添加HTML5 Geolocation代码,而不被任何方法调用,则不会触发隐私保护机制。只要所添加的HTML5 Geolocation代码被执行,浏览器就会提示用户应用程序要共享位置。执行HTML5 Geolocation的方式很多,如调用navigator.geolocation.getCurrentPosition方法等。
除了询问用户是否允许共享其位置之外,Firefox等浏览器还可以让用户选择记住该网站的位置服务权限,以便下次访问的时候不再弹出提示框,类似浏览器记住某些网站的密码。
4.1.9 处理位置信息
因为位置数据属于敏感信息,所以接收之后必须小心地处理、存储和重传。如果用户没有授权存储这些数据,那么应用程序应该在相应任务完成后,立即删除它们。如果要重传位置数据,建议先对其进行加密。在收集地理定位数据时,应用程序应该着重提示用户以下内容。
会收集位置数据。
为什么收集位置数据。
位置数据将保存多久。
怎样保证数据的安全。
如果用户同意共享,位置数据怎样共享。
用户怎样检查和更新他们的位置数据。
4.1.10 使用position
如果获取地理位置信息成功,这些地理位置信息可以在获取成功后的回调函数中通过访问position对象的属性来得到。position对象具有如下属性。
latitude:当前地理位置的纬度。
longitude:当前地理位置的经度。
altitude:当前地理位置的海拔高度(不能获取时为null)。
accuracy:获取的纬度或经度的精度(以米为单位)。
altitudeAccurancy:获取的海拔高度的精度(以米为单位)。
heading:设备的前进方向。用面朝正北方向的顺时针旋转角度表示方向,不能获取时为null。
speed:设备的前进速度(以米/秒为单位,不能获取时为null)。
timestamp:获取地理位置信息时的时间。
【示例】本示例使用getCurrentPosition方法获取当前位置的地理信息,并且在页面中显示position对象的所有属性。
这段代码的运行结果在不同设备的浏览器上也不同,具体的运行结果取决于运行浏览器的设备。