HarmonyOS 位置服務開發指南

HarmonyOS開發者社群發表於2023-11-27

位置服務開發概述

移動終端裝置已經深入人們日常生活的方方面面,如檢視所在城市的天氣、新聞軼事、出行叫車、旅行導航、運動記錄。這些習以為常的活動,都離不開定位使用者終端裝置的位置。

當使用者處於這些豐富的使用場景中時,系統的位置能力可以提供實時準確的位置資料。對於開發者,設計基於位置體驗的服務,也可以使應用的使用體驗更貼近每個使用者。

當應用在實現基於裝置位置的功能時,如:駕車導航,記錄運動軌跡等,可以呼叫該模組的 API 介面,完成位置資訊的獲取。

位置服務簡介

位置子系統使用多種定位技術提供服務,如 GNSS 定位、基站定位、WLAN/藍芽定位(基站定位、WLAN/藍芽定位後續統稱“網路定位技術”);透過這些定位技術,無論使用者裝置在室內或是戶外,都可以準確地確定裝置位置。

位置服務除了提供基礎的定位服務之外,還提供了地理圍欄、地理編碼、逆地理編碼、國家碼等功能和介面。

●  座標

系統以 1984 年世界大地座標系統為參考,使用經度、緯度資料描述地球上的一個位置。

●  GNSS 定位

基於全球導航衛星系統,包含:GPS、GLONASS、北斗、Galileo 等,透過導航衛星、裝置晶片提供的定位演算法,來確定裝置準確位置。定位過程具體使用哪些定位系統,取決於使用者裝置的硬體能力。

●  基站定位

根據裝置當前駐網基站和相鄰基站的位置,估算裝置當前位置。此定位方式的定位結果精度相對較低,並且需要裝置可以訪問蜂窩網路。

●  WLAN、藍芽定位

根據裝置可搜尋到的周圍 WLAN、藍芽裝置位置,估算裝置當前位置。此定位方式的定位結果精度依賴裝置周圍可見的固定 WLAN、藍芽裝置的分佈,密度較高時,精度也相較於基站定位方式更高,同時也需要裝置可以訪問網路。

運作機制

位置能力作為系統為應用提供的一種基礎服務,需要應用在所使用的業務場景,向系統主動發起請求,並在業務場景結束時,主動結束此請求,在此過程中系統會將實時的定位結果上報給應用。

約束與限制

使用裝置的位置能力,需要使用者進行確認並主動開啟位置開關。如果位置開關沒有開啟,系統不會向任何應用提供位置服務。

裝置位置資訊屬於使用者敏感資料,所以即使使用者已經開啟位置開關,應用在獲取裝置位置前仍需向使用者申請位置訪問許可權。在使用者確認允許後,系統才會嚮應用提供位置服務。

申請位置許可權開發指導


場景概述

應用在使用位置服務系統能力前,需要檢查是否已經獲取使用者授權訪問裝置位置資訊。如未獲得授權,可以向使用者申請需要的位置許可權。

系統提供的定位許可權有:

●  ohos.permission.LOCATION:用於獲取精準位置,精準度在米級別。

●  ohos.permission.APPROXIMATELY_LOCATION:用於獲取模糊位置,精確度為 5 公里。

●  ohos.permission.LOCATION_IN_BACKGROUND:用於應用切換到後臺仍然需要獲取定位資訊的場景。

訪問裝置的位置資訊,必須申請許可權,並且獲得使用者授權。

表 1 位置許可權申請方式介紹

HarmonyOS 位置服務開發指南


如果應用在後臺執行時也需要訪問裝置位置,除需要將應用宣告為允許後臺執行外,還必須申請 ohos.permission.LOCATION_IN_BACKGROUND 許可權,這樣應用在切入後臺之後,系統可以繼續上報位置資訊。

開發者可以在應用配置檔案中宣告所需要的許可權,具體可參考 授權申請指導

位置服務每個介面需要申請哪些許可權可以參見如下文件: 位置服務

開發步驟

具體可參考 授權申請指導

獲取裝置的位置資訊開發指導


場景概述

開發者可以呼叫 HarmonyOS 位置相關介面,獲取裝置實時位置,或者最近的歷史位置。

對於位置敏感的應用業務,建議獲取裝置實時位置資訊。如果不需要裝置實時位置資訊,並且希望儘可能的節省耗電,開發者可以考慮獲取最近的歷史位置。

介面說明

獲取裝置的位置資訊所使用的介面如下,詳細說明參見: 位置服務

