鸿蒙开发 车服务:想不想让你的应用和汽车互联

2 阅读9分钟

什么是车服务

你有没有想过,手机上的导航 App 怎么把路线信息传到车机屏幕上?或者怎么用手表控制车机播放音乐?车服务(Car Kit)就是来做这个的。

车服务是 HarmonyOS 提供的车联服务,面向华为 1+8 产品的应用开发者,提供便捷的接入出行服务能力。简单说,它就是手机和车机之间的"桥梁",让你的应用能把导航信息、出行数据传到车机上,也能监听车机的事件。

你可能会问:1+8 是什么?1 是手机,8 是平板、PC、手表、耳机、音箱、眼镜、车机、TV。车服务就是让手机和车机之间能互相通信。

核心功能

车服务提供两大类功能:

导航信息交互

  1. 注册监听:监听系统导航信息和指令。比如车机发来"开始导航"的指令,你的应用能收到
  2. 设置导航状态:设置导航类型、目的地、途经点等。告诉车机"我现在在导航,目的地是XXX"
  3. 设置导航数据:设置转向信息、道路名称、速度限制等。实时同步导航数据到车机

智慧出行业务

  1. 事件监听:监听出行业务事件(如换车事件)。用户换了一辆车,你的应用能知道
  2. 连接状态:监听智慧出行连接状态(如 HiCar 连接)。手机和车机连接或断开时,会通知你
  3. 事件查询:查询系统应用发送的事件详细信息

环境搭建

硬件要求

  • 设备类型:华为手机
  • HarmonyOS 系统:HarmonyOS 5.0.0 Release 及以上

软件要求

  • DevEco Studio 版本:DevEco Studio 5.0.0 Release 及以上
  • HarmonyOS SDK 版本:HarmonyOS 5.0.0 Release SDK 及以上

搭建步骤

  1. 安装 DevEco Studio:去华为开发者官网下载安装
  2. 配置开发环境:确保网络环境正常
  3. 设备调试:使用真机进行调试

权限配置

需要在 module.json5 中添加以下权限:

{
  "requestPermissions": [
    { "name": "ohos.permission.ACCESS_SERVICE_NAVIGATION_INFO" },
    { "name": "ohos.permission.ACCESS_CAR_DISTRIBUTED_ENGINE" }
  ]
}

这两个权限分别用于:

  • ACCESS_SERVICE_NAVIGATION_INFO:访问导航信息,用来设置和监听导航状态
  • ACCESS_CAR_DISTRIBUTED_ENGINE:访问车机分布式引擎,用来和车机通信

不配置这些权限的话,调用车服务的接口会报错。

项目结构

├── entry/src/main/ets
│   ├── common
│   │   ├── CommonUtils.ets           // 工具类
│   │   └── Logger.ets                // 日志类
│   ├── entryability
│   │   └── EntryAbility.ets          // 程序入口类
│   └── pages
│       ├── Index.ets                 // 程序入口类
│       ├── NavInfoServicePage.ets    // 导航信息交互接口用法类
│       └── TravelServicePage.ets     // 出行业务交互接口用法类
└── entry/src/main/resources          // 应用静态资源目录

项目按功能分成了导航信息交互和出行业务两个页面。

导航信息交互

导航信息交互是车服务最常用的功能。你的导航应用可以通过这个功能,把导航信息同步到车机屏幕上。

第一步:导入模块

import { navigationInfoMgr } from '@kit.CarKit';

导入车服务的导航信息管理模块。这个模块包含了所有的导航信息交互接口。

第二步:注册监听系统导航信息和指令

let controller: navigationInfoMgr.NavigationController = navigationInfoMgr.getNavigationController();

获取 NavigationController 实例,这是导航信息交互的核心控制器。所有的导航操作都通过它来完成。

let listenerImpl: navigationInfoMgr.SystemNavigationListener = {
  onQueryNavigationInfo(query: navigationInfoMgr.QueryType,
    args: Record<string, Object>): Promise<navigationInfoMgr.ResultData> {
    return new Promise(resolve => {
      let data: navigationInfoMgr.ResultData = {
        code: 1111,
        message: `查询[${query}]处理结果Success.`,
        data: {}
      };
      resolve(data);
    });
  },

  onReceiveNavigationCmd(command: navigationInfoMgr.CommandType,
    args: Record<string, Object>): Promise<navigationInfoMgr.ResultData> {
    return new Promise(resolve => {
      let data: navigationInfoMgr.ResultData = {
        code: 2222,
        message: `指令[${command}]处理结果Success.`,
        data: {}
      };
      resolve(data);
    });
  }
};

