在停車時使用的應用程式中新增 Android Automotive OS 支援功能

將應用程式發布至 Android Automotive OS 裝置時,請注意板型規格特有的考量事項。本指南將說明這些考量事項。

在 Android Automotive OS 模擬器上測試現有應用程式

如要開始建構適用於 Android Automotive OS 的應用程式,請先在 Android Automotive OS 模擬器測試現有應用程式。如要設定模擬器,請按照「使用 Android Automotive OS 模擬器進行測試」的步驟操作,然後依據「在模擬器上執行應用程式」說明,執行應用程式。

執行應用程式時請留意相容性問題,例如:

  • 資訊娛樂系統的畫面為固定螢幕方向。為符合車用應用程式品質指南規定,應用程式必須同時支援直向和橫向螢幕方向。
  • 其他裝置適用的 API 可能不適用於 Android Automotive OS。舉例來說,Android Automotive OS 並不支援某些 Google Play 服務 API。如要進一步瞭解如何處理這些問題,請參閱「停用功能」一節。

設定應用程式的資訊清單檔案

應用程式必須含有特定的資訊清單項目,才能將 Android Automotive OS 裝置設為目標平台。選擇在 Android Automotive OS 裝置上發布應用程式後,Google Play 會審查相容的應用程式,確保這些應用程式可在車上安全使用。詳情請參閱「發行至車輛」一文。

必要的 Android Automotive OS 功能

為 Android Automotive OS 建構的所有應用程式都必須符合特定規定,才能透過 Google Play 發布。詳情請參閱「符合 Google Play 功能規定」。

特定類別的資訊清單項目

除了上述適用於所有停妥時使用的應用程式規定,影片和遊戲類別還有額外規定:

符合駕駛人分心等級規定

將應用程式帶到車上時,請務必避免駕駛人分心。對於車輛停妥時使用的應用程式,主要做法是防止應用程式在使用者體驗 (UX) 限制生效時使用或播放音訊,如 DD-2DD-3 品質指南所述。

啟用使用者體驗限制時禁止使用

根據預設,UX 限制生效時,活動無法使用或啟動。為確保這項行為適用於您的應用程式,應用程式資訊清單的任何 <activity> 元素中,都不得包含下列 <meta-data> 元素:

<!-- NOT ALLOWED -->
<meta-data
  android:name="distractionOptimized"
  android:value="true"/>

如果應用程式中的活動在使用者體驗限制啟動時處於「已恢復」狀態,就會遭到作業系統擁有的活動遮蔽。

至少,應用程式的活動會轉換為暫停生命週期狀態。這項操作會以 onPause 生命週期回呼的方式進行,期間您必須暫停播放應用程式中的影片和音訊。

在搭載 Android Automotive OS 相容模式的裝置上,系統封鎖會導致應用程式活動從「暫停」狀態轉換為「已停止」狀態

停止播放並防止繼續播放

對於部分應用程式,只要在 onPause() 期間暫停播放,並追蹤狀態以防止在 onResume() 之前繼續播放,就足以符合駕駛人分心規定。

如果應用程式需要的不只是對生命週期回呼做出反應,您可以按照下一節所述,直接監聽 UX 限制狀態。舉例來說,支援子母畫面的應用程式可能會偏好直接監聽,而不是在生命週期回呼中進行條件檢查。

注意使用者體驗限制

如要監聽 UX 限制,請先在應用程式模組的 build.gradle 檔案中,新增 android.car 程式庫的依附元件。這是 Android SDK 的擴充功能,提供 Android Automotive OS 專用的 API。

android {
    ...
    useLibrary("android.car")
}

使用 CarUxRestrictionsManager 讀取 UX 限制狀態。請勿嘗試從其他硬體狀態 (例如檔位或速度) 判斷使用者體驗限制狀態,因為車輛內不同螢幕的使用者體驗限制可能有所不同。

