OpenHarmony位置服务模块架构设计
位置服务模块架构设计
1. 模块概述
移动终端设备已经深入人们日常生活的方方面面,如查看所在城市的天气、新闻轶事、出行打车、旅行导航、运动记录。这些习以为常的活动,都离不开定位用户终端设备的位置。当用户处于这些丰富的使用场景中时,系统的位置定位能力可以提供实时准确的位置数据。对于开发者,设计基于位置体验的服务,也可以更好的满足用户的需求。当应用在实现基于设备位置的功能时,如:驾车导航,记录运动轨迹等,可以调用该模块的API接口,完成位置信息的获取
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类
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类
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类
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结构体
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结构体
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接口:
位置开关查询
Location_ResultCode OH_Location_IsLocatingEnabled(bool* enabled);
- 功能:查询位置开关状态
- 参数:
enabled
- 输出参数,返回开关状态 - 返回值:操作结果码
- 异常处理:参数为空时返回
LOCATION_INVALID_PARAM
开始定位
Location_ResultCode OH_Location_StartLocating(const Location_RequestConfig* requestConfig);
- 功能:开始定位并订阅位置变化
- 参数:
requestConfig
- 定位请求配置 - 返回值:操作结果码
- 权限要求:
ohos.permission.APPROXIMATELY_LOCATION
- 异常处理:权限不足时返回
LOCATION_PERMISSION_DENIED
停止定位
Location_ResultCode OH_Location_StopLocating(const Location_RequestConfig* requestConfig);
- 功能:停止定位并取消订阅
- 参数:
requestConfig
- 定位请求配置(需与开始定位时相同) - 返回值:操作结果码
配置接口:
创建请求配置
Location_RequestConfig* OH_Location_CreateRequestConfig(void);
- 功能:创建定位请求配置实例
- 返回值:配置实例指针,失败时返回NULL
设置使用场景
void OH_LocationRequestConfig_SetUseScene(Location_RequestConfig* requestConfig,Location_UseScene useScene);
- 功能:设置定位使用场景
- 参数:
requestConfig
- 配置实例useScene
- 使用场景(导航、运动、交通、生活服务等)
设置回调函数
void OH_LocationRequestConfig_SetCallback(Location_RequestConfig* requestConfig,Location_InfoCallback callback, void* userData);
- 功能:设置位置信息回调函数
- 参数:
requestConfig
- 配置实例callback
- 回调函数指针userData
- 用户数据指针
5.2 数据交换接口
位置数据结构:
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;
回调函数定义:
typedef void (*Location_InfoCallback)(Location_Info* location, void* userData);
错误码定义:
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 整体系统架构
6.2 模块内部架构
6.3 类关系图
6.4 状态机转换图
6.5 接口调用时序图
7. 总结
位置服务模块是OpenHarmony系统中的核心基础服务,采用分层架构设计,支持多种定位技术的融合定位。模块通过C API为上层应用提供统一的位置服务接口,内部通过多个子能力协同工作,实现了高精度、低功耗的位置服务能力。
主要特点:
- 多技术融合:支持GNSS、网络、被动等多种定位技术
- 隐私保护:完善的权限管理和隐私保护机制
- 异步处理:基于事件驱动的异步处理机制
- 高可用性:支持服务状态监控和故障恢复
- 扩展性强:模块化设计,易于扩展新的定位技术
技术亮点:
- 采用单例模式管理核心组件
- 通过代理模式封装远程服务调用
- 使用观察者模式实现事件通知
- 支持多种定位策略的动态切换
- 完善的错误处理和异常管理机制