实现系统导航事件监听器,包含两个回调:

  • onQueryNavigationInfo:监听系统查询事件。比如车机问你"当前导航状态是什么?",你就要返回导航状态
  • onReceiveNavigationCmd:监听系统命令事件。比如车机发来"开始导航"或"停止导航"的指令

这两个回调都返回 Promise,里面包含处理结果。code 是结果码,message 是结果描述,data 是附加数据。

controller.registerSystemNavigationListener(listenerImpl);

调用 registerSystemNavigationListener 注册监听。注册后,系统导航的信息和指令就会回调到你的监听器里。

为什么要注册监听?因为车机可能会主动查询或控制你的导航。比如用户在车机上按了"停止导航"按钮,车机就会发一个指令给你的手机 App,你的 App 收到后要停止导航。

第三步:设置系统导航状态

let navInfoController: navigationInfoMgr.NavigationController = navigationInfoMgr.getNavigationController();

let location: navigationInfoMgr.Location = {
  name: 'ceshi0',
  coordType: navigationInfoMgr.LocationCoordType.GCJ02,
  longitude: 30.0,
  latitude: 30.0,
  altitude: 30.0
};

let data: navigationInfoMgr.NavigationStatus = {
  status: navigationInfoMgr.MapStatus.NAVIGATION,
  naviType: navigationInfoMgr.NaviType.DRIVING,
  destLocation: location,
  passPoint: [location],
  routeIndex: 0,
  routePreference: [],
  theme: navigationInfoMgr.ThemeType.LIGHT,
  customData: 'customData'
};

navInfoController.updateNavigationStatus(data);

设置系统导航状态,告诉车机"我现在在做什么":

  • status:地图状态,NAVIGATION 表示正在导航。还有其他状态,比如 BROWSING(浏览地图)
  • naviType:导航类型,DRIVING 表示驾车导航。还有 WALKING(步行)、CYCLING(骑行)等
  • destLocation:目的地位置。包含名称、坐标类型、经纬度、海拔
  • passPoint:途经点。导航路线中间经过的地点
  • routeIndex:路线索引。如果有多条路线,选择第几条
  • theme:主题类型,LIGHT 表示浅色主题,DARK 表示深色主题

这些信息会同步到车机屏幕上,用户在车机上就能看到导航状态了。

第四步:设置系统导航数据

let data: navigationInfoMgr.NavigationMetadata = {
  naviTurnMode: 0x0001,
  segmentLeftDis: 100,
  currentRoadName: 'currentRoad',
  nextRoadName: 'nextRoad',
  intersectionView: 'intersectionView',
  viewWidth: 960,
  viewHeight: 450,
  trafficLane: '0001',
  cameraSpeedLimitValid: false,
  cameraSpeedLimit: 120,
  naviSpeedLimitValid: true,
  naviSpeedLimit: 80,
  currentSpeed: 75,
  naviBearing: 90.0,
  totalLeftDis: 1546,
  remainingTime: 5,
  customData: { 'sample': 'sampleData' }
};

navInfoController.updateNavigationMetadata(data);

设置系统导航数据,告诉车机"当前的导航细节":

  • naviTurnMode:导航转向类型。比如左转、右转、直行
  • segmentLeftDis:当前路段剩余距离(米)。还有 100 米就要转弯了
  • currentRoadName:当前道路名。显示在车机屏幕上
  • nextRoadName:下一次进入的道路名。告诉用户"下一条路是什么"
  • naviSpeedLimit:导航速度限制(km/h)。当前路段限速 80
  • currentSpeed:当前速度(km/h)。用户当前车速 75
  • totalLeftDis:总剩余距离(米)。还有 1546 米到达目的地
  • remainingTime:剩余时间(分钟)。还有 5 分钟到达

这些数据会实时同步到车机屏幕上,用户在车机上就能看到详细的导航信息。

第五步:取消注册监听