表 2 獲取裝置的位置資訊介面介紹

HarmonyOS 位置服務開發指南


開發步驟

1.  獲取裝置的位置資訊,需要有位置許可權,位置許可權申請的方法和步驟見 申請位置許可權開發指導

2.  匯入 geoLocationManager 模組,所有與基礎定位能力相關的功能 API,都是透過該模組提供的。



import geoLocationManager 
from 
'@ohos.geoLocationManager';




3.  例項化 LocationRequest 物件,用於告知系統該向應用提供何種型別的位置服務,以及位置結果上報的頻率。

方式一:

為了面向開發者提供貼近其使用場景的 API 使用方式,系統定義了幾種常見的位置能力使用場景,並針對使用場景做了適當的最佳化處理,應用可以直接匹配使用,簡化開發複雜度。系統當前支援場景如下表所示。

定位場景型別說明

a.  導航場景:NAVIGATION

適用於在戶外定位裝置實時位置的場景,如車載、步行導航。

在此場景下,為保證系統提供位置結果精度最優,主要使用 GNSS 定位技術提供定位服務,結合場景特點,在導航啟動之初,使用者很可能在室內、車庫等遮蔽環境,GNSS 技術很難提供位置服務。

為解決此問題,我們會在 GNSS 提供穩定位置結果之前,使用系統網路定位技術,嚮應用提供位置服務,以在導航初始階段提升使用者體驗。

此場景預設以最小 1 秒間隔上報定位結果,使用此場景的應用必須申請 ohos.permission.LOCATION 許可權,同時獲得使用者授權。

b.  軌跡跟蹤場景:TRAJECTORY_TRACKING

適用於記錄使用者位置軌跡的場景,如運動類應用記錄軌跡功能。主要使用 GNSS 定位技術提供定位服務。

此場景預設以最小 1 秒間隔上報定位結果,並且應用必須申請 ohos.permission.LOCATION 許可權,同時獲得使用者授權。

c.  出行約車場景:CAR_HAILING

適用於使用者出行叫車時定位當前位置的場景,如網約車類應用。

此場景預設以最小 1 秒間隔上報定位結果,並且應用必須申請 ohos.permission.LOCATION 許可權,同時獲得使用者授權。

d.  生活服務場景:DAILY_LIFE_SERVICE

生活服務場景,適用於不需要定位使用者精確位置的使用場景,如新聞資訊、網購、點餐類應用,做推薦、推送時定位使用者大致位置即可。

此場景預設以最小 1 秒間隔上報定位結果,並且應用至少申請 ohos.permission.LOCATION 許可權,同時獲得使用者授權。

e.  無功耗場景:NO_POWER

無功耗場景,適用於不需要主動啟動定位業務。系統在響應其他應用啟動定位業務並上報位置結果時,會同時向請求此場景的應用程式上報定位結果,當前的應用程式不產生定位功耗。

此場景預設以最小 1 秒間隔上報定位結果,並且應用需要申請 ohos.permission.LOCATION 許可權,同時獲得使用者授權。


    
export 
enum LocationRequestScenario {
         UNSET = 
0x300,
         NAVIGATION,
         TRAJECTORY_TRACKING,
         
CAR_HAILING,
         DAILY_LIFE_SERVICE,
         NO_POWER,
     }




以導航場景為例,例項化方式如下:



let requestInfo = {
'scenario': geoLocationManager.
LocationRequestScenario.
NAVIGATION, 
'timeInterval': 
0, 
'distanceInterval': 
0, 
'maxAccuracy': 
0};





方式二:

如果定義的現有場景型別不能滿足所需的開發場景,系統提供了基本的定位優先順序策略型別。

定位優先順序策略型別說明

●  定位精度優先策略:ACCURACY

定位精度優先策略主要以 GNSS 定位技術為主,在開闊場景下可以提供米級的定位精度,具體效能指標依賴使用者裝置的定位硬體能力,但在室內等強遮蔽定位場景下,無法提供準確的位置服務。

●  快速定位優先策略:FIRST_FIX

快速定位優先策略會同時使用 GNSS 定位、基站定位和 WLAN、藍芽定位技術,以便室內和戶外場景下,透過此策略都可以獲得位置結果,當各種定位技術都有提供位置結果時,系統會選擇其中精度較好的結果返回給應用。因為對各種定位技術同時使用,對裝置的硬體資源消耗較大,功耗也較大。

●  低功耗定位優先策略:LOW_POWER

