4

GPS模块分析之ON函数

 2 years ago
source link: https://os.51cto.com/article/707280.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

b693e0583029472584c74938fdfa85bf92c1dc.png

​想了解更多内容,请访问:​

​51CTO OpenHarmony技术社区​

​https://ost.51cto.com​

3月30日openharmony3.1版本发布,openharmony新增许多服务功能组件,具体新添加的功能可以通过社区获取,当然新增组件中包含位置服务组件,用于位置相关的服务功能如定位,导航等等。本文通过详细代码具体分析其数据流程。

注意:代码分析需要一定c/c++代码阅读知识,当然由于代码为个人理解和社区代码不完的原因,会存在理解上面的偏差。

location介绍

location仓库位于base目录下面,其具体位置如图:

6938eab517b2aab7de2810beb580720458dfe8.png

location 简介说明

位置能力用于确定用户设备在哪里,系统使用位置坐标标示设备的位置,并用多种定位技术提供服务,如GNSS定位、基站定位、WLAN/蓝牙定位(基站定位、WLAN/蓝牙定位后续统称“网络定位技术”)。通过这些定位技术,无论用户设备在室内或是户外,都可以准确地确定设备位置。

系统以1984年世界大地坐标系统为参考,使用经度、纬度数据描述地球上的一个位置。

GNSS定位

基于全球导航系统,包含:GPS、GLONASS、北斗、Galileo等,通过导航,设备芯片提供的定位算法,来确定设备准确位置。定位过程具体使用哪些定位系统,取决于用户设备的硬件能力。

根据设备当前驻网基站和相邻基站的位置,估算设备当前位置。此定位方式的定位结果精度相对较低,并且需要设备可以访问蜂窝网络。

WLAN、蓝牙定位

根据设备可搜索到的周围WLAN、蓝牙设备位置,估算设备当前位置。此定位方式的定位结果精度依赖设备周围可见的固定WLAN、蓝牙设备的分布,密度较高时,精度也相较与基站定位方式更高,同时也需要设备可以访问网络。

说明:代码验证使用开发板为RK3568开发板。代码为主线4月8日代码。应用开发deveco studio API we为9版本,应用采用ets语言开发。

47f354b3744a4cdc955467fe3ea75fd413e733.png

使用deveco 编写一个简单的应用。通应用(即使用js)调用对应位置服务打开对应的接口。

应用代码如下:

tring = ''
  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;
    });
  }
}

应用截图:

37afb0a00c7e37caf7b5266ea61a81af62a18a.png

代码数据流程

开发板通过配置连接wifi,并打开位置信息(设置->隐私->位置),运行编译安装好的应用,通过hilog收集开发板中对应日志信息。我们可以逐步了解数据流转过程。注意:由于当前位置的使用没有具体的指导手册,位置授权处理是通过对CheckLocationPermission函数进行修改(应用中配置main_pages.json配置权限未见起作用)。

修改如下:

a20168940713f5f011f8660814e08d92ba80fb.png

通过hilog 获取日志。我们可以收集部分location 对应的信息。通过02300标识筛选与位置相关的日志信息。日志信息如图(当前图片日志信息已经在代码中增添一部分,非代码原始日志):

a71dbd0570d26a24ad30339b208c0fbce55243.png

位置流程框架

当开启应用时,从APP到底层的流程如下:

08faedd25b611d9e471060d97ea2df71d8506c.png

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

b387805947d45111553081b06e0bc900adb0dc.png

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

b5b8e8101311c2400a28305fbe58da17be7562.png

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​

71eea7105a1cf9982d2996c42d853b97bd50ef.jpg


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK