選取平台: Android iOS

設定即時中斷

即時中斷功能會提醒使用者路線上的中斷情形,並允許使用者回報及驗證遇到的中斷情形。例如車禍、交通壅塞、警察和測速照相機位置、施工、車道封閉,以及特定天氣狀況。本頁面說明即時中斷功能和設定選項,包括使用自訂導覽使用者介面的應用程式注意事項。

即時中斷功能

Navigation SDK 包含下列即時中斷功能,可做為核心導航體驗的一部分:

這些功能可供設定,且預設為啟用。以下各節將進一步說明這些功能和可用的設定選項。

路線沿途的互動式中斷通知

應用程式顯示路線時 (無論是路線總覽或導航期間),路線上出現的任何中斷情形都會以標註形式顯示。附註包含表示中斷類型的圖示。

沿途的標註

您可以使用 shouldDisplayPrompts 控制沿途顯示的干擾標註,這項屬性也會控制使用者接近干擾時顯示的自動警示

mapView.navigator.shouldDisplayPrompts = true

使用者輕觸標註時顯示中斷詳細資料

使用者輕觸附註即可顯示資訊卡,當中會提供更多中斷資訊,包括中斷類型、上次回報時間,以及在某些情況下,可選擇是否要投票表決中斷情形是否仍然存在。視使用者是否處於導航狀態而定,系統可能會顯示兩種不同的資訊卡,且每種資訊卡的設定選項各不相同。

在開始導航前,路徑總覽會顯示資訊卡

使用者在開始導航前輕觸路線總覽中的標註時,系統會顯示資訊卡,提供更多中斷資訊。

總覽資訊卡

您可以使用 showsIncidentCards,控管使用者是否能輕觸路線總覽中的中斷標註,顯示更多資訊。

mapView.settings.showsIncidentCards = true

導航期間的附註資訊卡

如果導航期間路線上出現中斷標註,使用者可以輕觸標註來顯示資訊卡,當中會提供中斷的詳細資訊,包括中斷類型和最近一次回報時間,以及用來投票表決中斷是否仍然存在的按鈕。Google 會處理使用者提交的投票,並可能在地圖上顯示給其他 Google 地圖和 Navigation SDK 使用者,也會根據投票結果決定是否繼續顯示中斷資訊。

導航資訊卡

您可以使用 shouldDisplayPrompts 控制導航期間的干擾標註顯示和輕觸功能,這項控制項也會控制沿途顯示的標註,以及使用者接近干擾時顯示的自動警示

mapView.navigator.shouldDisplayPrompts = true

在導航期間,系統會自動發出中斷警報,並提供投票功能

在導航期間,如果使用者接近路線上的中斷點,系統會顯示提示,提供中斷點的相關資訊,以及用於投票的按鈕,讓使用者回報中斷點是否仍存在。Google 會處理使用者提交的票選結果,並可能在 Google 地圖和 Navigation SDK 中顯示給其他使用者,以及用來判斷是否要繼續顯示中斷資訊。

導航資訊卡

您可以使用 shouldDisplayPrompts 設定在導覽期間顯示快訊提示,這項設定也會控管路線沿途的標註顯示方式。

mapView.navigator.shouldDisplayPrompts = true

在導航期間回報中斷情形

在導航模式啟用期間,導航使用者介面會顯示按鈕,方便使用者回報路線上的新狀況。使用者輕觸按鈕後,系統會顯示可回報的干擾類型選單。 Google 會處理使用者提交的檢舉內容,並可能在地圖上顯示,供其他 Google 地圖和 Navigation SDK 使用者查看。

「檢舉」按鈕 報表選單

顯示或隱藏標準報表按鈕

您可以使用 navigationReportIncidentButtonEnabled,在導覽期間設定標準報表按鈕的顯示狀態。

// Enables the incident reporting FAB to show in situations where incident
// reporting is possible.
mapView.settings.navigationReportIncidentButtonEnabled = true

新增自訂檢舉按鈕