低功耗定位優先策略主要使用基站定位和 WLAN、藍芽定位技術,也可以同時提供室內和戶外場景下的位置服務,因為其依賴周邊基站、可見 WLAN、藍芽裝置的分佈情況,定位結果的精度波動範圍較大,如果對定位結果精度要求不高,或者使用場景多在有基站、可見 WLAN、藍芽裝置高密度分佈的情況下,推薦使用,可以有效節省裝置功耗。


    
export 
enum 
LocationRequestPriority {
         UNSET = 
0x200,
         ACCURACY,
         LOW_POWER,
         FIRST_FIX,
     }




以定位精度優先策略為例,例項化方式如下:



let requestInfo = {
'priority': geoLocationManager.
LocationRequestPriority.
ACCURACY, 
'timeInterval': 
0, 
'distanceInterval': 
0, 
'maxAccuracy': 
0};




4.  例項化 Callback 物件,用於向系統提供位置上報的途徑。

應用需要自行實現系統定義好的回撥介面,並將其例項化。系統在定位成功確定裝置的實時位置結果時,會透過該介面上報給應用。應用程式可以在介面的實現中完成自己的業務邏輯。



let 
locationChange = (
location) => {
    
console.
log(
'locationChanger: data: ' + 
JSON.
stringify(location));
};




5.  啟動定位。


geoLocationManager.
on(
'locationChange', requestInfo, locationChange);




6.  (可選)結束定位。

如果不主動結束定位可能導致裝置功耗高,耗電快;建議在不需要獲取定位資訊時及時結束定位。


geoLocationManager.
off(
'locationChange', locationChange);




如果應用使用場景不需要實時的裝置位置,可以獲取系統快取的最近一次歷史定位結果。



import geoLocationManager 
from 
'@ohos.geoLocationManager';

try {
    
let location = geoLocationManager.
getLastLocation();
} 
catch (err) {
    
console.
error(
"errCode:" + err.
code + 
",errMessage:" + err.
message);
}





(逆)地理編碼轉化開發指導


場景概述

使用座標描述一個位置,非常準確,但是並不直觀,面向使用者表達並不友好。系統向開發者提供了以下兩種轉化能力。

●  地理編碼轉化:將地理描述轉化為具體座標。

●  逆地理編碼轉化能力:將座標轉化為地理描述。

其中地理編碼包含多個屬性來描述位置,包括國家、行政區劃、街道、門牌號、地址描述等等,這樣的資訊更便於使用者理解。

介面說明

進行座標和地理編碼資訊的相互轉化,所使用的介面說明如下,詳細資訊參見: 位置服務

表 3 (逆)地理編碼轉化介面介紹

HarmonyOS 位置服務開發指南


HarmonyOS 位置服務開發指南


開發步驟

說明

GeoConvert 需要訪問後端服務,請確保裝置聯網,以進行資訊獲取。

1.  匯入 geoLocationManager 模組,所有與(逆)地理編碼轉化能力相關的功能 API,都是透過該模組提供的。



import geoLocationManager 
from 
'@ohos.geoLocationManager';




2.  查詢 geoCoder 服務是否可用。

●  呼叫 isGeoServiceAvailable 查詢 geoCoder 服務是否可用,如果服務可用再繼續進行步驟



import geoLocationManager 
from 
'@ohos.geoLocationManager';

try {
    
let isAvailable = geoLocationManager.
isGeocoderAvailable();
} 
catch (err) {
    
console.
error(
"errCode:" + err.
code + 
",errMessage:" + err.
message);
}





3.  獲取轉化結果。

●  呼叫 getAddressesFromLocation,座標轉化地理位置資訊。



let reverseGeocodeRequest = {
"latitude": 
31.12, 
"longitude": 
121.11, 
"maxItems": 
1};

try {
    geoLocationManager.
getAddressesFromLocation(reverseGeocodeRequest, 
(
err, data) => {
        
if (err) {
            
console.
log(
'getAddressesFromLocation err: ' + 
JSON.
stringify(err));
        } 
else {
            
console.
log(
'getAddressesFromLocation data: ' + 
JSON.
stringify(data));
        }
    });
} 
catch (err) {
    
console.
error(
"errCode:" + err.
code + 
",errMessage:" + err.
message);
}




參考介面 API 說明 位置服務 ,應用可以獲得與此座標匹配的 GeoAddress 列表,應用可以根據實際使用需求,讀取相應的引數資料。

