Location 定位服务¶
Location 模块提供了定位服务功能。你可以使用它来获取当前位置、计算距离、地理编码等。支持使用 TrollStore 权限控制系统定位服务开关。
守护进程支持: 完全支持。在触发器模式下可正常运行。
快速开始¶
// 请求定位权限
location.requestAccess();
// 获取当前位置
if (location.isAuthorized()) {
const pos = location.getCurrent();
console.log(`位置: ${pos.lat}, ${pos.lng}`);
}
// 计算距离
const distance = location.distance(39.9, 116.4, 31.2, 121.5);
console.log(`距离: ${distance} 米`);
// 地理编码
const results = location.geocode('北京天安门');
console.log(results[0]);
API 参考¶
权限管理¶
location.requestAccess()¶
请求定位权限。返回: void
location.requestAccessAsync()¶
异步请求定位权限。返回: Promise<void>
location.getAccessStatus()¶
获取权限状态。返回: 'authorized' | 'denied' | 'restricted' | 'notDetermined' | 'unknown'
location.isAuthorized()¶
检查是否已授权。返回: boolean
location.isLocationServicesEnabled()¶
检查定位服务是否开启。返回: boolean
location.hasTrollStorePermission()¶
检查是否有 TrollStore 权限。返回: boolean
定位服务开关(TrollStore Only)¶
location.setLocationServicesEnabled(enabled)¶
开关系统定位服务。参数: enabled (boolean) 返回: { success, enabled?, message? }
注意: 需要 TrollStore 权限
location.setLocationServicesEnabledAsync(enabled)¶
异步开关系统定位服务。参数: enabled (boolean) 返回: Promise<{ success, enabled?, message? }>
location.toggleLocationServices()¶
切换定位服务状态。返回: { success, enabled?, message? }
注意: 需要 TrollStore 权限
location.toggleLocationServicesAsync()¶
异步切换定位服务状态。返回: Promise<{ success, enabled?, message? }>
位置获取¶
location.getCurrent()¶
获取当前位置。返回: { lat, lng, alt, course, speed, accuracy, timestamp } | null
location.getCurrentAsync()¶
异步获取当前位置。返回: Promise<{ lat, lng, alt, course, speed, accuracy, timestamp } | null>
返回值字段:
- lat - 纬度
- lng - 经度
- alt - 海拔(米)
- course - 方向(度)
- speed - 速度(米/秒)
- accuracy - 精度(米)
- timestamp - 时间戳
location.current()¶
getCurrent() 的别名。
计算¶
location.distance(lat1, lng1, lat2, lng2)¶
计算两点距离。参数: 4 个 number 返回: number(米)
const distance = location.distance(39.9, 116.4, 31.2, 121.5);
console.log(`距离: ${(distance / 1000).toFixed(2)} 公里`);
地理编码¶
location.geocode(address)¶
地址转坐标。参数: address (string) 返回: [{ lat, lng, name }]
const results = location.geocode('北京天安门');
if (results.length > 0) {
console.log(`坐标: ${results[0].lat}, ${results[0].lng}`);
}
location.geocodeAsync(address)¶
异步地址转坐标。参数: address (string) 返回: Promise<[{ lat, lng, name }]>
location.reverseGeocode(lat, lng, locale?)¶
坐标转地址。参数: lat (number), lng (number), locale (string, 可选) 返回: [{ name, country, locality, ... }]
locale 参数: 可选,指定语言(如 'zh_CN', 'en_US'),默认使用系统语言
返回值字段:
- name - 地点名称
- country - 国家
- locality - 城市
- administrativeArea - 省/州
- subLocality - 区/县
- thoroughfare - 街道
- postalCode - 邮编
const results = location.reverseGeocode(39.9, 116.4);
if (results.length > 0) {
const addr = results[0];
console.log(`${addr.country} ${addr.locality} ${addr.thoroughfare}`);
}
// 指定语言
const enResults = location.reverseGeocode(39.9, 116.4, 'en_US');
const zhResults = location.reverseGeocode(39.9, 116.4, 'zh_CN');
location.reverseGeocodeAsync(lat, lng, locale?)¶
异步坐标转地址。参数: lat (number), lng (number), locale (string, 可选) 返回: Promise<[{ name, country, locality, ... }]>
完整示例¶
示例 1: 获取当前位置¶
function getCurrentLocation() {
if (!location.isAuthorized()) {
console.log('请求定位权限...');
location.requestAccess();
return null;
}
const pos = location.getCurrent();
if (pos) {
console.log(`纬度: ${pos.lat}`);
console.log(`经度: ${pos.lng}`);
console.log(`精度: ${pos.accuracy} 米`);
return pos;
} else {
console.error('无法获取位置');
return null;
}
}
getCurrentLocation();
示例 2: 距离计算¶
function calculateDistance(from, to) {
const distance = location.distance(
from.lat, from.lng,
to.lat, to.lng
);
const km = (distance / 1000).toFixed(2);
console.log(`距离: ${km} 公里`);
return distance;
}
const beijing = { lat: 39.9, lng: 116.4 };
const shanghai = { lat: 31.2, lng: 121.5 };
calculateDistance(beijing, shanghai);
示例 3: 地理编码¶
function searchLocation(address) {
const results = location.geocode(address);
if (results.length === 0) {
console.log('未找到结果');
return null;
}
console.log(`找到 ${results.length} 个结果:`);
results.forEach((r, i) => {
console.log(`${i + 1}. ${r.name} (${r.lat}, ${r.lng})`);
});
return results[0];
}
searchLocation('北京天安门');
示例 4: 反向地理编码¶
function getAddress(lat, lng) {
const results = location.reverseGeocode(lat, lng);
if (results.length === 0) {
console.log('未找到地址');
return null;
}
const addr = results[0];
const fullAddress = [
addr.country,
addr.administrativeArea,
addr.locality,
addr.subLocality,
addr.thoroughfare
].filter(x => x).join(' ');
console.log('地址:', fullAddress);
return fullAddress;
}
getAddress(39.9, 116.4);
示例 5: 位置监控¶
function monitorLocation() {
let lastPos = null;
setInterval(() => {
const pos = location.getCurrent();
if (!pos) return;
if (lastPos) {
const distance = location.distance(
lastPos.lat, lastPos.lng,
pos.lat, pos.lng
);
if (distance > 100) {
console.log(`移动了 ${distance.toFixed(0)} 米`);
notification.send('位置变化', `移动了 ${distance.toFixed(0)} 米`);
}
}
lastPos = pos;
}, 60000); // 每分钟检查一次
}
monitorLocation();
示例 6: 定位服务控制(TrollStore)¶
function toggleLocationService() {
if (!location.hasTrollStorePermission()) {
console.error('需要 TrollStore 权限');
return false;
}
const result = location.toggleLocationServices();
if (result.success) {
const status = result.enabled ? '已开启' : '已关闭';
console.log(`定位服务${status}`);
notification.send('定位服务', status);
return true;
} else {
console.error('切换失败:', result.message);
return false;
}
}
toggleLocationService();
最佳实践¶
1. 检查权限¶
// ✅ 正确
if (location.isAuthorized()) {
const pos = location.getCurrent();
}
// ❌ 错误 - 不检查权限
const pos = location.getCurrent(); // 可能返回 null
2. 处理空值¶
// ✅ 正确
const pos = location.getCurrent();
if (pos) {
console.log(pos.lat, pos.lng);
}
// ❌ 错误 - 不检查空值
const pos = location.getCurrent();
console.log(pos.lat); // 可能报错
3. 使用合适的精度¶
// ✅ 正确 - 检查精度
const pos = location.getCurrent();
if (pos && pos.accuracy < 100) {
// 精度足够,使用位置
processLocation(pos);
}
4. 谨慎使用定位服务开关¶
// ✅ 正确 - 检查权限
if (location.hasTrollStorePermission()) {
location.setLocationServicesEnabled(false);
}
// ❌ 错误 - 不检查权限
location.setLocationServicesEnabled(false); // 会失败
注意事项¶
- 权限要求: 首次使用需要请求定位权限
- 精度: 定位精度受环境影响,室内精度较低
- 超时: 获取位置最多等待 30 秒
- TrollStore: 定位服务开关需要 TrollStore 权限
- 地理编码: 需要网络连接,最多等待 30 秒
- 语言: reverseGeocode 支持指定语言,默认使用系统语言
- 距离单位: distance 返回米,需要自行转换为公里
- 线程安全: 所有操作都是线程安全的