::: hljs-center
定位流程分析之--on函數啟動
:::
(目錄
-
-
背景
-
3月30日openharmony3.1版本釋出,openharmony新增許多服務功能元件,具體新添加的功能可以通過社群擷取,當然新增元件中包含位置服務元件,用于位置相關的服務功能如定位,導航等等。本文通過詳細代碼具體分析其資料流程。
注意:代碼分析需要一定c/c++代碼閱讀知識,當然由于代碼為個人了解和社群代碼不完的原因,會存在了解上面的偏差。
-
-
location介紹
-
-
-
-
倉庫位置
-
-
location倉庫位于base目錄下面,其具體位置如圖:

-
-
-
location 簡介說明
-
-
位置能力用于确定使用者裝置在哪裡,系統使用位置坐标标示裝置的位置,并用多種定位技術提供服務,如GNSS定位、基站定位、WLAN/藍牙定位(基站定位、WLAN/藍牙定位後續統稱“網絡定位技術”)。通過這些定位技術,無論使用者裝置在室内或是戶外,都可以準确地确定裝置位置。
-
-
-
-
坐标
-
-
-
系統以1984年世界大地坐标系統為參考,使用經度、緯度資料描述地球上的一個位置。
-
-
-
-
GNSS定位
-
-
-
基于全球導航系統,包含:GPS、GLONASS、北鬥、Galileo等,通過導航,裝置晶片提供的定位算法,來确定裝置準确位置。定位過程具體使用哪些定位系統,取決于使用者裝置的硬體能力。
-
-
-
-
基站定位
-
-
-
根據裝置目前駐網基站和相鄰基站的位置,估算裝置目前位置。此定位方式的定位結果精度相對較低,并且需要裝置可以通路蜂窩網絡。
-
-
-
-
WLAN、藍牙定位
-
-
-
根據裝置可搜尋到的周圍WLAN、藍牙裝置位置,估算裝置目前位置。此定位方式的定位結果精度依賴裝置周圍可見的固定WLAN、藍牙裝置的分布,密度較高時,精度也相較與基站定位方式更高,同時也需要裝置可以通路網絡。
-
-
-
架構介紹
-
-
說明:代碼驗證使用開發闆為RK3568開發闆。代碼為主線4月8日代碼。應用開發deveco studio API we為9版本,應用采用ets語言開發
-
-
應用開發
-
使用deveco 編寫一個簡單的應用。通應用(即使用js)調用對應位置服務打開對應的接口。
應用代碼如下:
@Entry
@Component
struct locator {
@State text: string = ''
private isWlanEnable: boolean = false;
private islocationon: boolean = false;
@State message: string = 'Hello World'
build() {
Row() {
Column() {
Toggle({ type: ToggleType.Switch, isOn: this.isWlanEnable })
.width(50)
.height(40)
.onChange((isOn: boolean) => {
this.isWlanEnable = !this.isWlanEnable;
if (this.isWlanEnable) {
this.islocationon = true;
this.switchOn();
}
})
Text("位址" + this.text)
.fontSize(50)
}
.width('100%')
}
.height('100%')
}
private switchOn() {
//導航場景
var requestInfo = {'scenario': 0x301, 'timeInterval': 0, 'distanceInterval': 0, 'maxAccuracy': 0};
//精度優先的
//var requestInfo = {'priority': 0x201, 'timeInterval': 0, 'distanceInterval': 10, 'maxAccuracy': 10};
var locationChange = (location) => {
console.log('locationChanger: data: ' + JSON.stringify(location));
};
// 打開位置資訊
geolocation.on('locationChange', requestInfo, locationChange);
// 位置資訊轉換
var reverseGeocodeRequest = {"latitude": 31.12, "longitude": 121.11, "maxItems": 1};
geolocation.getAddressesFromLocation(reverseGeocodeRequest, (data) => {
console.log('getAddressesFromLocation address: ' + JSON.stringify(data));
this.text = data;
});
}
}
應用截圖:
-
-
代碼資料流程
-
開發闆通過配置連接配接wifi,并打開位置資訊(設定->隐私->位置),運作編譯安裝好的應用,通過hilog收集開發闆中對應日志資訊。我們可以逐漸了解資料流轉過程。注意:由于目前位置的使用沒有具體的指導手冊,位置授權處理是通過對CheckLocationPermission函數進行修改(應用中配置main_pages.json配置權限未見起作用)。
修改如下:
通過hilog 擷取日志。我們可以收集部分location 對應的資訊。通過02300辨別篩選與位置相關的日志資訊。日志資訊如圖(目前圖檔日志資訊已經在代碼中增添一部分,非代碼原始日志):
-
-
-
位置流程架構
-
-
當開啟應用時,從APP到底層的流程如下:
On(napi_env env, napi_callback_info cbinfo) 函數為拉起位置服務相關功能入口函數。
-
-
-
On函數實作機制
-
-
napi_value On(napi_env env, napi_callback_info cbinfo)
cbinfo 資訊為js傳入資訊參數資訊,具體實作過程可以分析相關代碼。
on 函數中實作類型有以下幾種:
1、locationServiceState
2、gnssStatusChange
3、nmeaMessageChange
4、cachedGnssLocationsReporting
5、fenceStat
6、locationChange
目前暫時不清楚其他幾種類型的使用方法。需要後期研究。目前使用的為locationChange類型。
通過locationChange(APP配置)進入到SubscribeLocationChange。其中SubscribeLocationChange 中JsObjToLocationRequest将相關配置資訊轉換儲存到對應的配置檔案中。注意JsObjToLocationRequest由于JsObjectToInt沒有對傳回值進行判斷,這裡存在一個BUG。不存在的參數會将上一個參數的值傳遞到下一個變量。參考issue
g_locatorNapiPtr->StartLocating(requestConfig, locatorCallback); 拉起定位。
-
-
-
StartLocating
-
-
int LocatorAbility::StartLocating(std::unique_ptr<RequestConfig>& requestConfig, sptr<ILocatorCallback>& callback, std::string bundleName, pid_t pid, pid_t uid)
進行對應的ability配置
-
-
-
ProxySendLocationRequest
-
-
ProxySendLocationRequest 函數中,對應的使用3種類型的能力GNSS_ABILITY、NETWORK_ABILITY、PASSIVE_ABILITY。
由日志分析detect passive/gps/network ability requests(size:0) work record:[]這3種ability 的size為0,暫不清楚這種影響。
行 28932: 04-18 16:56:52.132 368 368 I 02300/RequestManager: RequestManager::HandleStartLocating
行 28934: 04-18 16:56:52.132 368 368 D 02300/Locator: RequestConfig::ToString
行 28941: 04-18 16:56:52.132 368 368 I 02300/RequestManager: RestorRequest add request:[request config: scenario : 513, location priority : 513, timeInterval : 0, distanceInterval : 0, maxAccuracy : 0, fixNumber : 0] from pid:1891, uid:20010033, location.ILocator, callback's address : 0x1d80390
行 28943: 04-18 16:56:52.132 368 368 D 02300/RequestManager: add new receiver with new callback
行 28945: 04-18 16:56:52.132 368 368 D 02300/RequestManager: RequestManager::UpdateRequestRecord1
行 28948: 04-18 16:56:52.132 368 368 E 02300/RequestManager: can not get proxy name according to request configuration
行 28950: 04-18 16:56:52.132 368 368 E 02300/RequestManager: RequestManager::HandleRequest
行 28952: 04-18 16:56:52.132 368 368 D 02300/RequestManager: RequestManager ProxySendLocationRequest
行 28955: 04-18 16:56:52.132 368 368 D 02300/RequestManager: detect gps ability requests(size:0) work record:[]
行 28957: 04-18 16:56:52.132 368 368 D 02300/RequestManager: RequestManager GetRemoteObject
行 28960: 04-18 16:56:52.132 368 368 I 02300/GnssAbility: GnssAbilityStub OnRemoteRequest cmd = 1, flags= 0, pid= 368, uid= 0
行 28962: 04-18 16:56:52.132 368 368 I 02300/GnssAbility: refrash requirements
行 28965: 04-18 16:56:52.132 368 368 D 02300/GnssAbility: RemoteRequest Transact ErrCode = 0
行 28968: 04-18 16:56:52.132 368 368 I 02300/FusionController: fused flag:0
行 28971: 04-18 16:56:52.132 368 368 I 02300/NetworkAbility: NetworkAbilityStub OnRemoteRequest cmd = 4, flags= 0, pid= 368, uid= 0
行 28973: 04-18 16:56:52.132 368 368 E 02300/NetworkAbility: SelfRequest 0
行 28976: 04-18 16:56:52.132 368 368 I 02300/NetworkAbility: refrash requirements
行 28978: 04-18 16:56:52.132 368 368 D 02300/RequestManager: RequestManager ProxySendLocationRequest
行 28980: 04-18 16:56:52.132 368 368 D 02300/RequestManager: detect network ability requests(size:0) work record:[]
行 28982: 04-18 16:56:52.132 368 368 D 02300/RequestManager: RequestManager GetRemoteObject
行 28985: 04-18 16:56:52.132 368 368 I 02300/NetworkAbility: NetworkAbilityStub OnRemoteRequest cmd = 1, flags= 0, pid= 368, uid= 0
行 28987: 04-18 16:56:52.132 368 368 I 02300/NetworkAbility: refrash requirements
行 28989: 04-18 16:56:52.132 368 368 D 02300/NetworkAbility: RemoteRequest Transact ErrCode = 0
行 28992: 04-18 16:56:52.132 368 368 D 02300/RequestManager: RequestManager ProxySendLocationRequest
行 28994: 04-18 16:56:52.132 368 368 D 02300/RequestManager: detect passive ability requests(size:0) work record:[]
行 28996: 04-18 16:56:52.132 368 368 D 02300/RequestManager: RequestManager GetRemoteObject
行 28999: 04-18 16:56:52.132 368 368 I 02300/PassiveAbility: PassiveAbilityStub OnRemoteRequest cmd = 1, flags= 0, pid= 368, uid= 0
行 29002: 04-18 16:56:52.132 368 368 I 02300/PassiveAbility: refrash requirements
行 29004: 04-18 16:56:52.132 368 368 D 02300/PassiveAbility: RemoteRequest Transact ErrCode = 0
行 29010: 04-18 16:56:52.133 368 368 D 02300/LocatorCallback: OnLocatingStatusChange Transact ErrCode
-
-
結束
-
location on 函數分析流程到此結束其中隻是簡單的分析了locationChange 類型的流程,其餘locationServiceState/gnssStatusChange/nmeaMessageChange/cachedGnssLocationsReporting/fenceStatusChange有具體使用方法時在一一進行分析。
想了解更多關于鴻蒙的内容,請通路:
51CTO OpenHarmony技術社群
https://ost.51cto.com/#bkwz