Слушайте навигационные события

Ваше приложение может отслеживать события, происходящие во время перемещения пользователя по маршруту.

Обзор

Для прослушивания событий навигации используйте следующие интерфейсы:

  • Navigator.ArrivalListener обеспечивает обратный вызов onArrival() , который срабатывает, когда устройство прибывает в пункт назначения.
  • RoadSnappedLocationProvider.LocationListener предоставляет обратный вызов onLocationChanged() , который срабатывает при изменении местоположения устройства.
  • Navigator.RemainingTimeOrDistanceChangedListener предоставляет обратный вызов onRemainingTimeOrDistanceChanged() , который срабатывает, когда время или расстояние до следующего пункта назначения изменяется более чем на заданную величину.
  • Navigator.RouteChangedListener предоставляет обратный вызов onRouteChanged() , срабатывающий при изменении маршрута.

Посмотреть код

Определить прибытие в пункт назначения

Здесь под пунктом назначения понимается либо конечный пункт назначения, либо промежуточная точка. Чтобы обнаружить прибытие, вызовите Navigator.addArrivalListener() , который регистрируется для обратного вызова, когда устройство достигает пункта назначения.

По прибытии Navigation SDK для Android запускает обратный вызов onArrival() , который затем можно использовать для остановки пошагового руководства с помощью Navigator.stopGuidance() или перехода к следующей точке маршрута с помощью Navigator.continueToNextDestination() . Если сеанс навигации включал только один пункт назначения или если в списке пунктов назначения не осталось ни одного пункта назначения, вызов Navigator.continueToNextDestination() автоматически останавливает руководство.

При вызове continueToNextDestination() навигатор отбрасывает всю информацию о предыдущем пункте назначения. Если вы хотите проанализировать информацию о предыдущем сегменте маршрута, вы должны получить информацию от навигатора перед вызовом continueToNextDestination() .

Чтобы избежать утечек памяти, необходимо вызвать removeArrivalListener(listener) когда прослушиватель больше не нужен.

mNavigator.addArrivalListener(new Navigator.ArrivalListener() {
    @Override
    public void onArrival(ArrivalEvent arrivalEvent) {
        displayMessage("onArrival: You've arrived at a waypoint: "
                +   mNavigator.getCurrentRouteSegment().getDestinationWaypoint().getTitle(),
                DISPLAY_BOTH);
        // Start turn-by-turn guidance for the next leg of the route.
        if (arrivalEvent.isFinalDestination()) {
            displayMessage("onArrival: You've arrived at the final destination.",
                    DISPLAY_BOTH);
        } else {
            mNavigator.continueToNextDestination();
            mNavigator.startGuidance();
        }
    }
});

Получать обновления местоположения

Получите RoadSnappedLocationProvider из NavigationApi , затем вызовите RoadSnappedLocationProvider.addLocationListener() для регистрации обратного вызова при изменении местоположения или направления устройства. Обратите внимание, что это местоположение привязано к дороге, поэтому оно может отличаться от местоположения, возвращаемого поставщиком объединенного местоположения в API местоположения сервисов Google Play.

Navigation SDK предоставляет обновления местоположения так часто, как это возможно. Когда доступно обновление местоположения, Navigation SDK запускает обратный вызов onLocationChanged() .

Обновления местоположения, привязанные к дороге, не зависят от навигации и могут продолжаться даже после ее остановки. Подписка на обновления местоположения может привести к разрядке батареи, утечке памяти или непреднамеренному сбору данных о местоположении устройства, если вы оставите обновления местоположения запущенными в фоновом режиме. Вызовите RoadSnappedLocationProvider.removeLocationListener , когда вам больше не нужен слушатель.

mRoadSnappedLocationProvider =
        NavigationApi.getRoadSnappedLocationProvider(getApplication());
if (mRoadSnappedLocationProvider != null) {
    mRoadSnappedLocationProvider.addLocationListener(
            new RoadSnappedLocationProvider.LocationListener() {
                @Override
                public void onLocationChanged(Location location) {
                    displayMessage("onLocationUpdated: Navigation engine has provided a new"
                                    +   " road-snapped location: "
                                    +   location.toString(),
                            DISPLAY_LOG);
                }
            });
} else {
    displayMessage("ERROR: Failed to get a location provider", DISPLAY_LOG);
}

