启用精细数据 Feed

精细导航数据 Feed 可向未设计为提供基于地图的导航指引的设备提供仅限导航的信息。它会为即将执行的车辆避障操作提供您提供的元素:

  • 图标(向左、向右、掉头)
  • 环岛的转弯编号
  • 道路名称
  • 到下一个导航步骤或最终目的地的预计距离和时间

您可以使用精细导航 Feed 在不适合使用完整 Navigation SDK 界面的环境中打造体验,例如在 Android Auto 中或在无法使用完整 Android 堆栈的小屏幕显示屏上。例如,您可以将此功能用于两轮车驾驶员,在这种情况下,您可以投影仅限导航的导引,帮助他们在尽可能减少干扰的情况下更快、更自信地到达目的地。

如需使用该 SDK,您需要创建一个服务并将其注册到 Navigation SDK for Android,以便它能够实时接收新的导航信息(在导航期间大约每秒一次)。

本文档介绍了如何创建和注册导航服务,以接收来自 SDK 的导航信息并向接收设备提供导航状态。

概览

本部分概要介绍了启用精细导航功能的大致流程。

使用精细导航功能

以下是启用精细导航功能的简要步骤。以下部分详细介绍了每个步骤。

  1. 创建用于接收导航更新的服务

  2. 注册服务

  3. 了解导航状态

创建用于接收导航更新的服务

Navigation SDK 会绑定到您的精细导航服务,并通过 Android 信使向其发送导航更新。您可以为这些更新创建新的导航服务,也可以使用现有服务。

使用服务接收导航更新的好处在于,该服务可以位于单独的后台进程中。

以下示例中的服务会接收导航信息,并使用 TurnByTurnManager 将数据转换为包含导航详细信息的 NavInfo 对象。

/**
 *   Receives turn-by-turn navigation information forwarded from NavSDK.
 */
public class NavInfoReceivingService extends Service {
  /** The messenger used by the service to receive nav step updates. */
  private Messenger incomingMessenger;
  private TurnByTurnManager turnByTurnManager;

  private final class IncomingNavStepHandler extends Handler {
    public IncomingNavStepHandler(Looper looper) {
      super(looper);
    }

    @Override
    public void handleMessage(Message msg) {
      // Identify the message through the msg.what field.
      if (TurnByTurnManager.MSG_NAV_INFO == msg.what) {
        // Extract the NavInfo object using the TurnByTurnManager.
        NavInfo navInfo = turnByTurnManager
          .readNavInfoFromBundle(msg.getData()));
      // Do something with the NavInfo
    }
  }
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
  return incomingMessenger.getBinder();
}

@Override
public void onCreate() {
  turnByTurnManager = TurnByTurnManager.createInstance();
  HandlerThread thread =
    new HandlerThread("NavInfoReceivingService",
      Process.THREAD_PRIORITY_DEFAULT);
  thread.start();
  incomingMessenger = new Messenger(
    new IncomingNavStepHandler(thread.getLooper()));
}

消息代码

Message 类的 Message.what 字段可用于识别 NavInfo 消息,该字段设置为 TurnByTurnManager.MSG_NAV_INFO 的值。

注册服务以接收导航更新

以下代码段会注册导航服务。

boolean isNavInfoReceivingServiceRegistered =
          navigator.registerServiceForNavUpdates(
              getPackageName(), NavInfoReceivingService.class.getName(), numNextStepsToPreview);

启动和停止服务

只要 Navigation SDK 绑定到导航服务,导航服务就会处于活动状态。您可以手动调用 startService()stopService() 来控制导航服务生命周期,但当您向 Navigation SDK 注册服务时,您的服务会自动启动,并且只有在您取消注册服务时才会停止。根据您设置应用的方式,您可能需要考虑启动前台服务,如 Android 文档中的服务概览中所述。

取消注册服务

如需停止接收导航更新,请从 Navigation SDK 取消注册该服务。

navigator.unregisterServiceForNavUpdates();

