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

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

Обзор

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

  • 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);
    }
});

Вы также можете включить ночной режим программно. Подробнее см. в разделе «Установка ночного режима» .