繪製地圖

使用下列範本的導航、搜尋點 (POI) 和天氣應用程式可以存取 Surface 來繪製地圖。

如要使用下列範本,應用程式必須在 AndroidManifest.xml 檔案的 <uses-permission> 元素中,宣告其中一項對應權限。

Template 權限 指南
NavigationTemplate androidx.car.app.NAVIGATION_TEMPLATES 導覽
MapWithContentTemplate

androidx.car.app.NAVIGATION_TEMPLATES

androidx.car.app.MAP_TEMPLATES

導覽興趣點天氣

MapTemplate

(已淘汰)

androidx.car.app.NAVIGATION_TEMPLATES 導覽

PlaceListNavigationTemplate

(已淘汰)

androidx.car.app.NAVIGATION_TEMPLATES 導覽

RoutePreviewNavigationTemplate

(已淘汰)

androidx.car.app.NAVIGATION_TEMPLATES 導覽

查看參考實作

如要查看完整的參考實作方式,請參閱「導覽範例」。

宣告表面權限

除了應用程式使用的範本所需權限外,應用程式也必須在 AndroidManifest.xml 檔案中宣告 androidx.car.app.ACCESS_SURFACE 權限,才能存取介面:

<manifest ...>
  ...
  <uses-permission android:name="androidx.car.app.ACCESS_SURFACE" />
  ...
</manifest>

存取介面

如要存取主機提供的 Surface,您必須實作 SurfaceCallback,並將該實作項目提供給 AppManager 車輛服務。目前的 Surface 會在 onSurfaceAvailable()onSurfaceDestroyed() 回呼的 SurfaceContainer 參數中,傳遞至 SurfaceCallback

Kotlin

carContext.getCarService(AppManager::class.java).setSurfaceCallback(surfaceCallback)

Java

carContext.getCarService(AppManager.class).setSurfaceCallback(surfaceCallback);

使用虛擬螢幕算繪內容

除了使用 Canvas API 直接算繪至 Surface,您也可以使用 VirtualDisplayPresentation API 將 Views 算繪至 Surface,如下列範例所示:

class HelloWorldSurfaceCallback(context: Context) : SurfaceCallback {
  lateinit var virtualDisplay: VirtualDisplay
  lateinit var presentation: Presentation

  override fun onSurfaceAvailable(surfaceContainer: SurfaceContainer) {
      virtualDisplay = context
          .getSystemService(DisplayManager::class.java)
          .createVirtualDisplay(
              VIRTUAL_DISPLAY_NAME ,
              surfaceContainer.width,
              surfaceContainer.height,
              surfaceContainer.dpi,
              surfaceContainer.surface,
              0
          )

      presentation = Presentation(context, virtualDisplay.display)

      // Instantiate the view to be used as the content view
      val view = ...

      presentation.setContentView(view)
      presentation.show()
  }

  override fun onSurfaceDestroyed(surfaceContainer: SurfaceContainer) {
    presentation.dismiss()
    // This handles releasing the Surface provided when creating the VirtualDisplay
    virtualDisplay.release()
  }
}

使用 Compose 轉譯至虛擬螢幕

您可以將 ComposeView 做為 Presentation 的內容檢視畫面。由於 ComposeView 是在活動外部使用,請確認該活動或父項檢視區塊會傳播 LifecycleOwnerSavedStateRegistryOwner。如要執行這項操作,請使用 setViewTreeLifecycleOwnersetViewTreeSavedStateRegistryOwner

Session 已實作 LifecycleOwner。如要同時提供這兩種角色,您的實作項目可以額外實作 SavedStateRegistryOwner

class HelloWorldSession() : Session(), SavedStateRegistryOwner { ... }

class HelloWorldSurfaceCallback(session: HelloWorldSession) : SurfaceCallback {
  ...

  override fun onSurfaceAvailable(surfaceContainer: SurfaceContainer) {
    ...
    val view = ComposeView(session.carContext)
    view.setViewTreeLifecycleOwner(session)
    view.setViewTreeSavedStateRegistryOwner(session)
    view.setContent {
      // Composable content
    }

    presentation.setContentView(view)
    presentation.show()
  }

  ...
}

瞭解可見表面區域

主機可在地圖上層為範本繪製使用者介面元素。主機會呼叫 SurfaceCallback.onVisibleAreaChanged 方法,與使用者絕對可見的開放區域通訊。

為盡量減少變更,主機會透過最小矩形呼叫 SurfaceCallback.onStableAreaChanged 方法,這種矩形一律會根據目前的範本顯示。

舉例來說,如果導航應用程式使用有頂端動作列NavigationTemplate,在使用者未與畫面互動時,系統就會隱藏該動作列,為畫面提供更多空間。在這種情況下,系統會使用相同矩形來回呼 onStableAreaChangedonVisibleAreaChanged

動作列隱藏時,系統只會使用較大區域呼叫 onVisibleAreaChanged。如果使用者與畫面互動,系統只會使用第一個矩形呼叫 onVisibleAreaChanged

支援深色主題

當主機判定條件可提供擔保時,應用程式必須使用適當的深色在 Surface 例項上重新繪製地圖,如「車用 Android 應用程式品質指南」所述。

如要繪製深色地圖,請使用 CarContext.isDarkMode 方法。深色主題狀態變更時,您會收到 Session.onCarConfigurationChanged 呼叫。

在儀表板螢幕上繪製地圖

除了在主螢幕上繪製地圖,導航應用程式也可以支援在方向盤後方的儀表板螢幕上繪製地圖。詳情請參閱「繪製到叢集螢幕」。