●  呼叫 getAddressesFromLocationName 位置描述轉化座標。



let geocodeRequest = {
"description": 
"上海市浦東新區xx路xx號", 
"maxItems": 
1};

try {
    geoLocationManager.
getAddressesFromLocationName(geocodeRequest, 
(
err, data) => {
        
if (err) {
            
console.
log(
'getAddressesFromLocationName err: ' + 
JSON.
stringify(err));
        } 
else {
            
console.
log(
'getAddressesFromLocationName data: ' + 
JSON.
stringify(data));
        }
    });
} 
catch (err) {
    
console.
error(
"errCode:" + err.
code + 
",errMessage:" + err.
message);
}




參考介面 API 說明 位置服務 ,應用可以獲得與位置描述相匹配的 GeoAddress 列表,其中包含對應的座標資料,請參考 API 使用。

如果需要查詢的位置描述可能出現多地重名的請求,可以設定 GeoCodeRequest,透過設定一個經緯度範圍,以高效地獲取期望的準確結果。

地理圍欄開發指導


場景概述

地理圍欄就是虛擬地理邊界,當裝置進入、離開某個特定地理區域時,可以接收自動通知和警告。

目前僅支援圓形圍欄,並且依賴 GNSS 晶片的地理圍欄功能。

應用場景舉例:開發者可以使用地理圍欄,在企業周圍建立一個區域進行廣告定位,在不同的地點,在移動裝置上進行有針對性的促銷優惠。

介面說明

地理圍欄所使用的介面如下,詳細說明參見: 位置服務

表 4 地理圍欄介面介紹

HarmonyOS 位置服務開發指南


開發步驟

1.  使用地理圍欄功能,需要有許可權 ohos.permission.APPROXIMATELY_LOCATION,位置許可權申請的方法和步驟見 申請位置許可權開發指導

2.  匯入 geoLocationManager 模組和 wantAgent 模組。



import geoLocationManager 
from 
'@ohos.geoLocationManager';

import wantAgent 
from 
'@ohos.app.ability.wantAgent';




3.  建立 WantAgentInfo 資訊。

場景一:建立拉起 Ability 的 WantAgentInfo 資訊。



let wantAgentObj = 
null; 
// 用於儲存建立成功的wantAgent物件,後續使用其完成觸發的動作。


// 透過WantAgentInfo的operationType設定動作型別 let wantAgentInfo = {     wants: [        {             deviceId: '',             bundleName: 'com.example.myapplication',             abilityName: 'EntryAbility',             action: '',             entities: [],             uri: '',             parameters: {}        }    ],     operationType: wantAgent. OperationType. START_ABILITY,     requestCode: 0,     wantAgentFlags:[wantAgent. WantAgentFlags. CONSTANT_FLAG] };



場景二:建立釋出 公共事件 的 WantAgentInfo 資訊。



let wantAgentObj = 
null; 
// 用於儲存建立成功的WantAgent物件,後續使用其完成觸發的動作。


// 透過WantAgentInfo的operationType設定動作型別 let wantAgentInfo = {     wants: [        {             action: 'event_name', // 設定事件名             parameters: {},        }    ],     operationType: wantAgent. OperationType. SEND_COMMON_EVENT,     requestCode: 0,     wantAgentFlags: [wantAgent. WantAgentFlags. CONSTANT_FLAG], }



4.  呼叫 getWantAgent() 方法進行建立 WantAgent。

並且在獲取到 WantAgent 物件之後呼叫地理圍欄介面新增圍欄。



// 建立WantAgent
wantAgent.
getWantAgent(wantAgentInfo, 
(
err, data) => {
    
if (err) {
      
console.
error(
'getWantAgent err=' + 
JSON.
stringify(err));
      
return;
    }
    
console.
info(
'getWantAgent success');
    wantAgentObj = data;
    
let requestInfo = {
'priority': 
0x201, 
'scenario': 
0x301, 
"geofence": {
"latitude": 
121, 
"longitude": 
26, 
"radius": 
100, 
"expiration": 
10000}};
    
try {
        geoLocationManager.
on(
'gnssFenceStatusChange', requestInfo, wantAgentObj);
    } 
catch (err) {
        
console.
error(
"errCode:" + err.
code + 
",errMessage:" + err.
message);
    }
});



1.  當裝置進入或者退出該圍欄時,系統會自動觸發 WantAgent 的動作。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70009402/viewspace-2997498/,如需轉載,請註明出處,否則將追究法律責任。

相關文章