了解导航状态

使用 NavInfo.getNavState() 获取导航的当前状态,该状态为以下之一:

  • 正在导航 - ENROUTE 状态表示导航功能目前处于活跃状态,并且用户位于所提供的路线上。系统会提供有关当前即将执行的车辆操控步骤的信息。

  • 重新规划路线 - REROUTING 表示导航正在进行,但导航器正在寻找新路线。由于尚无新路线,因此无法显示即将执行的操作步骤。在示例应用中,导航信息显示屏中会显示“正在重新路线...”消息。找到路线后,系统会发送状态为 ENROUTENavInfo 消息。

  • 已停止 - STOPPED 表示导航已结束。例如,当用户退出应用中的导航时,导航会停止。在示例应用中,STOPPED 状态会清除导航信息显示屏,以防止显示延迟的步骤说明。

填充 Feed 显示屏

现在,您已设置精细导航服务。本部分介绍了可用于为精细导航 Feed 填充引导卡片的视觉元素和文本元素。

移动屏幕,显示 100 英尺后即将左转进入 W Ahwanee Ave。屏幕底部显示,距离目的地还有 46 分钟,剩余距离为 39 英里。

当用户进入导航模式时,顶部会显示导航卡片,其中包含从 Navigation SDK 填充的导航数据。相关图片展示了这些基本导航元素的示例。

下表显示了导航信息的字段以及这些字段所在的位置。

每个导航步骤的字段 整个行程的字段
发现时间:StepInfo 发现时间:NavInfo
完整道路名称 剩余时间
相应车辆的“车辆操作”图标 与目的地的距离
距离下一步的距离
车道导航字段

车道导航

Navigation SDK 将导航转弯卡片中的车道表示为 LaneLaneDirection 数据对象。Lane 对象表示导航期间的特定车道,并包含一个 LaneDirection 对象列表,用于描述可在此车道上执行的所有转弯。

车道指引配置示例。

用户应在车道中采取的建议方向由 isRecommended 字段标记。

车道导航示例

以下代码段展示了上面显示的车道的表示形式。

// Lane 1
LaneDirections = [{/*laneShape=*/ STRAIGHT, /*isRecommended=*/ false},
                  {/*laneShape=*/ SLIGHT_LEFT, /*isRecommended=*/ true}]

// Lane 2
LaneDirections = [{/*laneShape=*/ STRAIGHT, /*isRecommended=*/ false}]

创建演习图标

Maneuver 枚举定义了导航期间可能发生的每种机动,您可以通过 StepInfo.getManeuver() 方法获取给定步骤的机动。

您必须创建机动图标,并将其与关联的机动配对。对于某些操控,您可以将其与图标(例如 DESTINATION_LEFTDESTINATION_RIGHT)进行一对一映射。不过,由于某些车辆操控相似,因此您可能需要将多个车辆操控映射到单个图标。例如,TURN_LEFTON_RAMP_LEFT 都可以映射到左转图标。

某些车辆操控包含额外的 clockwisecounterclockwise 标签,SDK 会根据国家/地区的驾驶侧来确定这些标签。例如,在车辆靠左行驶的国家/地区,驾驶员在环岛路或 U 形转弯时会顺时针行驶,而在车辆靠右行驶的国家/地区,驾驶员在环岛路或 U 形转弯时会逆时针行驶。Navigation SDK 会检测相应车辆是在左侧车道还是右侧车道上执行相应车辆动作,并输出相应的车辆动作。因此,顺时针和逆时针转弯的标志图标可能会有所不同。

展开即可查看不同驾驶操作的示例图标