val car = Car.createCar(context) ?: return
val carUxRestrictionsManager =
    car.getCarManager(Car.CAR_UX_RESTRICTION_SERVICE) as? CarUxRestrictionsManager ?: return

// You can either read the state directly ...
val currentUxRestrictions = carUxRestrictionsManager.currentCarUxRestrictions

// or listen to state changes
carUxRestrictionsManager.registerListener { carUxRestrictions: CarUxRestrictions ->
    // Handle UX restrictions
}

// Don't forget to teardown and release resources when they're no longer needed
carUxRestrictionsManager.unregisterListener()
car.disconnect()

應用程式參照的 CarUxRestrictions 唯一值是 isRequiresDistractionOptimization 的傳回值。其他值僅適用於標示為「適合在分心時使用」的活動。

測試實作成果

請按照下列程序,驗證應用程式是否符合駕駛人分心等級規定:

  1. 系統映像檔上安裝應用程式,不必使用 Google Play 商店或相容性模式。
  2. 開啟啟動器應用程式排列顯示,模擬駕駛並確認無法開啟應用程式。
  3. 停止模擬行車狀態,開啟應用程式並前往播放畫面,然後開始播放。
  4. 再次模擬駕駛,確認播放作業已暫停。
    1. 如果應用程式支援與 MediaSession 整合,請使用 adb shell cmd media_session dispatch play 並確認播放作業不會繼續。

為 Android Automotive OS 最佳化應用程式

為盡可能在車輛中提供最佳使用者體驗,建構 Android Automotive OS 應用程式時,請留意下列事項:

使用視窗插邊和螢幕凹口

與其他板型規格一樣,Android Automotive OS 包含系統 UI 元素 (例如狀態和導覽列),並支援非矩形螢幕。

根據預設,應用程式會在不與系統資訊列或螢幕凹口重疊的區域繪製內容。不過,您可能會希望應用程式隱藏系統資訊列、在系統資訊列後方繪製內容,或在螢幕凹口中顯示內容,如「在視窗插邊內配置應用程式」一文所述。如果應用程式會執行上述任一操作,請參閱下列小節,瞭解如何讓應用程式在 Android Automotive OS 裝置生態系統中順暢運作。

系統資訊列、沉浸模式和無邊框轉譯

車輛中的系統資訊列大小和位置可能與其他外型規格不同。舉例來說,導覽列可以放在畫面左側、右側或底部。即使頂端有狀態列,底部有導覽列 (大多數手機和平板電腦都是如此),這些元素在車輛中顯示時,大小可能也會大得多。

此外,Android Automotive OS 可讓原始設備製造商控制應用程式是否能顯示或隱藏系統資訊列,以進入及退出沉浸模式。舉例來說,原始設備製造商 (OEM) 可以選擇讓應用程式不隱藏系統資訊列,確保車輛控制項 (例如溫度控制項) 一律會顯示在螢幕上供隨時存取。如果 OEM 禁止應用程式控制系統資訊列,應用程式呼叫 WindowInsetsController (或 WindowInsetsControllerCompat) API 來顯示或隱藏系統資訊列時,不會發生任何事。如要進一步瞭解如何偵測應用程式是否能夠修改插邊,請參閱 showhide 的說明文件。

同樣地,原始設備製造商也可以控管應用程式是否能設定系統資訊列的顏色和半透明度,確保資訊列和其中的元素隨時都能清楚顯示。如果應用程式會繪製無邊框內容,請確認系統資訊列後方只會繪製非重要內容。如果裝置 OEM 阻擋設定資訊列的顏色或半透明度,這項內容可能不會顯示。

<!-- Depending on OEM configuration, these style declarations
     (and the corresponding runtime calls) may be ignored -->
<style name="...">
  <item name="android:statusBarColor">...</item>
  <item name="android:navigationBarColor">...</item>
  <item name="android:windowTranslucentStatus">...</item>
  <item name="android:windowTranslucentNavigation">...</status>