Получайте обновления времени и расстояния

Вызовите Navigator.addRemainingTimeOrDistanceChangedListener() , чтобы зарегистрироваться для обратного вызова, когда оставшееся время (секунды) или расстояние (метры) изменятся более чем на заданное пороговое значение.

Когда изменение времени или расстояния превышает указанную величину, Navigation SDK запускает обратный вызов onRemainingTimeOrDistanceChanged() .

Чтобы узнать оставшееся время и расстояние, вызовите Navigator.getTimeAndDistanceList() . Обратите внимание, что время и расстояние в списке являются кумулятивными: они показывают время и расстояние от текущего местоположения до каждой точки маршрута, а не от одной точки маршрута до другой. Объект TimeAndDistance теперь также возвращает delaySeverity . Это перечисление будет либо тяжелым, либо средним, либо легким, либо неизвестным. Это соответствует цвету, который вы видите на eta в пользовательском интерфейсе карт (тяжелый = красный, средний = желтый, легкий = зеленый). Это полезно, если вам нужно создать свой собственный нижний колонтитул eta.

Чтобы избежать утечек памяти, необходимо вызвать Navigator.removeRemainingTimeOrDistanceChangedListener(listener) , когда прослушиватель вам больше не нужен.

В приведенном ниже примере запрашивается обратный вызов, если оставшееся время изменяется более чем на 60 секунд или оставшееся расстояние изменяется более чем на 100 метров.

mNavigator.addRemainingTimeOrDistanceChangedListener(60, 100,
        new Navigator.RemainingTimeOrDistanceChangedListener() {
            @Override
            public void onRemainingTimeOrDistanceChanged() {
                displayMessage("onRemainingTimeOrDistanceChanged: Time or distance estimate"
                        +   " has changed.",
                        DISPLAY_LOG);
            }
        });

Вы можете отобразить оставшееся время и информацию о расстоянии с помощью встроенного дисплея, используя метод setEtaCardEnabled() и передав параметр со значением TRUE . Чтобы отключить отображение времени и расстояния, установите это значение на FALSE .

Вы также можете предоставить расчетное время прибытия для нескольких путевых точек с помощью метода getTimeAndDistanceList() .

Получать обновления маршрута

Вызовите Navigator.addRouteChangedListener() , чтобы зарегистрироваться для обратного вызова при изменении маршрута.

При изменении маршрута Navigation SDK запускает обратный вызов onRouteChanged() . Вы можете вызвать Navigator.getRouteSegments и Navigator.getCurrentRouteSegment() , чтобы найти новый маршрут.

Чтобы избежать утечек памяти, необходимо вызвать removeRouteChangedListener(listener) когда прослушиватель больше не нужен.

mNavigator.addRouteChangedListener(new Navigator.RouteChangedListener() {
    @Override
    public void onRouteChanged() {
        displayMessage("onRouteChanged: The driver's route has changed. Current waypoint: "
                +   mNavigator.getCurrentRouteSegment().getDestinationWaypoint().getTitle(),
                DISPLAY_LOG);
    }
});

Определить, когда меняется ночной режим

Вызовите NavigationView.addOnNightModeChangedListener или SupportNavigationFragment.addOnNightModeChangedListener , чтобы зарегистрироваться для обратного вызова при изменении ночного режима.

В следующем примере показано прослушивание изменений ночного режима на фрагменте навигации.

mNavFragment.addOnNightModeChangedListener(new NavigationView.OnNightModeChangedListener() {
    @Override
    public void onNightModeChanged(NightModeChangedEvent nightModeChangedEvent) {
        displayMessage("Night mode is active: " + nightModeChangedEvent.inNightMode(),
        DISPLAY_LOG);
    }
});

Вы также можете установить ночной режим программно. Для получения дополнительной информации см. Установка ночного режима .