示例图标 精细导航指令
DEPART
UNKNOWN
STRAIGHT
ON_RAMP_UNSPECIFIED
OFF_RAMP_UNSPECIFIED
NAME_CHANGE
TURN_RIGHT
ON_RAMP_RIGHT
TURN_LEFT
ON_RAMP_LEFT
TURN_SLIGHT_RIGHT
ON_RAMP_SLIGHT_RIGHT
OFF_RAMP_SLIGHT_RIGHT
TURN_SLIGHT_LEFT
ON_RAMP_SLIGHT_LEFT
OFF_RAMP_SLIGHT_LEFT
TURN_SHARP_RIGHT
ON_RAMP_SHARP_RIGHT
OFF_RAMP_SHARP_RIGHT
TURN_SHARP_LEFT
ON_RAMP_SHARP_LEFT
OFF_RAMP_SHARP_LEFT
TURN_U_TURN_COUNTERCLOCKWISE
ON_RAMP_U_TURN_COUNTERCLOCKWISE
OFF_RAMP_U_TURN_COUNTERCLOCKWISE
TURN_U_TURN_CLOCKWISE
ON_RAMP_U_TURN_CLOCKWISE
OFF_RAMP_U_TURN_CLOCKWISE
ROUNDABOUT_SHARP_RIGHT_COUNTERCLOCKWISE
ROUNDABOUT_SHARP_RIGHT_CLOCKWISE
ROUNDABOUT_RIGHT_COUNTERCLOCKWISE
ROUNDABOUT_RIGHT_CLOCKWISE
ROUNDABOUT_SLIGHT_RIGHT_COUNTERCLOCKWISE
ROUNDABOUT_SLIGHT_RIGHT_CLOCKWISE
ROUNDABOUT_STRAIGHT_COUNTERCLOCKWISE
ROUNDABOUT_STRAIGHT_CLOCKWISE
ROUNDABOUT_SLIGHT_LEFT_COUNTERCLOCKWISE
ROUNDABOUT_SLIGHT_LEFT_CLOCKWISE
ROUNDABOUT_LEFT_COUNTERCLOCKWISE
ROUNDABOUT_LEFT_CLOCKWISE
ROUNDABOUT_SHARP_LEFT_COUNTERCLOCKWISE
ROUNDABOUT_SHARP_LEFT_CLOCKWISE
ROUNDABOUT_U_TURN_COUNTERCLOCKWISE
ROUNDABOUT_U_TURN_CLOCKWISE
ROUNDABOUT_COUNTERCLOCKWISE
ROUNDABOUT_CLOCKWISE
ROUNDABOUT_EXIT_COUNTERCLOCKWISE
ROUNDABOUT_EXIT_CLOCKWISE
MERGE_RIGHT
OFF_RAMP_RIGHT
MERGE_LEFT
OFF_RAMP_LEFT
FORK_RIGHT
TURN_KEEP_RIGHT
ON_RAMP_KEEP_RIGHT
OFF_RAMP_KEEP_RIGHT
FORK_LEFT
TURN_KEEP_LEFT
ON_RAMP_KEEP_LEFT
OFF_RAMP_KEEP_LEFT
MERGE_UNSPECIFIED
DESTINATION
DESTINATION_RIGHT
DESTINATION_LEFT
FERRY_BOAT
FERRY_TRAIN

使用生成的图标

Navigation SDK 提供的生成的图标的简短列表。

为了方便使用 Android Auto 用例,Navigation SDK 支持生成车道指示和车道引导图标。这些图标符合 Android Auto 汽车应用库的图片大小准则,该准则建议以 500 x 74 dp 边界框为目标。如需了解详情,请参阅 Android 参考文档中的 setsLaneImageCarIcon

图标生成示例

NavigationUpdatesOptions options =
  NavigationUpdatesOptions.builder()
             .setNumNextStepsToPreview(numNextStepsToPreview)
             .setGeneratedStepImagesType(GeneratedStepImagesType.BITMAP)
             .setDisplayMetrics(getResources().getDisplayMetrics())
             .build();
boolean isRegistered =
          navigator.registerServiceForNavUpdates(
              getPackageName(),
              NavInfoReceivingService.class.getName(),
              options);

启用图标生成后,TurnbyTurn StepInfo 对象会使用图标填充 maneuverBitmaplanesBitmap 字段。

后续步骤