位置服务模块架构
1. 模块概述
移动终端设备已经深入人们日常生活的方方面面,如查看所在城市的天气、新闻轶事、出行打车、旅行导航、运动记录。这些习以为常的活动,都离不开定位用户终端设备的位置。当用户处于这些丰富的使用场景中时,系统的位置定位能力可以提供实时准确的位置数据。对于开发者,设计基于位置体验的服务,也可以更好的满足用户的需求。当应用在实现基于设备位置的功能时,如:驾车导航,记录运动轨迹等,可以调用该模块的API接口,完成位置信息的获取
源码下载:https://gitee.com/openharmony/base_location
1.1 功能与目标
主要功能:
- 提供多种定位技术的位置服务,包括GNSS定位、基站定位、WLAN/蓝牙定位
- 支持地理编码和反地理编码功能
- 提供地理围栏(Geofence)和信标围栏(Beacon Fence)服务
- 支持位置隐私保护和权限管理
- 提供被动定位和缓存位置服务
目标:
- 为移动终端设备提供实时准确的位置数据
- 支持室内外多种场景下的精确定位
- 满足不同应用场景的定位需求(导航、运动记录、生活服务等)
- 确保用户隐私和数据安全
使用场景:
- 驾车导航和路径规划
- 运动轨迹记录和健身应用
- 基于位置的生活服务(天气、新闻、打车等)
- 室内定位和POI服务
- 地理围栏监控和位置提醒
1.2 系统位置
位置服务模块是OpenHarmony系统中的核心基础服务模块,属于系统能力层(SystemCapability)的重要组成部分。
系统位置:
- 位于系统服务层,为上层应用提供位置服务能力
- 与系统权限管理、网络管理、设备管理等多个系统模块协作
- 作为系统能力的一部分,通过SA(System Ability)机制提供服务
模块关系:
- 依赖系统权限管理模块进行权限验证
- 依赖网络管理模块进行网络定位
- 依赖设备管理模块获取硬件定位能力
- 为上层应用框架提供位置服务接口
1.3 设计思路与模式
设计思路:
- 采用分层架构设计,将接口层、框架层、服务层分离
- 支持多种定位技术的融合定位
- 实现异步处理和事件驱动机制
- 注重隐私保护和权限管理
设计模式:
- 单例模式:CountryCodeManager等核心管理器采用单例模式
- 代理模式:通过代理对象封装远程服务调用
- 观察者模式:位置状态变化通过回调机制通知
- 策略模式:不同定位技术采用不同的策略实现
- 工厂模式:位置请求配置的创建和管理
2. 模块结构
2.1 源文件与头文件
主要头文件:
oh_location.h
- C API接口定义oh_location_type.h
- 位置数据类型定义constant_definition.h
- 常量定义和错误码country_code_manager.h
- 国家代码管理器app_identity.h
- 应用身份标识async_context.h
- 异步上下文管理
主要源文件:
locator_impl.cpp
- 定位器实现locator_ability.cpp
- 定位服务能力gnss_ability.cpp
- GNSS定位能力network_ability.cpp
- 网络定位能力passive_ability.cpp
- 被动定位能力geo_convert_service.cpp
- 地理编码服务
2.2 类、结构体、函数与方法
核心类:
LocatorAbility类
cpp
class LocatorAbility : public SystemAbility, public LocatorServiceStub {
public:
static LocatorAbility* GetInstance();
void OnStart() override;
void OnStop() override;
LocationErrCode StartLocating(const RequestConfig& requestConfig,
const sptr<ILocatorCallback>& cb);
LocationErrCode StopLocating(const sptr<ILocatorCallback>& cb);
void GetSwitchState(int& state);
void GetCacheLocation(Location& location);
private:
bool CheckLocationPermission(uint32_t callingTokenId, uint32_t callingFirstTokenid);
bool CheckRequestAvailable(LocatorInterfaceCode code, AppIdentity &identity);
std::shared_ptr<RequestManager> requestManager_;
std::shared_ptr<ReportManager> reportManager_;
};
CountryCodeManager类
cpp
class CountryCodeManager {
public:
static CountryCodeManager* GetInstance();
std::shared_ptr<CountryCode> GetIsoCountryCode();
void RegisterCountryCodeCallback(const sptr<IRemoteObject>& callback,
AppIdentity &identity);
void UnregisterCountryCodeCallback(const sptr<IRemoteObject>& callback);
private:
std::string GetCountryCodeByLocation(const std::unique_ptr<Location>& location);
void UpdateCountryCode(std::string countryCode, int type);
void NotifyAllListener();
};
AppIdentity类
cpp
class AppIdentity : public Parcelable {
public:
AppIdentity(pid_t uid, pid_t pid, uint32_t tokenId,
uint64_t tokenIdEx, uint32_t firstTokenId);
pid_t GetPid() const;
pid_t GetUid() const;
uint32_t GetTokenId() const;
std::string GetBundleName() const;
bool Marshalling(Parcel& parcel) const;
static std::shared_ptr<AppIdentity> Unmarshalling(Parcel& parcel);
private:
pid_t uid_;
pid_t pid_;
uint32_t tokenId_;
uint64_t tokenIdEx_;
uint32_t firstTokenId_;
std::string bundleName_;
};
核心结构体:
Location结构体
cpp
struct Location {
double latitude; // 纬度
double longitude; // 经度
double altitude; // 海拔
double accuracy; // 精度
double speed; // 速度
double direction; // 方向
int64_t timeStamp; // 时间戳
int64_t timeSinceBoot; // 系统启动时间
int locationSourceType; // 定位源类型
bool isFromMock; // 是否来自模拟
std::string uuid; // 唯一标识
};
RequestConfig结构体
cpp
struct RequestConfig {
int priority; // 优先级
int scenario; // 使用场景
int timeInterval; // 时间间隔
int distanceInterval; // 距离间隔
int maxAccuracy; // 最大精度
bool isLocationPrivacyConfirmed; // 隐私确认状态
};
2.3 继承与多态
继承关系:
LocatorAbility
继承自SystemAbility
和LocatorServiceStub
AppIdentity
继承自Parcelable
,支持序列化- 各种回调类继承自相应的接口基类
多态设计:
- 通过接口抽象实现不同定位技术的统一管理
- 回调机制支持多种事件类型的统一处理
- 策略模式实现不同定位算法的动态切换
3. 模块间交互
3.1 交互描述
与系统模块的交互:
- 权限管理:通过AccessToken模块验证位置权限
- 网络管理:通过NetManager模块进行网络定位
- 设备管理:通过HDF框架访问GNSS硬件
- 事件系统:通过CommonEvent模块处理系统事件
- 数据存储:通过RelationalStore模块存储位置数据
外部库依赖:
- HDF驱动:GNSS、WiFi、蓝牙硬件驱动
- 系统服务:SAMGR、SAFWK等系统框架
- 第三方库:cJSON、ICU、libuv等
异步处理机制:
- 使用FFRT(Fast and Flexible Runtime)进行异步任务处理
- 通过事件循环机制处理位置更新回调
- 支持多线程并发处理多个定位请求
3.2 事件驱动机制
事件类型:
- 位置开关状态变化事件
- 网络状态变化事件
- SIM卡状态变化事件
- 语言环境变化事件
- 位置隐私确认事件
事件处理流程:
- 注册事件监听器
- 接收系统事件通知
- 解析事件参数
- 更新内部状态
- 通知相关回调
4. 状态机转换图
4.1 状态机模型
位置服务模块的状态机包含以下主要状态:
服务状态:
STATE_NOT_START
- 服务未启动STATE_RUNNING
- 服务运行中STATE_STOPPING
- 服务停止中
定位状态:
LOCATING_STATE_UNKNOWN
- 未知状态LOCATING_STATE_LOCATING
- 定位中LOCATING_STATE_SUCCESS
- 定位成功LOCATING_STATE_FAIL
- 定位失败
开关状态:
STATE_OPEN
- 位置开关开启STATE_CLOSE
- 位置开关关闭
4.2 状态切换规则
服务启动流程:
- 系统启动时,位置服务处于
STATE_NOT_START
状态 - 收到启动事件后,进入
STATE_RUNNING
状态 - 初始化各个子模块和事件监听器
- 注册到系统能力管理器
定位状态转换:
- 收到定位请求时,从
LOCATING_STATE_UNKNOWN
进入LOCATING_STATE_LOCATING
- 定位成功时,进入
LOCATING_STATE_SUCCESS
状态 - 定位失败时,进入
LOCATING_STATE_FAIL
状态 - 停止定位时,回到
LOCATING_STATE_UNKNOWN
状态
事件触发条件:
- 位置开关状态变化
- 网络连接状态变化
- 定位请求开始/停止
- 权限状态变化
- 系统配置更新
5. 接口设计
5.1 公共接口
C API接口:
位置开关查询
c
Location_ResultCode OH_Location_IsLocatingEnabled(bool* enabled);
- 功能:查询位置开关状态
- 参数 :
enabled
- 输出参数,返回开关状态 - 返回值:操作结果码
- 异常处理 :参数为空时返回
LOCATION_INVALID_PARAM
开始定位
c
Location_ResultCode OH_Location_StartLocating(const Location_RequestConfig* requestConfig);
- 功能:开始定位并订阅位置变化
- 参数 :
requestConfig
- 定位请求配置 - 返回值:操作结果码
- 权限要求 :
ohos.permission.APPROXIMATELY_LOCATION
- 异常处理 :权限不足时返回
LOCATION_PERMISSION_DENIED
停止定位
c
Location_ResultCode OH_Location_StopLocating(const Location_RequestConfig* requestConfig);
- 功能:停止定位并取消订阅
- 参数 :
requestConfig
- 定位请求配置(需与开始定位时相同) - 返回值:操作结果码
配置接口:
创建请求配置
c
Location_RequestConfig* OH_Location_CreateRequestConfig(void);
- 功能:创建定位请求配置实例
- 返回值:配置实例指针,失败时返回NULL
设置使用场景
c
void OH_LocationRequestConfig_SetUseScene(Location_RequestConfig* requestConfig,
Location_UseScene useScene);
- 功能:设置定位使用场景
- 参数 :
requestConfig
- 配置实例useScene
- 使用场景(导航、运动、交通、生活服务等)
设置回调函数
c
void OH_LocationRequestConfig_SetCallback(Location_RequestConfig* requestConfig,
Location_InfoCallback callback,
void* userData);
- 功能:设置位置信息回调函数
- 参数 :
requestConfig
- 配置实例callback
- 回调函数指针userData
- 用户数据指针
5.2 数据交换接口
位置数据结构:
c
typedef struct Location_BasicInfo {
double latitude; // 纬度 (-90 到 90)
double longitude; // 经度 (-180 到 180)
double altitude; // 海拔(米)
double accuracy; // 水平精度(米)
double speed; // 速度(米/秒)
double direction; // 方向(度,0-360)
int64_t timeForFix; // 定位时间戳
int64_t timeSinceBoot; // 系统启动时间
double altitudeAccuracy; // 垂直精度(米)
double speedAccuracy; // 速度精度(米/秒)
double directionAccuracy; // 方向精度(度)
int64_t uncertaintyOfTimeSinceBoot; // 时间不确定性
Location_SourceType locationSourceType; // 定位源类型
} Location_BasicInfo;
回调函数定义:
c
typedef void (*Location_InfoCallback)(Location_Info* location, void* userData);
错误码定义:
c
typedef enum Location_ResultCode {
LOCATION_SUCCESS = 0, // 成功
LOCATION_PERMISSION_DENIED = 201, // 权限不足
LOCATION_INVALID_PARAM = 401, // 参数错误
LOCATION_NOT_SUPPORTED = 801, // 不支持
LOCATION_SERVICE_UNAVAILABLE = 3301000, // 服务不可用
LOCATION_SWITCH_OFF = 3301100 // 开关关闭
} Location_ResultCode;
6. 系统架构图
6.1 整体系统架构
硬件层 系统层 服务层 框架层 应用层 GNSS芯片 WiFi模块 蓝牙模块 基站模块 权限管理 网络管理 设备管理 事件系统 LocatorAbility
定位服务 GNSSAbility
卫星定位 NetworkAbility
网络定位 PassiveAbility
被动定位 GeocodeService
地理编码 JS API C API NDK NAPI 位置服务应用 导航应用 运动应用
6.2 模块内部架构
子能力层 服务层 框架层 接口层 GNSSAbility
卫星定位 NetworkAbility
网络定位 PassiveAbility
被动定位 GeocodeService
地理编码 LocatorAbility
定位服务 RequestManager
请求管理 ReportManager
报告管理 FusionController
融合控制 LocatorImpl
定位器实现 CountryCodeManager
国家代码管理 AppIdentity
应用身份 oh_location.h
C API oh_location_type.h
数据类型 constant_definition.h
常量定义
6.3 类关系图
LocatorAbility -requestManager_ RequestManager -reportManager_ ReportManager +GetInstance() +OnStart() : void +OnStop() : void +StartLocating() : LocationErrCode +StopLocating() : LocationErrCode -CheckLocationPermission() : bool CountryCodeManager +GetInstance() +GetIsoCountryCode() +RegisterCountryCodeCallback() : void +UnregisterCountryCodeCallback() : void -GetCountryCodeByLocation() : string -UpdateCountryCode() : void AppIdentity +GetPid() : pid_t +GetUid() : pid_t +GetTokenId() : uint32_t +GetBundleName() : string +Marshalling() : bool +Unmarshalling() Location +latitude double +longitude double +altitude double +accuracy double +speed double +direction double +timeStamp int64_t +locationSourceType int RequestConfig +priority int +scenario int +timeInterval int +distanceInterval int +maxAccuracy int <<interface>> ILocatorCallback +OnLocationReport() : void +OnLocatingStatusChange() : void +OnErrorReport() : void
6.4 状态机转换图
系统启动 OnStart() OnStop() 停止完成 收到定位请求 开始定位 定位成功 定位失败 停止定位 停止定位 位置开关开启 位置开关关闭 状态同步 状态同步 NotStarted Running Stopping LocatingUnknown Locating LocatingSuccess LocatingFail SwitchOpen SwitchClose 定位过程中可能触发
多种事件和回调
6.5 接口调用时序图
应用程序 C API LocatorAbility GNSSAbility NetworkAbility 回调函数 OH_Location_IsLocatingEnabled() GetSwitchState() 开关状态 返回状态 OH_Location_StartLocating() StartLocating() CheckLocationPermission() CheckRequestAvailable() 启动GNSS定位 启动网络定位 启动结果 返回结果 OnLocationReport() OnLocationReport() 位置信息回调 OH_Location_StopLocating() StopLocating() 停止GNSS定位 停止网络定位 停止结果 返回结果 应用程序 C API LocatorAbility GNSSAbility NetworkAbility 回调函数
7. 总结
位置服务模块是OpenHarmony系统中的核心基础服务,采用分层架构设计,支持多种定位技术的融合定位。模块通过C API为上层应用提供统一的位置服务接口,内部通过多个子能力协同工作,实现了高精度、低功耗的位置服务能力。
主要特点:
- 多技术融合:支持GNSS、网络、被动等多种定位技术
- 隐私保护:完善的权限管理和隐私保护机制
- 异步处理:基于事件驱动的异步处理机制
- 高可用性:支持服务状态监控和故障恢复
- 扩展性强:模块化设计,易于扩展新的定位技术
技术亮点:
- 采用单例模式管理核心组件
- 通过代理模式封装远程服务调用
- 使用观察者模式实现事件通知
- 支持多种定位策略的动态切换
- 完善的错误处理和异常管理机制