您可以在導覽使用者介面中新增自訂回報按鈕,取代標準的服務中斷回報按鈕。使用者點選自訂按鈕時,您可以呼叫 presentReportIncidentsPanel 方法,觸發顯示檢舉選單。新增自訂檢舉按鈕前,請先呼叫 reportIncidentsAvailable,確認應用程式處於有效導覽狀態,且使用者位於檢舉功能已啟用的國家/地區。如果不符合上述任一條件,系統就不會顯示報表選單。

  // Check if reporting is available before displaying your button
  let isReportingAvailable = mapview.isIncidentReportingAvailable()
  customReportingIncidentButton.isHidden = !isReportingAvailable
  customReportingIncidentButton.addTarget(self, action: #selector(didTapReportIncidentButton), for: .touchUpInside)
  
  // Trigger the reporting flow if the button is clicked
  func didTapReportIncidentButton() {
          mapView.presentReportIncidentsPanel(self) { [weak self] error in
              guard let self = self else { return }
              if let error = error as NSError? {
                  if error.domain == GMSMapViewPresentReportIncidentPanelErrorDomain {
                      let errorCode = GMSMapViewPresentReportIncidentPanelErrorCode(rawValue: error.code)
                      
                      switch errorCode {
                      case .internal:
                          self.showErrorMessage(
                              title: "Error Presenting Report Incident Panel",
                              message: "An internal error occurred."
                          )
                      case .reportingNotAvailable:
                          self.showErrorMessage(
                              title: "Error Presenting Report Incident Panel",
                              message: "Reporting is not available."
                          )
                      case .none:
                          self.showErrorMessage(
                              title: "Error Presenting Report Incident Panel",
                              message: "An unknown error occurred."
                          )
                      }
                  } else {
                      // Handle other potential errors (e.g., network errors)
                      self.showErrorMessage(
                          title: "Error Presenting Report Incident Panel",
                          message: "An unexpected error occurred: \(error.localizedDescription)"
                      )
                  }
              }
              // If error is nil, the panel was presented successfully. You can add any extra logic here.
          }
     }

使用自訂導覽 UI

如果 Navigation SDK 導入作業包含自訂 UI 元素,您必須考量即時中斷元素,以免發生衝突。

檢舉按鈕位置

依預設,中斷回報按鈕會顯示在地圖的底部/尾端角落,如果書寫方向是由左至右,按鈕會顯示在右側;如果書寫方向是由右至左,按鈕會顯示在左側。如要移動報表按鈕,為自訂 UI 元素騰出空間,請使用 bottomTrailingButtonsLayoutGuide

Swift

// Create a new layout guide
let topRightLayoutGuide = UILayoutGuide()
self.view.addLayoutGuide(topRightLayoutGuide)

// Activate constraints using fixed constants here as an example
// assuming the current reporting button is of fixed height
topRightLayoutGuide.topAnchor.constraint(equalTo: _mapView.navigationHeaderLayoutGuide.bottomAnchor, constant: 50).isActive = true
topRightLayoutGuide.trailingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.trailingAnchor, constant: -14).isActive = true

// Assign the layout guide
_mapView.bottomTrailingButtonsLayoutGuide = topRightLayoutGuide

// Create an alternate layout guide to use when the header and the footer are not full width
let topRightAlternateLayoutGuide = UILayoutGuide()
self.view.addLayoutGuide(topRightAlternateLayoutGuide)

// Activate constraints using fixed constants here as an example
// assuming the current RTD button is of fixed height
topRightAlternateLayoutGuide.topAnchor.constraint(equalTo: _mapView.navigationHeaderLayoutGuide.bottomAnchor, constant: 20).isActive = true
topRightAlternateLayoutGuide.trailingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.trailingAnchor, constant: -10).isActive = true

// Assign the layout guide
_mapView.bottomTrailingButtonsAlternateLayoutGuide = topRightAlternateLayoutGuide

Objective-C

// Create a new layout guide
UILayoutGuide *topRightLayoutGuide = [[UILayoutGuide alloc] init];
[self.view addLayoutGuide:topRightLayoutGuide];

// Activate constraints using fixed constants here as an example
// assuming the current RTD button is of fixed height
[[topRightLayoutGuide.topAnchor
    constraintEqualToAnchor:_mapView.navigationHeaderLayoutGuide.bottomAnchor
                   constant:50]
    setActive:YES];

[[topRightLayoutGuide.trailingAnchor
    constraintEqualToAnchor:self.view.safeAreaLayoutGuide.trailingAnchor
                   constant:-14]
    setActive:YES];

// Assign the layout guide
_mapView.bottomTrailingButtonsLayoutGuide = topRightLayoutGuide;

// Create an alternate layout guide to use when the header and the footer are not full width
UILayoutGuide *topRightAlternateLayoutGuide = [[UILayoutGuide alloc] init];
[self.view addLayoutGuide:topRightAlternateLayoutGuide];

// Activate constraints using fixed constants here as an example
// assuming the current RTD button is of fixed height
[[topRightAlternateLayoutGuide.topAnchor
    constraintEqualToAnchor:_mapView.navigationHeaderLayoutGuide.bottomAnchor
                   constant:50]
    setActive:YES];

[[topRightAlternateLayoutGuide.trailingAnchor
    constraintEqualToAnchor:self.view.safeAreaLayoutGuide.trailingAnchor
                   constant:-14]
    setActive:YES];

// Assign the layout guide
_mapView.bottomTrailingButtonsAlternateLayoutGuide = topRightAlternateLayoutGuide;

提示瀏覽權限 API (實驗性)

您可以新增接聽程式,在 Navigation SDK UI 元素即將顯示前和移除後立即收到回呼,藉此使用 Prompt Visibility API 避免 Navigation SDK 產生的 UI 元素與自訂 UI 元素發生衝突。您可以接收即時中斷元素的回呼,包括資訊卡、提示和中斷回報選單,以及 Navigation SDK 產生的其他通知。

Swift

// Additional methods added to GMSNavigatorListener
...
func navigatorWillPresentPrompt(_ navigator: GMSNavigator) {
  // Hide any sort of custom UI element.
}

func navigatorDidDismissPrompt(_ navigator: GMSNavigator) {
  // Show any sort of custom UI element.
}
...

Objective-C

// Additional methods added to GMSNavigatorListener
...
- (void)navigatorWillPresentPrompt:(GMSNavigator *)navigator {
  // Hide any sort of custom UI element.
}

- (void)navigatorDidDismissPrompt:(GMSNavigator *)navigator {
  // Show any sort of custom UI element.
}
...