鸿蒙App车机导航接力(手机设置目的地在车机继续导航)全解析【华为根技术】
【摘要】 鸿蒙App车机导航接力(手机设置目的地在车机继续导航)全解析1. 引言随着智能网联汽车的普及,车载导航已成为现代出行不可或缺的工具。然而,用户在出行前往往习惯在手机上搜索目的地、规划路线,当进入车内时需要将导航信息迁移到车机系统。传统的手动迁移方式(重新输入地址、重新规划路线)不仅繁琐,还存在安全隐患。鸿蒙操作系统的分布式能力为解决这一问题提供了完美的技术方案。通过"车机导航接力"功能,用户...
鸿蒙App车机导航接力(手机设置目的地在车机继续导航)全解析
1. 引言
2. 技术背景
2.1 鸿蒙分布式能力基础
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2.2 导航接力技术架构
graph TD
A[手机端] -->|分布式软总线| B[鸿蒙分布式内核]
B -->|设备发现与认证| C[车机端]
subgraph 手机端组件
A1[导航应用] --> A2[分布式导航管理器]
A2 --> A3[目的地数据封装]
A3 --> A4[路线规划服务]
A4 --> A5[分布式数据发布]
A6[位置服务] --> A2
end
subgraph 分布式中间件
B1[分布式软总线] --> B2[设备发现服务]
B2 --> B3[安全认证模块]
B3 --> B4[数据路由中心]
B4 --> B5[任务调度中心]
end
subgraph 车机端组件
C1[分布式导航订阅器] --> C2[导航数据处理器]
C2 --> C3[地图显示服务]
C3 --> C4[HUD投影服务]
C2 --> C5[导航控制服务]
C5 --> C6[车辆控制接口]
C7[情景感知引擎] --> C2
C8[本地导航存储] --> C2
end
B --> D[安全与权限管理]
D --> E[数据加密传输]
E --> F[隐私保护机制]
2.3 关键技术特性
-
无缝迁移:基于分布式数据管理,实现导航数据的实时同步和任务迁移 -
智能接续:结合位置服务和情景感知,自动判断导航接续时机 -
多模态交互:支持语音、触控、手势等多种交互方式在车机端延续 -
安全保障:端到端加密传输,确保导航数据隐私和安全 -
容错机制:网络中断、设备离线等情况下的降级处理和数据恢复 -
个性化适配:根据车机屏幕尺寸、HUD能力等硬件特性优化显示
3. 应用使用场景
3.1 典型应用场景分类
|
|
|
|
|
|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3.2 场景复杂度分析
-
简单场景:单目的地导航,手机与车机直连 -
中级场景:多途经点路线,支持实时路况更新 -
复杂场景:跨城市长途导航,离线地图支持,多设备协同 -
企业级场景:车队管理,行程审批,数据分析
4. 核心原理与流程图
4.1 导航接力系统架构图
graph TD
subgraph 手机端(HarmonyOS Phone)
A[导航应用/地图APP] --> B[导航接力管理器]
B --> C[目的地管理器]
C --> D[路线规划引擎]
D --> E[分布式数据发布者]
F[位置服务] --> B
G[用户设置] --> B
end
subgraph 分布式中间件
H[分布式软总线] --> I[设备发现服务]
I --> J[安全认证模块]
J --> K[数据路由中心]
K --> L[任务调度中心]
M[超级终端] --> I
end
subgraph 车机端(HarmonyOS Car)
N[分布式数据订阅者] --> O[导航数据处理器]
O --> P[地图渲染引擎]
P --> Q[导航显示UI]
O --> R[HUD投影控制器]
O --> S[语音导航服务]
T[车辆状态监控] --> O
U[情景感知引擎] --> O
V[本地缓存管理] --> O
end
E --> K
K --> N
T --> W[导航接续决策]
W --> X[自动/手动接续]
4.2 导航接力工作流程
sequenceDiagram
participant User as 用户
participant Phone as 手机端
participant DistributedBus as 分布式软总线
participant Car as 车机端
User->>Phone: 设置导航目的地(公司)
Phone->>Phone: 规划最优路线
Phone->>Phone: 封装导航数据(目的地+路线)
alt 检测到车机连接
Phone->>DistributedBus: 发布导航数据(加密)
DistributedBus->>Car: 路由导航数据
Car->>Car: 解密并验证数据
Car->>Car: 情景感知判断(是否接续)
alt 允许接续
Car->>Car: 加载地图和路线
Car->>Car: 启动导航界面
Car->>Car: HUD投影路线(如有)
Car->>Phone: 确认接续成功
Note over Phone,Car: 导航任务已迁移<br/>手机可退出导航
else 不允许接续
Car->>Car: 仅存储数据,等待用户确认
Car->>User: 提示"检测到导航任务,是否接续?"
end
else 未检测到车机
Phone->>Phone: 本地保存导航任务
Note over Phone: 等待车机连接后自动同步
end
User->>Car: 开始驾驶
Car->>Car: 实时导航引导
Car->>Car: 上报位置和状态(可选)
4.3 工作原理详解
-
导航设置阶段:用户在手机导航应用中设置目的地,系统完成地址解析、POI搜索、路线规划等操作,生成完整的导航数据。 -
数据封装阶段:将目的地信息(坐标、地址、POI详情)、路线数据(路径点、转向指令、预计时间)、用户偏好(避开高速、避免收费)等封装为标准化的导航数据包。 -
设备发现阶段:通过分布式软总线和超级终端能力,手机自动发现附近可用的车机设备,进行设备认证和连接建立。 -
数据传输阶段:采用加密传输将导航数据包从手机同步到车机,支持断点续传和完整性校验,确保大数据量路线的可靠传输。 -
接续决策阶段:车机端结合车辆状态(是否点火、是否在行驶中)、用户设置(自动/手动接续)、环境条件(网络状况)等因素,决定导航接续的时机和方式。 -
导航启动阶段:车机加载地图数据,渲染导航界面,启动语音引导,并根据硬件能力(如HUD、仪表盘)优化显示效果。 -
状态同步阶段:导航过程中,车机可向手机同步位置、ETA等状态信息,支持双向控制(如在车机上修改目的地,手机端同步更新)。
5. 环境准备
5.1 开发环境配置
# 安装DevEco Studio最新版
# 下载地址:https://developer.harmonyos.com/cn/develop/deveco-studio
# 创建鸿蒙车机应用项目
# 1. 打开DevEco Studio -> Create Project
# 2. 选择"Automotive" -> "Navigation Application"
# 3. 配置项目信息:
# - Project name: CarNavigationRelay
# - Bundle name: com.example.carnavigationrelay
# - Save location: 选择合适路径
# - Compile SDK: API 9+
# - Device type: Automotive
# - Language: ArkTS
# 同时创建配套的手机端项目
# 1. 新建项目 -> "Phone" -> "Empty Ability"
# - Project name: PhoneNavigationApp
# - Bundle name: com.example.phonenavigationapp
# - 其他配置类似
# 目录结构规划
CarNavigationRelay/ # 车机端项目
├── entry/
│ ├── src/
│ │ ├── main/
│ │ │ ├── ets/ # ArkTS源代码
│ │ │ │ ├── pages/ # 页面组件
│ │ │ │ │ ├── NavigationPage.ets # 导航主页面
│ │ │ │ │ ├── DestinationPage.ets # 目的地设置页面
│ │ │ │ │ └── SettingsPage.ets # 设置页面
│ │ │ │ ├── model/ # 数据模型
│ │ │ │ │ ├── NavigationModel.ets
│ │ │ │ │ ├── VehicleModel.ets
│ │ │ │ │ └── DeviceManager.ets
│ │ │ │ ├── service/ # 业务逻辑
│ │ │ │ │ ├── NavigationRelayService.ets
│ │ │ │ │ ├── DistributedSyncService.ets
│ │ │ │ │ ├── MapDisplayService.ets
│ │ │ │ │ ├── HUDService.ets
│ │ │ │ │ └── VehicleInterfaceService.ets
│ │ │ │ ├── utils/ # 工具类
│ │ │ │ │ ├── Logger.ets
│ │ │ │ │ ├── LocationUtil.ets
│ │ │ │ │ ├── RouteCalculator.ets
│ │ │ │ │ └── PermissionUtil.ets
│ │ │ │ └── Application.ets # 应用入口
│ │ │ ├── resources/ # 资源文件
│ │ │ │ ├── base/
│ │ │ │ │ ├── element/ # 颜色、字符串、样式
│ │ │ │ │ ├── media/ # 图片、图标、音效
│ │ │ │ │ ├── profile/ # 配置文件
│ │ │ │ │ └── rawfile/ # 地图数据、语音包
│ │ │ └── module.json5 # 模块配置
│ ├── build-profile.json5 # 构建配置
│ └──hvigorfile.ts # 构建脚本
PhoneNavigationApp/ # 手机端项目
├── entry/
│ ├── src/
│ │ ├── main/
│ │ │ ├── ets/
│ │ │ │ ├── pages/
│ │ │ │ │ ├── HomePage.ets # 主页
│ │ │ │ │ ├── SearchPage.ets # 搜索页面
│ │ │ │ │ └── NavigationPage.ets # 导航页面
│ │ │ │ ├── model/
│ │ │ │ │ ├── DestinationModel.ets
│ │ │ │ │ └── NavigationModel.ets
│ │ │ │ ├── service/
│ │ │ │ │ ├── NavigationRelayService.ets
│ │ │ │ │ ├── DistributedSyncService.ets
│ │ │ │ │ └── MapSearchService.ets
│ │ │ │ ├── utils/
│ │ │ │ │ ├── Logger.ets
│ │ │ │ │ └── PermissionUtil.ets
│ │ │ │ └── Application.ets
│ │ │ ├── resources/
│ │ │ │ ├── base/
│ │ │ │ │ ├── element/
│ │ │ │ │ ├── media/
│ │ │ │ │ └── profile/
│ │ │ └── module.json5
│ ├── build-profile.json5
│ └──hvigorfile.ts
5.2 权限配置
{
"module": {
"name": "entry",
"type": "entry",
"description": "$string:module_desc",
"mainElement": "EntryAbility",
"deviceTypes": ["automotive"],
"deliveryWithInstall": true,
"installationFree": false,
"pages": "$profile:main_pages",
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/application/Application.ets",
"description": "$string:EntryAbility_desc",
"icon": "$media:icon",
"label": "$string:EntryAbility_label",
"startWindowIcon": "$media:icon",
"startWindowBackground": "$color:start_window_background",
"exported": true,
"skills": [
{
"entities": ["entity.system.home"],
"actions": ["action.system.home"]
}
]
},
{
"name": "NavigationAbility",
"srcEntry": "./ets/application/NavigationAbility.ets",
"description": "导航能力",
"icon": "$media:navigation_icon",
"label": "$string:NavigationAbility_label",
"exported": true,
"backgroundModes": ["location", "audioPlayback"]
}
],
"requestPermissions": [
{
"name": "ohos.permission.DISTRIBUTED_DATASYNC",
"reason": "$string:distributed_datasync_reason",
"usedScene": {
"abilities": ["EntryAbility", "NavigationAbility"],
"when": "always"
}
},
{
"name": "ohos.permission.LOCATION",
"reason": "$string:location_reason",
"usedScene": {
"abilities": ["NavigationAbility"],
"when": "always"
}
},
{
"name": "ohos.permission.VEHICLE_INFO",
"reason": "$string:vehicle_info_reason",
"usedScene": {
"abilities": ["NavigationAbility"],
"when": "always"
}
},
{
"name": "ohos.permission.MEDIA_LOCATION",
"reason": "$string:media_location_reason",
"usedScene": {
"abilities": ["NavigationAbility"],
"when": "inuse"
}
},
{
"name": "ohos.permission.CAMERA",
"reason": "$string:camera_reason",
"usedScene": {
"abilities": ["NavigationAbility"],
"when": "inuse"
}
},
{
"name": "ohos.permission.MICROPHONE",
"reason": "$string:microphone_reason",
"usedScene": {
"abilities": ["NavigationAbility"],
"when": "inuse"
}
},
{
"name": "ohos.permission.READ_MEDIA",
"reason": "$string:read_media_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
},
{
"name": "ohos.permission.WRITE_MEDIA",
"reason": "$string:write_media_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
}
],
"extensionAbilities": [
{
"name": "NavigationRelayExtAbility",
"type": "service",
"srcEntry": "./ets/service/NavigationRelayService.ets",
"description": "导航接力后台服务",
"exported": true,
"backgroundModes": ["dataTransfer", "location"]
}
],
"definePermissions": [
{
"name": "com.example.carnavigationrelay.permission.NAVIGATION_CONTROL",
"grantMode": "system_grant",
"availableLevel": "system_core",
"description": "导航控制权限"
}
]
}
}
{
"module": {
"name": "entry",
"type": "entry",
"description": "$string:module_desc",
"mainElement": "EntryAbility",
"deviceTypes": ["phone"],
"deliveryWithInstall": true,
"installationFree": false,
"pages": "$profile:main_pages",
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/application/Application.ets",
"description": "$string:EntryAbility_desc",
"icon": "$media:icon",
"label": "$string:EntryAbility_label",
"startWindowIcon": "$media:icon",
"startWindowBackground": "$color:start_window_background",
"exported": true,
"skills": [
{
"entities": ["entity.system.home"],
"actions": ["action.system.home"]
}
]
},
{
"name": "NavigationAbility",
"srcEntry": "./ets/application/NavigationAbility.ets",
"description": "手机导航能力",
"icon": "$media:navigation_icon",
"label": "$string:NavigationAbility_label",
"exported": true,
"backgroundModes": ["location", "audioPlayback"]
}
],
"requestPermissions": [
{
"name": "ohos.permission.DISTRIBUTED_DATASYNC",
"reason": "$string:distributed_datasync_reason",
"usedScene": {
"abilities": ["EntryAbility", "NavigationAbility"],
"when": "always"
}
},
{
"name": "ohos.permission.LOCATION",
"reason": "$string:location_reason",
"usedScene": {
"abilities": ["NavigationAbility"],
"when": "always"
}
},
{
"name": "ohos.permission.INTERNET",
"reason": "$string:internet_reason",
"usedScene": {
"abilities": ["NavigationAbility"],
"when": "inuse"
}
},
{
"name": "ohos.permission.ACCESS_NETWORK_STATE",
"reason": "$string:access_network_state_reason",
"usedScene": {
"abilities": ["NavigationAbility"],
"when": "always"
}
},
{
"name": "ohos.permission.WRITE_EXTERNAL_STORAGE",
"reason": "$string:write_external_storage_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
},
{
"name": "ohos.permission.READ_EXTERNAL_STORAGE",
"reason": "$string:read_external_storage_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
}
],
"extensionAbilities": [
{
"name": "NavigationRelayExtAbility",
"type": "service",
"srcEntry": "./ets/service/NavigationRelayService.ets",
"description": "手机导航接力后台服务",
"exported": true,
"backgroundModes": ["dataTransfer", "location"]
}
]
}
}
5.3 依赖配置
{
"apiType": "stageMode",
"buildOption": {
"strictMode": {
"caseSensitiveCheck": true,
"useNormalizedOHMUrl": true
},
"arkOptions": {
"debug": false,
"optimize": true
}
},
"buildOptionSet": [
{
"name": "release",
"arkOptions": {
"debug": false,
"optimize": true
}
}
],
"targets": [
{
"name": "default",
"applyToProducts": ["default"]
}
],
"products": [
{
"name": "default",
"compatibleSdkVersion": "9",
"runtimeOS": "HarmonyOS",
"signingConfig": "default"
}
],
"dependencies": {
"@ohos/distributedHardware.deviceManager": "9.0.0",
"@ohos/data.distributedData": "9.0.0",
"@ohos/location": "9.0.0",
"@ohos/multimodalinput": "9.0.0",
"@ohos.vehicle": "9.0.0"
}
}
6. 详细代码实现
6.1 数据模型定义
/**
* 导航数据模型定义
*/
/**
* 位置坐标
*/
export interface LocationCoordinate {
latitude: number; // 纬度
longitude: number; // 经度
altitude?: number; // 海拔高度(可选)
accuracy?: number; // 精度(米)
timestamp: number; // 时间戳
}
/**
* POI信息
*/
export interface POIInfo {
id: string; // POI唯一标识
name: string; // POI名称
address: string; // 详细地址
coordinate: LocationCoordinate; // 坐标
category: POICategory; // POI类别
phone?: string; // 联系电话(可选)
rating?: number; // 评分(可选)
tags?: string[]; // 标签(可选)
}
/**
* POI类别枚举
*/
export enum POICategory {
RESTAURANT = "restaurant", // 餐厅
HOTEL = "hotel", // 酒店
GAS_STATION = "gas_station", // 加油站
PARKING = "parking", // 停车场
SHOPPING = "shopping", // 购物中心
HOSPITAL = "hospital", // 医院
BANK = "bank", // 银行
OFFICE = "office", // 办公楼
HOME = "home", // 家
COMPANY = "company", // 公司
SCENIC_SPOT = "scenic_spot", // 景点
CUSTOM = "custom" // 自定义
}
/**
* 导航路段
*/
export interface RouteSegment {
segmentId: string; // 路段ID
instruction: string; // 导航指令
distance: number; // 路段距离(米)
duration: number; // 预计时间(秒)
roadName: string; // 道路名称
maneuver: ManeuverType; // 转向类型
coordinates: LocationCoordinate[]; // 路段坐标点
}
/**
* 转向类型枚举
*/
export enum ManeuverType {
STRAIGHT = "straight", // 直行
TURN_LEFT = "turn_left", // 左转
TURN_RIGHT = "turn_right", // 右转
UTURN = "uturn", // 掉头
MERGE = "merge", // 合并车道
EXIT_LEFT = "exit_left", // 左侧出口
EXIT_RIGHT = "exit_right", // 右侧出口
ROUNDABOUT_ENTER = "roundabout_enter", // 进入环岛
ROUNDABOUT_EXIT = "roundabout_exit", // 离开环岛
DESTINATION = "destination" // 到达目的地
}
/**
* 完整导航路线
*/
export interface NavigationRoute {
routeId: string; // 路线唯一标识
origin: LocationCoordinate; // 起点坐标
destination: POIInfo; // 目的地POI信息
waypoints: POIInfo[]; // 途经点(可选)
segments: RouteSegment[]; // 导航路段
totalDistance: number; // 总距离(米)
totalDuration: number; // 总时间(秒)
trafficCondition: TrafficCondition; // 路况信息
alternativeRoutes?: NavigationRoute[]; // 备选路线(可选)
routePreference: RoutePreference; // 路线偏好设置
}
/**
* 路况信息
*/
export enum TrafficCondition {
UNKNOWN = "unknown", // 未知
SMOOTH = "smooth", // 畅通
SLOW = "slow", // 缓行
CONGESTED = "congested", // 拥堵
SEVERE_CONGESTION = "severe_congestion" // 严重拥堵
}
/**
* 路线偏好设置
*/
export interface RoutePreference {
avoidHighways: boolean; // 避开高速公路
avoidTolls: boolean; // 避开收费路段
avoidFerries: boolean; // 避开轮渡
vehicleType: VehicleType; // 车辆类型
departureTime?: number; // 出发时间(时间戳,可选)
}
/**
* 车辆类型枚举
*/
export enum VehicleType {
CAR = "car", // 小汽车
TRUCK = "truck", // 卡车
BUS = "bus", // 公交车
MOTORCYCLE = "motorcycle" // 摩托车
}
/**
* 导航任务
*/
export interface NavigationTask {
taskId: string; // 任务唯一标识
route: NavigationRoute; // 导航路线
createdTime: number; // 创建时间
lastUpdatedTime: number; // 最后更新时间
status: NavigationStatus; // 任务状态
sourceDeviceId: string; // 来源设备ID
targetDeviceId?: string; // 目标设备ID(可选)
isContinuing: boolean; // 是否为接续任务
userSettings: NavigationSettings; // 用户设置
}
/**
* 导航状态枚举
*/
export enum NavigationStatus {
CREATED = "created", // 已创建
TRANSFERRING = "transferring", // 传输中
READY = "ready", // 准备就绪
ACTIVE = "active", // 导航中
PAUSED = "paused", // 暂停
COMPLETED = "completed", // 已完成
CANCELLED = "cancelled", // 已取消
FAILED = "failed" // 失败
}
/**
* 导航设置
*/
export interface NavigationSettings {
voiceGuidance: boolean; // 语音引导
voiceVolume: number; // 语音音量(0-100)
displayMode: DisplayMode; // 显示模式
hudEnabled: boolean; // HUD投影启用
nightMode: boolean; // 夜间模式
speedWarning: boolean; // 超速提醒
speedLimit: number; // 限速值(km/h)
}
/**
* 显示模式枚举
*/
export enum DisplayMode {
MAP_FULLSCREEN = "map_fullscreen", // 全屏地图
SPLIT_VIEW = "split_view", // 分屏视图
MINIMAL = "minimal" // 简洁模式
}
/**
* 导航事件
*/
export interface NavigationEvent {
eventId: string; // 事件ID
taskId: string; // 关联的任务ID
eventType: NavigationEventType; // 事件类型
timestamp: number; // 时间戳
data: any; // 事件数据
deviceId: string; // 产生事件的设备ID
}
/**
* 导航事件类型枚举
*/
export enum NavigationEventType {
TASK_CREATED = "task_created", // 任务创建
TASK_TRANSFERRED = "task_transferred", // 任务传输
NAVIGATION_STARTED = "navigation_started", // 导航开始
NAVIGATION_PAUSED = "navigation_paused", // 导航暂停
NAVIGATION_RESUMED = "navigation_resumed", // 导航恢复
LOCATION_UPDATED = "location_updated", // 位置更新
ROUTE_DEVIATED = "route_deviated", // 偏离路线
DESTINATION_REACHED = "destination_reached", // 到达目的地
TASK_COMPLETED = "task_completed", // 任务完成
TASK_CANCELLED = "task_cancelled", // 任务取消
ERROR_OCCURRED = "error_occurred" // 错误发生
}
/**
* 设备信息
*/
export interface DeviceInfo {
deviceId: string; // 设备ID
deviceName: string; // 设备名称
deviceType: DeviceType; // 设备类型
isConnected: boolean; // 是否已连接
capabilities: DeviceCapabilities; // 设备能力
lastActiveTime: number; // 最后活跃时间
}
/**
* 设备类型枚举
*/
export enum DeviceType {
PHONE = "phone", // 手机
CAR = "car", // 车机
TABLET = "tablet", // 平板
WATCH = "watch", // 手表
TV = "tv" // 智慧屏
}
/**
* 设备能力
*/
export interface DeviceCapabilities {
supportsNavigation: boolean; // 支持导航
supportsHUD: boolean; // 支持HUD
screenSize: { width: number; height: number }; // 屏幕尺寸
hasVoiceAssistant: boolean; // 有语音助手
hasGPS: boolean; // 有GPS模块
networkType: NetworkType; // 网络类型
}
/**
* 网络类型枚举
*/
export enum NetworkType {
WIFI = "wifi",
CELLULAR_4G = "cellular_4g",
CELLULAR_5G = "cellular_5g",
OFFLINE = "offline"
}
6.2 工具类实现
/**
* 日志工具类
*/
export class Logger {
private static readonly TAG: string = 'CarNavigationRelay';
private static readonly IS_DEBUG: boolean = true; // 发布版本设为false
/**
* 调试日志
*/
static d(message: string, tag: string = Logger.TAG): void {
if (Logger.IS_DEBUG) {
console.debug(`[${tag}] ${message}`);
}
}
/**
* 信息日志
*/
static i(message: string, tag: string = Logger.TAG): void {
console.info(`[${tag}] ${message}`);
}
/**
* 警告日志
*/
static w(message: string, tag: string = Logger.TAG): void {
console.warn(`[${tag}] ${message}`);
}
/**
* 错误日志
*/
static e(message: string, tag: string = Logger.TAG, error?: Error): void {
let logMessage = `[${tag}] ${message}`;
if (error) {
logMessage += `, Error: ${error.message}, Stack: ${error.stack}`;
}
console.error(logMessage);
}
/**
* 关键日志
*/
static wtf(message: string, tag: string = Logger.TAG): void {
console.error(`[${tag}] WTF: ${message}`);
}
/**
* 性能日志记录
*/
static timeStart(label: string): void {
if (Logger.IS_DEBUG) {
console.time(`[${Logger.TAG}] ${label}`);
}
}
/**
* 性能日志结束
*/
static timeEnd(label: string): void {
if (Logger.IS_DEBUG) {
console.timeEnd(`[${Logger.TAG}] ${label}`);
}
}
/**
* 导航专用日志
*/
static navigation(message: string, routeId?: string): void {
const routeInfo = routeId ? `[Route:${routeId}]` : '';
Logger.i(`导航: ${routeInfo} ${message}`, 'Navigation');
}
/**
* 分布式同步日志
*/
static distributed(message: string, deviceId?: string): void {
const deviceInfo = deviceId ? `[Device:${deviceId}]` : '';
Logger.i(`分布式: ${deviceInfo} ${message}`, 'Distributed');
}
}
import location from '@ohos.location';
import { LocationCoordinate } from '../model/NavigationModel';
import Logger from './Logger';
/**
* 位置工具类
*/
export class LocationUtil {
/**
* 获取当前位置
*/
static async getCurrentLocation(): Promise<LocationCoordinate | null> {
try {
Logger.d('获取当前位置', 'LocationUtil');
// 检查定位权限
const hasPermission = await LocationUtil.checkLocationPermission();
if (!hasPermission) {
Logger.e('无定位权限', 'LocationUtil');
return null;
}
// 获取位置管理器
const locationManager = location.getLocationManager();
// 创建位置请求
const request: location.LocationRequest = {
'scenario': location.Scenario.NAVIGATION,
'timeInterval': 1000, // 1秒更新一次
'distanceInterval': 5, // 5米更新一次
'maxAccuracy': 10 // 最大精度10米
};
// 获取位置信息
const locationInfo = await locationManager.getSingleLocation(request);
if (locationInfo) {
const coordinate: LocationCoordinate = {
latitude: locationInfo.latitude,
longitude: locationInfo.longitude,
altitude: locationInfo.altitude,
accuracy: locationInfo.accuracy,
timestamp: locationInfo.timestamp
};
Logger.i(`获取位置成功: ${coordinate.latitude}, ${coordinate.longitude}`, 'LocationUtil');
return coordinate;
}
Logger.w('未能获取位置信息', 'LocationUtil');
return null;
} catch (error) {
Logger.e('获取当前位置失败', 'LocationUtil', error as Error);
return null;
}
}
/**
* 持续监听位置变化
*/
static startLocationUpdates(callback: (location: LocationCoordinate) => void): void {
try {
const locationManager = location.getLocationManager();
const request: location.LocationRequest = {
'scenario': location.Scenario.NAVIGATION,
'timeInterval': 1000,
'distanceInterval': 5,
'maxAccuracy': 10
};
// 注册位置变化监听
locationManager.on('locationChange', (locationInfo: location.Location) => {
const coordinate: LocationCoordinate = {
latitude: locationInfo.latitude,
longitude: locationInfo.longitude,
altitude: locationInfo.altitude,
accuracy: locationInfo.accuracy,
timestamp: locationInfo.timestamp
};
callback(coordinate);
});
// 开始位置更新
locationManager.startLocationUpdate(request);
Logger.i('开始监听位置变化', 'LocationUtil');
} catch (error) {
Logger.e('开始位置更新失败', 'LocationUtil', error as Error);
}
}
/**
* 停止位置更新
*/
static stopLocationUpdates(): void {
try {
const locationManager = location.getLocationManager();
locationManager.off('locationChange');
locationManager.stopLocationUpdate();
Logger.i('停止位置更新', 'LocationUtil');
} catch (error) {
Logger.e('停止位置更新失败', 'LocationUtil', error as Error);
}
}
/**
* 计算两个坐标点之间的距离(米)
*/
static calculateDistance(point1: LocationCoordinate, point2: LocationCoordinate): number {
const R = 6371000; // 地球半径(米)
const lat1Rad = LocationUtil.degreesToRadians(point1.latitude);
const lat2Rad = LocationUtil.degreesToRadians(point2.latitude);
const deltaLatRad = LocationUtil.degreesToRadians(point2.latitude - point1.latitude);
const deltaLonRad = LocationUtil.degreesToRadians(point2.longitude - point1.longitude);
const a = Math.sin(deltaLatRad / 2) * Math.sin(deltaLatRad / 2) +
Math.cos(lat1Rad) * Math.cos(lat2Rad) *
Math.sin(deltaLonRad / 2) * Math.sin(deltaLonRad / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return R * c;
}
/**
* 计算方位角(度)
*/
static calculateBearing(from: LocationCoordinate, to: LocationCoordinate): number {
const lat1Rad = LocationUtil.degreesToRadians(from.latitude);
const lat2Rad = LocationUtil.degreesToRadians(to.latitude);
const deltaLonRad = LocationUtil.degreesToRadians(to.longitude - from.longitude);
const y = Math.sin(deltaLonRad) * Math.cos(lat2Rad);
const x = Math.cos(lat1Rad) * Math.sin(lat2Rad) -
Math.sin(lat1Rad) * Math.cos(lat2Rad) * Math.cos(deltaLonRad);
let bearing = Math.atan2(y, x);
bearing = LocationUtil.radiansToDegrees(bearing);
return (bearing + 360) % 360;
}
/**
* 检查是否偏离路线
*/
static isOffRoute(currentLocation: LocationCoordinate, route: import('../model/NavigationModel').NavigationRoute, threshold: number = 50): boolean {
if (!route.segments || route.segments.length === 0) {
return false;
}
// 找到最近的路段
let minDistance = Number.MAX_VALUE;
let closestSegment: import('../model/NavigationModel').RouteSegment | null = null;
for (const segment of route.segments) {
for (const coord of segment.coordinates) {
const distance = LocationUtil.calculateDistance(currentLocation, coord);
if (distance < minDistance) {
minDistance = distance;
closestSegment = segment;
}
}
}
const isOffRoute = minDistance > threshold;
if (isOffRoute) {
Logger.w(`偏离路线: 距离最近路段${minDistance.toFixed(2)}米`, 'LocationUtil');
}
return isOffRoute;
}
/**
* 获取地址信息(逆地理编码)
*/
static async getAddressFromCoordinate(coordinate: LocationCoordinate): Promise<string | null> {
try {
// 在实际实现中,应该调用地图服务的逆地理编码API
// 这里简化处理,返回模拟地址
const address = `纬度:${coordinate.latitude.toFixed(6)}, 经度:${coordinate.longitude.toFixed(6)}`;
Logger.d(`获取地址: ${address}`, 'LocationUtil');
return address;
} catch (error) {
Logger.e('获取地址失败', 'LocationUtil', error as Error);
return null;
}
}
/**
* 检查定位权限
*/
private static async checkLocationPermission(): Promise<boolean> {
// 在实际实现中,应该检查ohos.permission.LOCATION权限
// 这里简化处理,返回true
return true;
}
/**
* 角度转弧度
*/
private static degreesToRadians(degrees: number): number {
return degrees * (Math.PI / 180);
}
/**
* 弧度转角度
*/
private static radiansToDegrees(radians: number): number {
return radians * (180 / Math.PI);
}
}
import { NavigationRoute, RouteSegment, LocationCoordinate, ManeuverType, POIInfo } from '../model/NavigationModel';
import Logger from './Logger';
import LocationUtil from './LocationUtil';
/**
* 路线计算器
*/
export class RouteCalculator {
/**
* 简化版路线计算(实际应用中应该接入专业地图服务)
*/
static async calculateRoute(
origin: LocationCoordinate,
destination: POIInfo,
waypoints: POIInfo[] = [],
preference: import('../model/NavigationModel').RoutePreference
): Promise<NavigationRoute | null> {
try {
Logger.timeStart('calculate_route');
Logger.navigation(`开始计算路线: ${origin.latitude},${origin.longitude} -> ${destination.name}`, 'calculation');
// 生成路线ID
const routeId = `route_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
// 简化的路线生成逻辑(实际应用中应该调用地图API)
const segments: RouteSegment[] = await RouteCalculator.generateSimpleRoute(origin, destination, preference);
// 计算总距离和时间
let totalDistance = 0;
let totalDuration = 0;
segments.forEach(segment => {
totalDistance += segment.distance;
totalDuration += segment.duration;
});
const route: NavigationRoute = {
routeId: routeId,
origin: origin,
destination: destination,
waypoints: waypoints,
segments: segments,
totalDistance: totalDistance,
totalDuration: totalDuration,
trafficCondition: TrafficCondition.SMOOTH, // 简化处理
routePreference: preference
};
Logger.timeEnd('calculate_route');
Logger.navigation(`路线计算完成: 距离=${totalDistance}m, 时间=${totalDuration}s`, routeId);
return route;
} catch (error) {
Logger.e('路线计算失败', 'RouteCalculator', error as Error);
return null;
}
}
/**
* 生成简化的路线(演示用)
*/
private static async generateSimpleRoute(
origin: LocationCoordinate,
destination: POIInfo,
preference: import('../model/NavigationModel').RoutePreference
): Promise<RouteSegment[]> {
const segments: RouteSegment[] = [];
// 计算直线距离
const directDistance = LocationUtil.calculateDistance(origin, destination.coordinate);
// 根据距离生成若干路段
const segmentCount = Math.max(3, Math.ceil(directDistance / 1000)); // 每公里至少一个路段
const segmentDistance = directDistance / segmentCount;
let currentCoord = { ...origin };
for (let i = 0; i < segmentCount; i++) {
// 计算下一段终点(简单的直线插值)
const progress = (i + 1) / segmentCount;
const nextCoord: LocationCoordinate = {
latitude: origin.latitude + (destination.coordinate.latitude - origin.latitude) * progress,
longitude: origin.longitude + (destination.coordinate.longitude - origin.longitude) * progress,
timestamp: Date.now()
};
// 随机生成导航指令
const maneuvers = [ManeuverType.STRAIGHT, ManeuverType.TURN_LEFT, ManeuverType.TURN_RIGHT];
const maneuver = i === segmentCount - 1 ? ManeuverType.DESTINATION :
maneuvers[Math.floor(Math.random() * maneuvers.length)];
// 生成路段
const segment: RouteSegment = {
segmentId: `segment_${Date.now()}_${i}`,
instruction: RouteCalculator.generateInstruction(maneuver, i === segmentCount - 1 ? destination.name : ''),
distance: Math.round(segmentDistance),
duration: Math.round(segmentDistance / 13.89), // 假设平均速度50km/h
roadName: `道路${i + 1}`,
maneuver: maneuver,
coordinates: [currentCoord, nextCoord]
};
segments.push(segment);
currentCoord = nextCoord;
}
return segments;
}
/**
* 生成导航指令文本
*/
private static generateInstruction(maneuver: ManeuverType, destinationName: string): string {
switch (maneuver) {
case ManeuverType.STRAIGHT:
return '直行';
case ManeuverType.TURN_LEFT:
return '左转';
case ManeuverType.TURN_RIGHT:
return '右转';
case ManeuverType.UTURN:
return '掉头';
case ManeuverType.MERGE:
return '合并车道';
case ManeuverType.EXIT_LEFT:
return '从左侧出口驶出';
case ManeuverType.EXIT_RIGHT:
return '从右侧出口驶出';
case ManeuverType.ROUNDABOUT_ENTER:
return '进入环岛';
case ManeuverType.ROUNDABOUT_EXIT:
return '离开环岛';
case ManeuverType.DESTINATION:
return `到达目的地: ${destinationName}`;
default:
return '继续前行';
}
}
/**
* 重新计算路线(考虑实时路况)
*/
static async recalculateRoute(
currentRoute: NavigationRoute,
currentLocation: LocationCoordinate
): Promise<NavigationRoute | null> {
try {
Logger.navigation(`重新计算路线: 当前位置偏离,RouteId=${currentRoute.routeId}`, currentRoute.routeId);
// 找到当前所在的路段
let currentSegmentIndex = -1;
let minDistance = Number.MAX_VALUE;
currentRoute.segments.forEach((segment, index) => {
segment.coordinates.forEach(coord => {
const distance = LocationUtil.calculateDistance(currentLocation, coord);
if (distance < minDistance) {
minDistance = distance;
currentSegmentIndex = index;
}
});
});
if (currentSegmentIndex === -1) {
Logger.e('无法确定当前所在路段', 'RouteCalculator');
return null;
}
// 从当前位置开始重新规划到目的地的路线
const remainingSegments = currentRoute.segments.slice(currentSegmentIndex);
const newOrigin = currentLocation;
// 这里简化处理,实际应该调用地图API进行增量重算
const newRoute = await RouteCalculator.calculateRoute(
newOrigin,
currentRoute.destination,
currentRoute.waypoints,
currentRoute.routePreference
);
if (newRoute) {
Logger.navigation(`路线重新计算完成: 新距离=${newRoute.totalDistance}m`, newRoute.routeId);
}
return newRoute;
} catch (error) {
Logger.e('重新计算路线失败', 'RouteCalculator', error as Error);
return null;
}
}
/**
* 计算备选路线
*/
static async calculateAlternativeRoutes(
origin: LocationCoordinate,
destination: POIInfo,
preference: import('../model/NavigationModel').RoutePreference,
count: number = 2
): Promise<NavigationRoute[]> {
try {
Logger.navigation(`计算备选路线: 数量=${count}`, 'alternatives');
const alternatives: NavigationRoute[] = [];
for (let i = 0; i < count; i++) {
// 为每个备选路线添加一些随机变化
const modifiedPreference = { ...preference };
modifiedPreference.avoidHighways = i === 1; // 第二条路线避开高速
modifiedPreference.avoidTolls = i === 2; // 第三条路线避开收费
const route = await RouteCalculator.calculateRoute(origin, destination, [], modifiedPreference);
if (route) {
alternatives.push(route);
}
}
Logger.navigation(`备选路线计算完成: ${alternatives.length}条`, 'alternatives');
return alternatives;
} catch (error) {
Logger.e('计算备选路线失败', 'RouteCalculator', error as Error);
return [];
}
}
}
import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
import bundleManager from '@ohos.bundle.bundleManager';
import Logger from './Logger';
/**
* 权限工具类
*/
export class PermissionUtil {
/**
* 检查单个权限
*/
static async checkPermission(permission: string): Promise<boolean> {
try {
const atManager = abilityAccessCtrl.createAtManager();
const grantStatus = await atManager.checkAccessToken(
globalThis.abilityContext.tokenId,
permission
);
return grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;
} catch (error) {
Logger.e(`检查权限失败: ${permission}`, 'PermissionUtil', error as Error);
return false;
}
}
/**
* 请求单个权限
*/
static async requestPermission(permission: string): Promise<boolean> {
try {
const atManager = abilityAccessCtrl.createAtManager();
const result = await atManager.requestPermissionsFromUser(
globalThis.abilityContext,
[permission]
);
return result.authResults[0] === 0; // 0表示授权成功
} catch (error) {
Logger.e(`请求权限失败: ${permission}`, 'PermissionUtil', error as Error);
return false;
}
}
/**
* 检查并请求多个权限
*/
static async checkAndRequestPermissions(permissions: string[]): Promise<boolean> {
const results: boolean[] = [];
for (const permission of permissions) {
const hasPermission = await PermissionUtil.checkPermission(permission);
if (!hasPermission) {
Logger.i(`请求权限: ${permission}`, 'PermissionUtil');
const granted = await PermissionUtil.requestPermission(permission);
results.push(granted);
} else {
results.push(true);
}
}
return results.every(granted => granted);
}
/**
* 获取应用名称
*/
static async getAppName(packageName: string): Promise<string> {
try {
const bundleInfo = await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLENAME);
return bundleInfo.appInfo.label;
} catch (error) {
Logger.e(`获取应用名称失败: ${packageName}`, 'PermissionUtil', error as Error);
return packageName;
}
}
/**
* 检查位置权限(导航专用)
*/
static async checkLocationPermission(): Promise<boolean> {
const locationPermissions = [
'ohos.permission.LOCATION',
'ohos.permission.APPROXIMATELY_LOCATION'
];
return await PermissionUtil.checkAndRequestPermissions(locationPermissions);
}
/**
* 检查车辆信息权限
*/
static async checkVehiclePermission(): Promise<boolean> {
return await PermissionUtil.checkPermission('ohos.permission.VEHICLE_INFO');
}
/**
* 检查分布式数据同步权限
*/
static async checkDistributedSyncPermission(): Promise<boolean> {
return await PermissionUtil.checkPermission('ohos.permission.DISTRIBUTED_DATASYNC');
}
}
6.3 设备管理类
import distributedDeviceManager from '@ohos.distributedHardware.deviceManager';
import { DeviceInfo, DeviceType, DeviceCapabilities } from './NavigationModel';
import Logger from '../utils/Logger';
/**
* 设备管理器
*/
export class DeviceManager {
private static instance: DeviceManager;
private deviceManager: distributedDeviceManager.DeviceManager | null = null;
private connectedDevices: Map<string, DeviceInfo> = new Map();
private context: any; // 实际应用中应为AbilityContext
private isDiscovering: boolean = false;
private constructor(context: any) {
this.context = context;
this.initDeviceManager();
}
/**
* 获取单例实例
*/
static getInstance(context: any): DeviceManager {
if (!DeviceManager.instance) {
DeviceManager.instance = new DeviceManager(context);
}
return DeviceManager.instance;
}
/**
* 初始化设备管理器
*/
private async initDeviceManager(): Promise<void> {
try {
Logger.d('初始化设备管理器', 'DeviceManager');
// 获取设备管理器实例
this.deviceManager = distributedDeviceManager.createDeviceManager(this.context);
// 注册设备状态变化监听
this.registerDeviceStateListener();
// 发现周边设备
await this.startDeviceDiscovery();
Logger.i('设备管理器初始化成功', 'DeviceManager');
} catch (error) {
Logger.e('设备管理器初始化失败', 'DeviceManager', error as Error);
}
}
/**
* 注册设备状态监听
*/
private registerDeviceStateListener(): void {
if (!this.deviceManager) return;
// 设备上线监听
this.deviceManager.on('deviceOnline', (device: distributedDeviceManager.DeviceInfo) => {
Logger.i(`设备上线: ${device.deviceName}(${device.deviceId}), 类型: ${device.deviceTypeId}`, 'DeviceManager');
this.handleDeviceOnline(device);
});
// 设备离线监听
this.deviceManager.on('deviceOffline', (device: distributedDeviceManager.DeviceInfo) => {
Logger.i(`设备离线: ${device.deviceName}(${device.deviceId})`, 'DeviceManager');
this.handleDeviceOffline(device);
});
// 设备信息变更监听
this.deviceManager.on('deviceInfoChanged', (device: distributedDeviceManager.DeviceInfo) => {
Logger.d(`设备信息变更: ${device.deviceName}`, 'DeviceManager');
this.updateDeviceInfo(device);
});
// 分布式组网状态变更
this.deviceManager.on('groupStateChanged', (groupId: string, state: number) => {
Logger.i(`组网状态变更: Group=${groupId}, State=${state}`, 'DeviceManager');
this.handleGroupStateChanged(groupId, state);
});
}
/**
* 开始设备发现
*/
async startDeviceDiscovery(): Promise<void> {
if (this.isDiscovering || !this.deviceManager) {
return;
}
try {
Logger.d('开始设备发现', 'DeviceManager');
// 开始发现设备
await this.deviceManager.startDeviceDiscovery({
discoverTargetType: 1, // 发现所有类型的设备
strategy: 1 // 常规发现策略
});
this.isDiscovering = true;
// 获取已配对设备
const pairedDevices = this.deviceManager.getAvailableDeviceListSync();
Logger.i(`发现${pairedDevices.length}个已配对设备`, 'DeviceManager');
// 添加到连接设备列表
pairedDevices.forEach(device => {
this.addConnectedDevice(device);
});
} catch (error) {
Logger.e('开始设备发现失败', 'DeviceManager', error as Error);
}
}
/**
* 停止设备发现
*/
stopDeviceDiscovery(): void {
if (!this.isDiscovering || !this.deviceManager) {
return;
}
try {
this.deviceManager.stopDeviceDiscovery();
this.isDiscovering = false;
Logger.d('停止设备发现', 'DeviceManager');
} catch (error) {
Logger.e('停止设备发现失败', 'DeviceManager', error as Error);
}
}
/**
* 处理设备上线
*/
private handleDeviceOnline(device: distributedDeviceManager.DeviceInfo): void {
this.addConnectedDevice(device);
// 通知上层设备上线
this.notifyDeviceStatusChange(device.deviceId, true);
// 如果是手机设备,检查是否有待接续的导航任务
if (this.isPhoneDevice(device.deviceTypeId)) {
this.checkPendingNavigationTasks(device.deviceId);
}
}
/**
* 处理设备离线
*/
private handleDeviceOffline(device: distributedDeviceManager.DeviceInfo): void {
const existingDevice = this.connectedDevices.get(device.deviceId);
if (existingDevice) {
const updatedDevice: DeviceInfo = {
...existingDevice,
isConnected: false,
lastActiveTime: Date.now()
};
this.connectedDevices.set(device.deviceId, updatedDevice);
}
// 通知上层设备离线
this.notifyDeviceStatusChange(device.deviceId, false);
}
/**
* 更新设备信息
*/
private updateDeviceInfo(device: distributedDeviceManager.DeviceInfo): void {
const existingDevice = this.connectedDevices.get(device.deviceId);
if (existingDevice) {
const updatedDevice: DeviceInfo = {
...existingDevice,
deviceName: device.deviceName,
lastActiveTime: Date.now(),
// 更新设备能力信息
capabilities: this.getDeviceCapabilities(device)
};
this.connectedDevices.set(device.deviceId, updatedDevice);
}
}
/**
* 添加连接设备
*/
private addConnectedDevice(deviceInfo: distributedDeviceManager.DeviceInfo): void {
const deviceType = this.mapDeviceType(deviceInfo.deviceTypeId);
const device: DeviceInfo = {
deviceId: deviceInfo.deviceId,
deviceName: deviceInfo.deviceName,
deviceType: deviceType,
isConnected: true,
lastActiveTime: Date.now(),
capabilities: this.getDeviceCapabilities(deviceInfo)
};
this.connectedDevices.set(deviceInfo.deviceId, device);
Logger.d(`添加设备: ${device.deviceName}(${device.deviceType}), 能力: ${JSON.stringify(device.capabilities)}`, 'DeviceManager');
}
/**
* 映射设备类型
*/
private mapDeviceType(deviceTypeId: number): DeviceType {
// 根据实际设备类型ID映射
switch (deviceTypeId) {
case 102: return DeviceType.PHONE; // 手机
case 103: return DeviceType.TABLET; // 平板
case 106: return DeviceType.WATCH; // 手表
case 109: return DeviceType.CAR; // 车机
case 110: return DeviceType.TV; // 智慧屏
default: return DeviceType.PHONE;
}
}
/**
* 判断是否为手机设备
*/
private isPhoneDevice(deviceTypeId: number): boolean {
return deviceTypeId === 102; // 手机设备类型ID
}
/**
* 获取设备能力
*/
private getDeviceCapabilities(deviceInfo: distributedDeviceManager.DeviceInfo): DeviceCapabilities {
// 根据设备类型和系统信息判断设备能力
const deviceType = this.mapDeviceType(deviceInfo.deviceTypeId);
const baseCapabilities: DeviceCapabilities = {
supportsNavigation: deviceType === DeviceType.PHONE || deviceType === DeviceType.CAR,
supportsHUD: deviceType === DeviceType.CAR,
screenSize: { width: 1920, height: 1080 }, // 默认值,实际应从设备获取
hasVoiceAssistant: true,
hasGPS: deviceType === DeviceType.PHONE || deviceType === DeviceType.CAR,
networkType: NetworkType.WIFI // 简化处理
};
// 根据设备类型调整能力
switch (deviceType) {
case DeviceType.CAR:
baseCapabilities.supportsHUD = true;
baseCapabilities.screenSize = { width: 1280, height: 720 };
break;
case DeviceType.PHONE:
baseCapabilities.screenSize = { width: 1080, height: 2340 };
break;
case DeviceType.WATCH:
baseCapabilities.supportsNavigation = false;
baseCapabilities.supportsHUD = false;
baseCapabilities.screenSize = { width: 454, height: 454 };
break;
}
return baseCapabilities;
}
/**
* 处理组网状态变更
*/
private handleGroupStateChanged(groupId: string, state: number): void {
Logger.i(`组网状态变更: Group=${groupId}, State=${state}`, 'DeviceManager');
// 可以在这里处理超级终端组网相关的逻辑
}
/**
* 检查待处理的导航任务
*/
private checkPendingNavigationTasks(sourceDeviceId: string): void {
// 在实际实现中,这里应该检查是否有从手机端同步过来的待接续导航任务
Logger.d(`检查设备${sourceDeviceId}的待处理导航任务`, 'DeviceManager');
// 发送自定义事件通知导航服务
if (globalThis.navigationEventEmitter) {
globalThis.navigationEventEmitter.emit('checkPendingTasks', { sourceDeviceId });
}
}
/**
* 获取已连接的手机设备
*/
getConnectedPhones(): DeviceInfo[] {
const phones: DeviceInfo[] = [];
this.connectedDevices.forEach(device => {
if (device.deviceType === DeviceType.PHONE && device.isConnected) {
phones.push(device);
}
});
return phones;
}
/**
* 获取已连接的车机设备(主要用于手机端)
*/
getConnectedCars(): DeviceInfo[] {
const cars: DeviceInfo[] = [];
this.connectedDevices.forEach(device => {
if (device.deviceType === DeviceType.CAR && device.isConnected) {
cars.push(device);
}
});
return cars;
}
/**
* 获取设备信息
*/
getDeviceInfo(deviceId: string): DeviceInfo | undefined {
return this.connectedDevices.get(deviceId);
}
/**
* 获取所有已连接设备
*/
getAllConnectedDevices(): DeviceInfo[] {
const devices: DeviceInfo[] = [];
this.connectedDevices.forEach(device => {
if (device.isConnected) {
devices.push(device);
}
});
return devices;
}
/**
* 通知设备状态变化
*/
private notifyDeviceStatusChange(deviceId: string, isConnected: boolean): void {
Logger.d(`设备状态变化: ${deviceId} ${isConnected ? '在线' : '离线'}`, 'DeviceManager');
// 发送自定义事件通知其他模块
if (globalThis.deviceEventEmitter) {
globalThis.deviceEventEmitter.emit('deviceStatusChanged', {
deviceId,
isConnected,
deviceInfo: this.connectedDevices.get(deviceId)
});
}
}
/**
* 释放资源
*/
release(): void {
this.stopDeviceDiscovery();
this.connectedDevices.clear();
if (this.deviceManager) {
// 取消所有事件监听
this.deviceManager.off('deviceOnline');
this.deviceManager.off('deviceOffline');
this.deviceManager.off('deviceInfoChanged');
this.deviceManager.off('groupStateChanged');
this.deviceManager = null;
}
Logger.i('设备管理器资源已释放', 'DeviceManager');
}
}
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)