</style>

如果應用程式採用無邊框設計,請勿假設系統資訊列的大小、數量、類型或位置。請改用視窗插邊 API,根據系統資訊列配置應用程式內容。如要進一步瞭解如何使用這些 API,請參閱「在應用程式中以無邊框方式顯示內容」。不建議為任何外型規格硬式編碼邊框間距值,但在車輛中,這類值可能完全無法將內容保留在安全區域內。

配合不規則形狀的螢幕調整

除了矩形螢幕,部分車輛也可能配備不規則形狀的螢幕,如圖 1 所示:

螢幕右側彎曲的 Android Automotive OS 裝置。
圖 1:Android Automotive OS 裝置,螢幕右側為弧形。綠色區域是安全矩形,不會與曲線螢幕凹口的定界框重疊。

如果應用程式不會無邊框顯示,您不需要採取任何行動,應用程式就會在安全區域內顯示。

如果應用程式會無邊框顯示,您可以選擇應用程式在螢幕凹口方面的行為。如要達成這個目標,您可以使用資源,為應用程式的主題設定 android:windowLayoutInDisplayCutoutMode 屬性,或在執行階段修改視窗的 layoutInDisplayCutoutMode 屬性。

Android Automotive OS 裝置上的螢幕凹口類型與行動裝置不同,因此請勿使用 LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULTLAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES,因為這些項目已針對行動裝置上的凹口進行最佳化。請改用 LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVERLAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS,一律避開或一律進入凹口。選擇後者時,請參閱「支援螢幕凹口」,進一步瞭解與螢幕凹口相關的 API。

如果應用程式會算繪到螢幕凹口區域,且您希望 Android Automotive OS 和行動裝置有不同行為,請參閱「停用功能」一節,瞭解如何讓應用程式在執行階段設定這項行為;如果應用程式使用資源檔案設定這項行為,請參閱「使用替代資源」一節。

停用功能

如果您打算在 Android Automotive OS 上提供現有的行動應用程式,某些特性和功能可能會不適合或無法使用。舉例來說,汽車通常不會授予相機存取權限。此外,Android Automotive OS 只支援部分 Google Play 服務,詳情請參閱「車用 Google Play 服務」一文。

您可以使用 PackageManager.hasSystemFeature API,檢查應用程式是否具備 FEATURE_AUTOMOTIVE 功能,偵測應用程式是否在 Android Automotive OS 上執行。如以下範例所示:

val isCar = packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
if (isCar) {
    // Enable or disable a given feature
}

此外,如果您的應用程式也有 Android Auto 元件,則可使用 車輛專用 Android App Library 中的 CarConnection API 偵測應用程式是否在 Android Automotive OS 或 Android Auto 上執行,或是否未與任何車輛連線。

針對子母畫面 (PiP) 功能,請按照既定的最佳做法檢查該功能是否可用,並進行適當回應。

處理離線情況

雖然越來越多車輛都能連上網際網路,但仍建議您確保應用程式即使沒有網路連線也能執行,例如下列情況:

  • 使用者可能會選擇停用汽車製造商在訂閱套裝組合中提供的行動數據。
  • 部分地區的行動數據存取功能可能會受到限制。
  • 配備 Wi-Fi 無線電的車輛可能不在 Wi-Fi 訊號範圍內,或者原始設備製造商 (OEM) 可能停用 Wi-Fi 而改用行動網路。

為因應應用程式中的這些情境,請對需要網際網路連線的功能進行優雅降級,例如提供離線內容。詳情請參閱「最佳化網路的最佳做法」。

使用替代資源

為協助調整車輛應用程式,您可以在搭載 Android Automotive OS 的車輛上使用 car 資源限定詞,來提供替代資源。舉例來說,如果您使用維度資源來儲存邊框間距值,可以針對 car 資源集使用較大的值,讓觸控目標更大。