用Geolocation获位置信息
如果设备支持Geolocation,并且所使用的浏览器支持,就可以使用Geolocation获取设备的当前地理位置。可以打开网页http://caniuse.com/#search=geolocation查看有哪些浏览器版本支持Geolocation。显示Supported表示支持。

Geolocation返回的GeolocationInfo,包含以下信息:
latitude—— 纬度(度)。longitude—— 经度(度)。altitude—— 相对于海平面的海拔高度(米)。如果设备不提供海拔数据,altitude的值为null。accuracy—— 返回经纬度的精度,以米为单位。altitudeAccuracy—— 返回海拔的精度,以米为单位。altitudeAccuracy可能为null。heading—— 返回设备的移动方向(角度),指示距离北方的角度。0度表示指向正北方,方向以顺时针旋转(这表示东方是90度,西方是270度)。如果speed是0,heading会是NaN。如果设备无法提供heading信息,值为null。speed—— 返回设备每秒的移动速度(米)。speed可能为null。timestamp—— 获取得到设备当前位置的时间。
Geolocation静态属性值包含以下通用设置:
enableHighAccuracy—— 布尔值,如果设为true并且设备能够提供更精确地位置,则应用尽可能获取最佳结果。注意着可能导致更长的响应时间和更大的电量消耗(如开启了移动设备的GPS)。如果设置为false,将会得到更快速的响应和更少的电量消耗。默认值为false。timeout—— 代表返回位置的最大时间(毫秒)限制。默认值是1E10,意味着getCurrentPosition()直到位置可用时才会返回。maximumAge—— 代表可返回的可用缓存位置的最大时限。如果设置为0,意味着设备不使用缓存位置,始终尝试获取实时位置。如果设置为Infinity,设备必须返回缓存位置无论其寿命。默认值:0。
1、获取当前定位
Section titled “1、获取当前定位”使用静态方法Geolocation.getCurrentPosition()获取当前的位置,getCurrentPosition()只触发一次。
/** * 获取设备当前位置。 * @param onSuccess 带有唯一<code>Position</code>参数的回调处理器。 * @param onError 可选的。带有错误信息的回调处理器。错误代码为Geolocation.PERMISSION_DENIED、Geolocation.POSITION_UNAVAILABLE和Geolocation.TIMEOUT之一。 */ static getCurrentPosition(onSuccess: (info: GeolocationInfo) => void, onError?: (err: { code: number, message: string }) => void): void; /** @deprecated */ static getCurrentPosition(onSuccess: Handler, onError?: Handler): void; static getCurrentPosition(onSuccess: Handler | ((info: GeolocationInfo) => void), onError?: Handler | ((err: { code: number, message: string }) => void)): void { PAL.device.getCurrentPosition( info => { if (onSuccess instanceof Handler) onSuccess.runWith(info); else onSuccess(info); }, err => { if (onError instanceof Handler) onError.runWith(err); else if (onError) onError(err); }, { enableHighAccuracy: Geolocation.enableHighAccuracy, timeout: Geolocation.timeout, maximumAge: Geolocation.maximumAge } ); }在LayaAir IDE中,给Scene2D添加一个自定义的组件脚本,添加如下代码,实现鼠标点击后,获取地理位置。
const { regClass, property } = Laya;
@regClass()export class NewScript extends Laya.Script {
constructor() { super(); }
onMouseClick(evt: Laya.Event): void { // 尝试获取当前位置 Laya.Geolocation.getCurrentPosition( Laya.Handler.create(this, this.onSuccess), Laya.Handler.create(this, this.onError) ); console.log("click"); }
// 成功获取位置后触发 onSuccess(info: Laya.GeolocationInfo): void { console.log('经纬度: (' + info.longitude + '°, ' + info.latitude + '°),精确度:' + info.accuracy + 'm');
if (info.altitude != null) console.log('海拔:' + info.altitude + 'm' + (info.altitudeAccuracy != null ? (',精确度:' + info.altitudeAccuracy + 'm') : ''));
if (info.heading != null && !isNaN(info.heading)) console.log('方向:' + info.heading + "°");
if (info.speed != null && !isNaN(info.speed)) console.log('速度:' + info.speed + "m/s"); }
// 获取位置失败后触发 onError(err: any): void { var errType: String; if (err.code == Laya.Geolocation.PERMISSION_DENIED) errType = "Permission Denied"; else if (err.code == Laya.Geolocation.POSITION_UNAVAILABLE) errType = "Position Unavailable"; else if (err.code == Laya.Geolocation.TIMEOUT) errType = "Time Out"; console.log('ERROR(' + errType + '): ' + err.message); }}以上示例代码演示使用getCurrentPosition()获取当前的位置信息,成功时打印地理位置信息,失败时打印错误信息和错误原因。
开发者如果点击IDE内的浏览器预览,上述示例则会打印Permission Denied(没有权限)的错误信息,原因是getCurrentPosition()获取位置信息时,Geolocation中navigator.geolocation的使用,只能使用https协议,普通的http协议是无法执行的,而IDE默认打开的谷歌浏览器里使用的是http协议。
这里提供一种测试办法,开发者可以先Web发布,然后用anywhere命令启动https进行测试。这里要注意,示例中将获取地理位置的方法放在了鼠标点击事件中,原因是navigator.geolocation只有响应用户的手势操作时,才会返回地理信息。所以如果直接放在onStart()等全局方法里面是不行的,得是像onMouseClick()这样的手势事件的响应函数才可以。
获取位置信息需要开启代理。
2、监视位置改变
Section titled “2、监视位置改变”除了获取当前位置之外,还可以监视位置的改变。使用Geolocation.watchPosition()监视位置改变,该函数返回一个监视器ID值,可以使用Geolocation.clearWatch()并传入该ID值来取消由watchPosition()注册的位置监听器。
/** * 监视设备当前位置。回调处理器在设备位置改变时被执行。 * @param onSuccess 带有唯一<code>Position</code>参数的回调处理器。 * @param onError 可选的。带有错误信息的回调处理器。错误代码为Geolocation.PERMISSION_DENIED、Geolocation.POSITION_UNAVAILABLE和Geolocation.TIMEOUT之一。 */ static watchPosition(onSuccess: (info: GeolocationInfo) => void, onError?: (err: { code: number, message: string }) => void): number; /** @deprecated */ static watchPosition(onSuccess: Handler, onError?: Handler): number; static watchPosition(onSuccess: Handler | ((info: GeolocationInfo) => void), onError?: Handler | ((err: { code: number, message: string }) => void)): number { return PAL.device.watchPosition( info => { if (onSuccess instanceof Handler) onSuccess.runWith(info); else onSuccess(info); }, err => { if (onError instanceof Handler) onError.runWith(err); else if (onError) onError(err); }, { enableHighAccuracy: Geolocation.enableHighAccuracy, timeout: Geolocation.timeout, maximumAge: Geolocation.maximumAge } ); }
/** * 移除<code>watchPosition</code>安装的指定处理器。 * @param id */ static clearWatch(id: number): void { PAL.device.clearWatchPosition(id); }以下示例同第1节示例的测试方法相同,需要发布后进行测试。
const { regClass, property } = Laya;
@regClass()export class NewScript extends Laya.Script {
constructor() { super(); }
onKeyDown(): void { // Geolocation.watchPosition函数签名 Laya.Geolocation.watchPosition( Laya.Handler.create(this, this.updatePosition), Laya.Handler.create(this, this.onError)); console.log("keydown"); }
updatePosition(info: Laya.GeolocationInfo): void { console.log('经纬度: (' + info.longitude + '°, ' + info.latitude + '°),精确度:' + info.accuracy + 'm'); }
onError(err: any): void { var errType: String; if (err.code == Laya.Geolocation.PERMISSION_DENIED) errType = "Permission Denied"; else if (err.code == Laya.Geolocation.POSITION_UNAVAILABLE) errType = "Position Unavailable"; else if (err.code == Laya.Geolocation.TIMEOUT) errType = "Time Out"; console.log('ERROR(' + errType + '): ' + err.message); }}watchPosition()具有和getCurrentPosition()一样的函数签名。更多关于watchPosition()的应用,可以查看文档《使用百度地图》。