let navInfoController: navigationInfoMgr.NavigationController = navigationInfoMgr.getNavigationController();
navInfoController.unregisterSystemNavigationListener();

应用退出时,调用 unregisterSystemNavigationListener 取消注册监听,释放资源。

为什么要取消注册?因为如果你不取消,系统会一直调用你的监听器,浪费资源。而且你的应用退出后,监听器还在的话,可能会导致内存泄漏。

智慧出行业务

智慧出行业务用来监听车机的事件和连接状态。

第一步:导入模块

import { smartMobilityCommon } from '@kit.CarKit';
import { hilog } from '@kit.PerformanceAnalysisKit';

导入智慧出行的公共模块和日志模块。

第二步:注册出行业务事件监听

let awareness: smartMobilityCommon.SmartMobilityAwareness = smartMobilityCommon.getSmartMobilityAwareness();

let types: smartMobilityCommon.SmartMobilityType[] = [smartMobilityCommon.SmartMobilityType.CAR_HOP];

const callBack = (event: smartMobilityCommon.SmartMobilityEvent) => {
  hilog.info(0x0000, 'Received smart mobility event: ', JSON.stringify(event));
};

awareness.on('smartMobilityEvent', types, callBack);

注册出行业务事件监听:

  1. 获取 SmartMobilityAwareness 实例,这是智慧出行的感知器
  2. 定义要监听的业务类型。CAR_HOP 表示换车事件,用户从一辆车换到另一辆车时会触发
  3. 定义回调函数,当事件发生时会被调用
  4. 调用 awareness.on 注册监听。第一个参数是事件类型,第二个参数是业务类型数组,第三个参数是回调函数

第三步:查询事件详细信息

let awareness: smartMobilityCommon.SmartMobilityAwareness = smartMobilityCommon.getSmartMobilityAwareness();
let type = smartMobilityCommon.SmartMobilityType.CAR_HOP;
let eventName = 'CAR_HOP_EVENT';
let event: smartMobilityCommon.SmartMobilityEvent = awareness.getSmartMobilityEvent(type, eventName);

调用 getSmartMobilityEvent 查询系统应用发送的事件详细信息。你可以传入业务类型和事件名称,获取对应的事件数据。

第四步:监听智慧出行连接状态

let awareness: smartMobilityCommon.SmartMobilityAwareness = smartMobilityCommon.getSmartMobilityAwareness();
let types = [smartMobilityCommon.SmartMobilityType.HICAR];

const callBack = (info: smartMobilityCommon.SmartMobilityInfo) => {
  hilog.info(0x0000, 'Received smart mobility info: ', JSON.stringify(info));
};

awareness.on('smartMobilityStatus', types, callBack);

监听智慧出行连接状态,比如 HiCar 的连接和断开。当手机和车机连接或断开时,会回调这个函数。

HiCar 是华为的手机-车机互联方案,类似于苹果的 CarPlay。用户把手机连接到车机后,手机上的应用可以在车机屏幕上显示。

第五步:获取智慧出行连接状态

let awareness: smartMobilityCommon.SmartMobilityAwareness = smartMobilityCommon.getSmartMobilityAwareness();
let type = smartMobilityCommon.SmartMobilityType.HICAR;
let ret = awareness.getSmartMobilityStatus(type);

调用 getSmartMobilityStatus 获取当前的智慧出行连接状态。你可以用这个来判断手机是否已经连接到车机。

第六步:取消注册监听

let awareness: smartMobilityCommon.SmartMobilityAwareness = smartMobilityCommon.getSmartMobilityAwareness();
let types = [smartMobilityCommon.SmartMobilityType.HICAR];
const callBack = (info: smartMobilityCommon.SmartMobilityInfo) => {
  hilog.info(0x0000, 'Received smart mobility info: ', JSON.stringify(info));
};
awareness.off('smartMobilityStatus', types, callBack);

不需要监听时,调用 awareness.off 取消注册。和导航监听一样,不取消的话会浪费资源。

实际应用场景

车服务在实际开发中有很多用途:

导航应用

