融合多元定位技術,幫助應用破解精準定位難題
從查閱天氣到記錄運動軌跡,從打車到路徑規劃等,移動終端已深入人們日常生活的方方面面,看似簡單的操作背后,都依賴于精準的定位技術。對于應用開發者,位置數據的實時性與準確性直接決定用戶體驗。當前主流定位技術正面臨兩難選擇:GPS等衛星定位雖能實現<5米的高精度,卻需長時間開啟硬件模塊,導致設備耗電量激增,且冷啟動時受衛星信號搜索、數據計算影響,等待時長普遍達10-30秒;而基站/Wi-Fi定位雖能秒級響應并降低功耗,但精度可能擴大至百米級,難以支撐精準導航等深度場景。
HarmonyOS SDK位置服務(Location Kit)的位置子系統使用多種定位技術提供服務,如GNSS定位、基站定位、WLAN/藍牙定位(基站定位、WLAN/藍牙定位后續統稱"網絡定位技術");通過這些定位技術,無論用戶設備在室內或是戶外,都可以較為準確地確定設備位置。
Location Kit除了提供基礎的定位服務之外,還提供了地理圍欄、地理編碼、逆地理編碼、國家碼等功能和接口。

開發步驟
-
獲取設備的位置信息,需要有位置權限,位置權限申請的方法和步驟見申請位置權限開發指導。
-
導入geoLocationManager模塊,所有與基礎定位能力相關的功能API,都是通過該模塊提供的。
import { geoLocationManager } from '@kit.LocationKit';
-
調用獲取位置接口之前需要先判斷位置開關是否打開。
查詢當前位置開關狀態,返回結果為布爾值,true代表位置開關開啟,false代表位置開關關閉,示例代碼如下:
import { geoLocationManager } from '@kit.LocationKit';
try {
let locationEnabled = geoLocationManager.isLocationEnabled();
} catch (err) {
console.error("errCode:" + err.code + ", message:" + err.message);
}
如果位置開關未開啟,可以拉起全局開關設置彈框,引導用戶打開位置開關,具體可參考拉起全局開關設置彈框。
- 單次獲取當前設備位置。多用于查看當前位置、簽到打卡、服務推薦等場景。
方式一:獲取系統緩存的最新位置。
如果系統當前沒有緩存位置會返回錯誤碼。
推薦優先使用該接口獲取位置,可以減少系統功耗。
如果對位置的新鮮度比較敏感,可以先獲取緩存位置,將位置中的時間戳與當前時間對比,若新鮮度不滿足預期可以使用方式二獲取位置。
import { geoLocationManager } from '@kit.LocationKit';
import { BusinessError } from '@kit.BasicServicesKit'
try {
let location = geoLocationManager.getLastLocation();
} catch (err) {
console.error("errCode:" + JSON.stringify(err));
}
方式二:獲取當前位置。
首先要實例化SingleLocationRequest對象,用于告知系統該向應用提供何種類型的位置服務,以及單次定位超時時間。
- 設置LocatingPriority:
如果對位置的返回精度要求較高,建議LocatingPriority參數優先選擇PRIORITY_ACCURACY,會將一段時間內精度較好的結果返回給應用。
如果對定位速度要求較高,建議LocatingPriority參數選擇PRIORITY_LOCATING_SPEED,會將最先拿到的定位結果返回給應用。
兩種定位策略均會同時使用GNSS定位和網絡定位技術,以便在室內和戶外場景下均可以獲取到位置結果,對設備的硬件資源消耗較大,功耗也較大。
- 設置locatingTimeoutMs:
因為設備環境、設備所處狀態、系統功耗管控策略等的影響,定位返回的時延會有較大波動,建議把單次定位超時時間設置為10秒。
以快速定位策略(PRIORITY_LOCATING_SPEED)為例,調用方式如下:
import { geoLocationManager } from '@kit.LocationKit';
import { BusinessError } from '@kit.BasicServicesKit'
let request: geoLocationManager.SingleLocationRequest = {
'locatingPriority': geoLocationManager.LocatingPriority.PRIORITY_LOCATING_SPEED,
'locatingTimeoutMs': 10000
}
try {
geoLocationManager.getCurrentLocation(request).then((result) => { // 調用getCurrentLocation獲取當前設備位置,通過promise接收上報的位置
console.info('current location: ' + JSON.stringify(result));
})
.catch((error:BusinessError) => { // 接收上報的錯誤碼
console.error('promise, getCurrentLocation: error=' + JSON.stringify(error));
});
} catch (err) {
console.error("errCode:" + JSON.stringify(err));
}
通過本模塊獲取到的坐標均為WGS-84坐標系坐標點,如需使用其它坐標系類型的坐標點,請進行坐標系轉換后再使用。
可參考Map Kit提供的地圖計算工具進行坐標轉換。
- 持續定位。多用于導航、運動軌跡、出行等場景。
首先要實例化ContinuousLocationRequest對象,用于告知系統該向應用提供何種類型的位置服務,以及位置結果上報的頻率。
設置locationScenario
建議locationScenario參數優先根據應用的使用場景進行設置,該參數枚舉值定義參見UserActivityScenario,例如地圖在導航時使用NAVIGATION參數,可以持續在室內和室外場景獲取位置用于導航。
設置interval
表示上報位置信息的時間間隔,單位是秒,默認值為1秒。如果對位置上報時間間隔無特殊要求,可以不填寫該字段。
以地圖導航場景為例,調用方式如下:
import { geoLocationManager } from '@kit.LocationKit';
let request: geoLocationManager.ContinuousLocationRequest= {
'interval': 1,
'locationScenario': geoLocationManager.UserActivityScenario.NAVIGATION
}
let locationCallback = (location:geoLocationManager.Location):void => {
console.info('locationCallback: data: ' + JSON.stringify(location));
};
try {
geoLocationManager.on('locationChange', request, locationCallback);
} catch (err) {
console.error("errCode:" + JSON.stringify(err));
}
如果不主動結束定位可能導致設備功耗高,耗電快;建議在不需要獲取定位信息時及時結束定位。
// 該回調函數需要與on接口傳入的回調函數保持一致。
geoLocationManager.off('locationChange', locationCallback);
了解更多詳情>>
訪問位置服務聯盟官網
浙公網安備 33010602011771號