GPS模块分析之ON函数

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

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

​51CTO OpenHarmony技术社区​

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

背景

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)调用对应位置服务打开对应的接口。

应用代码如下:

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

应用截图:

代码数据流程

开发板通过配置连接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​

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2022-01-12 14:45:26

鸿蒙HarmonyOS应用

2015-09-11 09:15:32

RyuSDN

2020-09-04 06:32:20

Pythonshutil函数

2022-08-27 08:02:09

SQL函数语法

2021-02-16 10:55:02

Nodejs模块

2014-11-13 14:07:04

2017-03-09 13:11:48

Oracle分析函数

2010-09-16 09:35:17

SQL函数

2010-09-10 14:05:12

SQL聚合函数

2011-05-26 10:05:48

MongoDB

2010-07-12 11:38:24

SQL Server函

2009-10-27 17:10:05

Linux安全模块

2019-09-02 10:51:59

Python脚本语言程序员

2019-08-28 16:18:39

JavaScriptJS前端

2017-07-13 11:08:52

PythonC模块性能分析

2020-07-21 14:19:18

JVM编程语言

2011-05-26 16:18:51

Mongodb

2011-08-29 15:53:04

Lua位运算

2010-09-10 15:51:51

SQL分析函数

2010-03-16 20:27:52

Python模块
点赞
收藏

51CTO技术栈公众号