// 导航应用把路线信息同步到车机
function syncNavigationToCar(routeInfo: RouteInfo) {
  let controller = navigationInfoMgr.getNavigationController();

  // 设置导航状态
  controller.updateNavigationStatus({
    status: navigationInfoMgr.MapStatus.NAVIGATION,
    naviType: navigationInfoMgr.NaviType.DRIVING,
    destLocation: routeInfo.destination,
    theme: navigationInfoMgr.ThemeType.LIGHT
  });

  // 设置导航数据
  controller.updateNavigationMetadata({
    currentRoadName: routeInfo.currentRoad,
    nextRoadName: routeInfo.nextRoad,
    totalLeftDis: routeInfo.totalDistance,
    remainingTime: routeInfo.remainingTime
  });
}

导航应用可以把当前的导航信息同步到车机上,让用户在车机屏幕上看到导航路线。用户开车时不用看手机,看车机屏幕就行了,更安全。

出行应用

// 监听 HiCar 连接状态
function monitorHiCarConnection() {
  let awareness = smartMobilityCommon.getSmartMobilityAwareness();
  awareness.on('smartMobilityStatus', [smartMobilityCommon.SmartMobilityType.HICAR],
    (info: smartMobilityCommon.SmartMobilityInfo) => {
      if (info.status === 'connected') {
        console.info('HiCar 已连接');
        // 启动车机模式,显示车机专用界面
      } else {
        console.info('HiCar 已断开');
        // 退出车机模式,恢复手机界面
      }
    });
}

出行应用可以监听 HiCar 连接状态,当手机连接到车机时,自动切换到车机模式。车机模式的界面更大、更简洁,适合开车时使用。

换车服务

// 监听换车事件
function monitorCarHopEvent() {
  let awareness = smartMobilityCommon.getSmartMobilityAwareness();
  awareness.on('smartMobilityEvent', [smartMobilityCommon.SmartMobilityType.CAR_HOP],
    (event: smartMobilityCommon.SmartMobilityEvent) => {
      console.info('收到换车事件:', JSON.stringify(event));
      // 处理换车逻辑,比如更新车辆信息
    });
}

换车服务可以监听换车事件,当用户换车时,自动处理相关逻辑。比如用户从一辆车换到另一辆车,你的应用可以自动更新车辆信息。

适用场景

车服务适合以下场景:

  • 导航应用:导航信息同步到车机
  • 出行应用:出行服务和车机联动
  • 音乐应用:音乐播放控制同步到车机
  • 换车服务:换车事件监听和处理
  • 任何需要和车机交互的应用

注意事项

  1. 权限申请:需要申请 ACCESS_SERVICE_NAVIGATION_INFOACCESS_CAR_DISTRIBUTED_ENGINE 权限
  2. 设备限制:目前只支持华为手机
  3. 监听管理:不需要监听时要及时取消注册,避免资源浪费
  4. 数据格式:导航数据要符合车机的要求格式,否则车机可能无法正确显示
  5. 连接状态:使用前要检查设备是否已连接车机

核心流程图

导航信息同步到车机的完整流程:

flowchart TD
    A[配置导航和车机权限] --> B[导入 navigationInfoMgr 模块]
    B --> C[获取 NavigationController 实例]
    C --> D[注册系统导航监听器]
    D --> E[设置导航状态: 类型/目的地/途经点]
    E --> F[设置导航数据: 转向/路名/限速/剩余距离]
    F --> G[数据实时同步到车机屏幕]
    G --> H[用户在车机上查看导航信息]
    H --> I[应用退出时取消注册监听]

智慧出行业务的事件监听流程:

flowchart TD
    A[获取 SmartMobilityAwareness 实例] --> B{监听类型}
    B --> C[监听出行业务事件]
    B --> D[监听连接状态]
    C --> E[注册 smartMobilityEvent 监听]
    E --> F{收到换车事件?}
    F -- 是 --> G[处理换车逻辑]
    D --> H[注册 smartMobilityStatus 监听]
    H --> I{HiCar 连接状态变化?}
    I -- 已连接 --> J[切换到车机模式]
    I -- 已断开 --> K[恢复手机界面]

总结

车服务让你的应用和汽车互联,核心流程:

  1. 配置权限
  2. 导入车服务模块
  3. 注册监听系统导航信息和指令
  4. 设置导航状态和数据
  5. 监听出行业务事件和连接状态

掌握了这些,你就能开发出和车机联动的应用,让用户在驾驶时也能享受你的服务。