天天看點

GPS子產品分析之on函數

::: hljs-center

定位流程分析之--on函數啟動

:::

(目錄

    • 背景

3月30日openharmony3.1版本釋出,openharmony新增許多服務功能元件,具體新添加的功能可以通過社群擷取,當然新增元件中包含位置服務元件,用于位置相關的服務功能如定位,導航等等。本文通過詳細代碼具體分析其資料流程。

注意:代碼分析需要一定c/c++代碼閱讀知識,當然由于代碼為個人了解和社群代碼不完的原因,會存在了解上面的偏差。

    • location介紹

      • 倉庫位置

location倉庫位于base目錄下面,其具體位置如圖:

GPS子產品分析之on函數
      • location 簡介說明

位置能力用于确定使用者裝置在哪裡,系統使用位置坐标标示裝置的位置,并用多種定位技術提供服務,如GNSS定位、基站定位、WLAN/藍牙定位(基站定位、WLAN/藍牙定位後續統稱“網絡定位技術”)。通過這些定位技術,無論使用者裝置在室内或是戶外,都可以準确地确定裝置位置。

        • 坐标

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

        • GNSS定位

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

        • 基站定位

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

        • WLAN、藍牙定位

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

      • 架構介紹

說明:代碼驗證使用開發闆為RK3568開發闆。代碼為主線4月8日代碼。應用開發deveco studio API we為9版本,應用采用ets語言開發

GPS子產品分析之on函數
    • 應用開發

使用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;
    });
  }
}
           

應用截圖:

GPS子產品分析之on函數
    • 代碼資料流程

開發闆通過配置連接配接wifi,并打開位置資訊(設定->隐私->位置),運作編譯安裝好的應用,通過hilog收集開發闆中對應日志資訊。我們可以逐漸了解資料流轉過程。注意:由于目前位置的使用沒有具體的指導手冊,位置授權處理是通過對CheckLocationPermission函數進行修改(應用中配置main_pages.json配置權限未見起作用)。

修改如下:

GPS子產品分析之on函數

通過hilog 擷取日志。我們可以收集部分location 對應的資訊。通過02300辨別篩選與位置相關的日志資訊。日志資訊如圖(目前圖檔日志資訊已經在代碼中增添一部分,非代碼原始日志):

GPS子產品分析之on函數
      • 位置流程架構

當開啟應用時,從APP到底層的流程如下:

GPS子產品分析之on函數

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

GPS子產品分析之on函數

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配置

GPS子產品分析之on函數
      • 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

繼續閱讀