GPS模块分析之on函数 原创 精华

挖墙脚的农民工
发布于 2022-4-19 11:53
浏览
6收藏

::: hljs-center
定位流程分析之–on函数启动
:::
@[toc](目录

    • 背景

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有具体使用方法时在一一进行分析。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2022-12-14 17:42:18修改
10
收藏 6
回复
举报
3条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

感谢有楼主这样的先锋开路,理解的更透彻了

2
回复
2022-4-19 14:13:21
民之码农
民之码农

666

回复
2022-4-20 09:03:36
科技维度
科技维度

为大佬点赞

回复
2022-4-22 09:35:28
回复
    相关推荐