在範本應用程式中新增對 Android Automotive OS 的支援

Android Automotive OS 可讓使用者在車輛中安裝應用程式。為觸及這個平台的使用者,您必須發布專為駕駛人設計且與 Android Automotive OS 相容的應用程式。您可以重複使用 Android Auto 應用程式中絕大部分的程式碼和資源,但必須建立符合本頁所述規定的獨立版本。

如要在 Android Automotive OS 上執行車輛應用程式,請務必安裝最新版的 Templates Host 系統應用程式。

開發作業總覽

新增對 Android Automotive OS 的支援只需完成幾個步驟,如本頁各節所述:

  1. 建立車用模組
  2. 宣告支援 Android Automotive OS
  3. 宣告 CarAppServiceCarAppActivity
  4. 更新 Gradle 依附元件

使用 Android Studio Bumblebee 以上版本,確保已啟用所有 Automotive OS 功能。

建立車用模組

Android Automotive OS 的部分元件 (例如資訊清單) 對於作業平台有一定的要求。您建立的模組必須能夠區隔這些元件的程式碼與專案中的其他程式碼 (例如用於手機應用程式的程式碼)。

如要在現有專案中新增汽車模組,請按照下列步驟進行:

  1. 在 Android Studio 中,依序點選「File」>「New」>「New Module」
  2. 選取「Automotive Module」,然後點選「Next」
  3. 提供「Application/Library name」。這是使用者會在 Android Automotive OS 上看到的應用程式名稱。
  4. 輸入「Module name」
  5. 依據現有應用程式編輯「Package name」
  6. 將「Minimum SDK」設為「API 29: Android 10 (Q)」,然後點選「Next」。所有支援 Android Automotive OS Car App Library 的車輛均搭載 Android 10 API 級別 29 以上版本,因此選取這個值就能指定所有相容的車輛。

  7. 選取「Add No Activity」,然後按一下「Finish」

如要新建專案:

  1. 在 Android Studio 中,依序選取「File」>「New」>「New Project」
  2. 在「Project Type」中選取「Automotive」
  3. 選取「No Activity」,然後點選「Next」
  4. 在「Name」中設定專案名稱。這是使用者會在 Android Automotive OS 上看到的應用程式名稱。
  5. 在「Package name」中輸入套件名稱。如要進一步瞭解如何選取套件名稱,請參閱「套件名稱」一節。
  6. 將「Minimum SDK」設為「API 29: Android 10 (Q)」,然後點選「Next」

    所有支援 Android Automotive OS Car App Library 的車輛均搭載 Android 10 API 級別 29 以上版本,因此選取這個值就能指定所有相容的車輛。

在 Android Studio 中建立模組後,請在新的車用模組中開啟 AndroidManifest.xml 檔案:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.car.app">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme" />

    <uses-feature
        android:name="android.hardware.type.automotive"
        android:required="true" />

</manifest>

application 元素提供一些標準應用程式資訊,以及宣告支援 Android Automotive OS 的 uses-feature 元素。請注意,資訊清單中未宣告任何活動。

下一步,將下列 uses-feature 元素新增至資訊清單:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.car.app">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme" />

    <uses-feature
        android:name="android.hardware.type.automotive"
        android:required="true" />
    <uses-feature
        android:name="android.software.car.templates_host"
        android:required="true" />

    <uses-feature
        android:name="android.hardware.wifi"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.screen.portrait"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.screen.landscape"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.camera"
        android:required="false" />

</manifest>

第一個 uses-feature 元素會宣告應用程式使用 Templates Host 執行。將剩餘的四個 uses-feature 元素明確設為 required="false",可確保應用程式不會與 Android Automotive OS 裝置上的可用硬體功能發生衝突。

更新 Gradle 依附元件

在汽車模組中,您必須為 androidx.car.app:app-automotive 外掛程式新增依附元件,其中包含應用程式在 Android Automotive OS 上執行所需的 CarAppActivity 實作項目。

如果您開發的應用程式同時支援 Android Auto 和 Android Automotive OS,建議您將 CarAppService 存放在可供行動裝置和車用模組共用的獨立模組中。如要使用這個方法,您必須更新車用模組,以便使用 Gradle 的專案依附元件加入共用模組,如以下程式碼片段所示:

Groovy

buildscript {
    ...
    dependencies {
        ...
        implementation "androidx.car.app:app-automotive:car_app_library_version"
        implementation project(':shared_module_name')
    }
}

Kotlin

buildscript {
    ...
    dependencies {
        ...
        implementation("androidx.car.app:app-automotive:car_app_library_version")
        implementation(project(":shared_module_name"))
    }
}

宣告支援 Android Automotive OS

使用下列資訊清單項目宣告您的應用程式支援 Android Automotive OS:

<application>
    ...
    <meta-data android:name="com.android.automotive"
        android:resource="@xml/automotive_app_desc"/>
    ...
</application>

這個資訊清單項目參照的 XML 檔案會宣告應用程式支援的汽車功能。

如要表示您擁有 Car App Library 應用程式,請在 Android Automotive OS 模組的 res/xml/ 目錄中新增名為 automotive_app_desc.xml 的 XML 檔案。此檔案應包含下列內容:

<automotiveApp>
    <uses name="template"/>
</automotiveApp>

宣告您的 CarAppService 和 CarAppActivity

與 Android Auto 一樣,Android Automotive OS 會使用您的 CarAppService 實作來執行應用程式。如要瞭解如何實作及宣告 CarAppService,請參閱「建立 CarAppService 與工作階段」和「宣告 CarAppService」。

與 Android Auto 不同,您必須加入額外的應用程式元件 (CarAppActivity),做為 Android Automotive OS 應用程式的進入點。此活動的實作內容包含在 androidx.car.app:app-automotive 構件中,負責與範本主機應用程式通訊,以轉譯應用程式的 UI。資訊清單中應只包含一個此活動的例項,且必須宣告如下:

<activity
    android:exported="true"
    android:theme="@android:style/Theme.DeviceDefault.NoActionBar"
    android:name="androidx.car.app.activity.CarAppActivity"
    android:launchMode="singleTask"
    android:label="Your app name">

    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>

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

</activity>
  • android:name 會設為 app-automotive 構件中 CarAppActivity 類別的完整類別名稱。
  • android:exported 設為 true,因為活動必須由自身以外的應用程式 (即啟動器) 啟動。
  • android:launchMode 設為 singleTask,因此使用者在離開啟動器後,可以返回活動的相同例項。
  • android:theme 設為 @android:style/Theme.DeviceDefault.NoActionBar,讓應用程式占用可用的全螢幕空間。
  • 意圖篩選器表示這是應用程式的啟動器活動。
  • <meta-data> 元素會向 OS 指出,應用程式可以在使用者體驗限制生效時使用,例如車輛行駛時。

對於導航應用程式,CarAppActivity 需要更多資訊清單項目,如以下程式碼片段所示:

<activity
    android:exported="true"
    android:theme="@android:style/Theme.DeviceDefault.NoActionBar"
    android:name="androidx.car.app.activity.CarAppActivity"
    android:launchMode="singleTask"
    android:label="Your app name">

    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
        <!-- Include the category below ONLY for navigation apps -->
        <category android:name="android.intent.category.APP_MAPS" />
    </intent-filter>

    <!-- Include the intent-filter below ONLY for navigation apps -->
    <intent-filter>
        <action android:name="androidx.car.app.action.NAVIGATE" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:scheme="geo" />
    </intent-filter>

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

</activity>
  • 額外的 android.intent.category.APP_MAPS 類別會通知系統,您的應用程式能夠顯示使用者的位置。
  • androidx.car.app.action.NAVIGATE 意圖篩選器可確保使用者在處理其他車輛應用程式提供的隱含導航意圖時,可以選擇使用您的應用程式。

其他考量

開發 Android Automotive OS 應用程式時,請考量下列幾點:

套件名稱

由於您發布了 Android Automotive OS 專用的獨立 Android 應用程式套件 (APK),因此可以重複使用您行動應用程式中的套件名稱,或者建立新的套件名稱。如果您使用其他套件名稱,應用程式會有兩筆獨立的 Play 商店資訊。若重複使用既有套件名稱,應用程式則會在兩個平台共用同一筆商店資訊。

您可以依據業務考量決定採用哪一種做法。舉例來說,假設您有一個團隊負責開發行動應用程式,而另一個獨立的團隊負責開發 Android Automotive OS 應用程式,就非常適合使用不同的套件名稱,讓兩個團隊各自管理自己的 Play 商店資訊。無論採用哪一種方式,在技術上所需投入的人力差異不大。

下表摘要說明保留既有套件名稱與使用新套件名稱之間的其他主要差異:

功能 相同套件名稱 新建套件名稱
商店資訊 單個 多個
鏡像安裝 是:在設定精靈中快速重新安裝應用程式
Play 商店審核程序 封鎖審查:如果其中一個 APK 未通過審查,透過同一個版本提交的其他 APK 會一併遭到封鎖 個別審查
統計資料、指標和 Android Vitals 合併:您可以依裝置名稱篩選汽車專屬資料。 分用
建立索引和搜尋排名 依據現有記錄建立 不會沿用
與其他應用程式整合 通常無須變更 (假設兩個 APK 共用同一組媒體程式碼) 可能需要更新對應的應用程式 (例如透過 Google 助理執行 URI 播放)

離線內容

在適用情況下,請為應用程式實作支援離線使用功能。一般來說,搭載 Android Automotive OS 的車輛應具備專屬的數據連線,也就是內含於車輛費用或使用者付費的數據方案。不過,與行動裝置相較,車輛也應提供更多樣化的連線方式。

將支援離線使用策略納入考量時,請留意下列事項:

  • 應用程式正在使用的當下是下載內容的最佳時機。
  • 請勿假設有可供使用的 Wi-Fi。車輛可能未進入 Wi-Fi 訊號範圍內,或者原始設備製造商 (OEM) 可能偏好使用行動網路,因而停用了 Wi-Fi。
  • 儘管可以使用智慧型快取機制,下載您預期使用者會使用的內容,我們仍建議您讓使用者變更這項行為。
  • 車輛上的磁碟空間各有不同,因此請讓使用者能夠透過特定方式刪除離線內容。

常見問題

以下各節提供 Android Automotive OS 常見問題的解答。

使用第三方 SDK 和程式庫是否有任何限制或建議?

我們並未針對第三方 SDK 和程式庫制定具體的使用規範。如果選擇使用第三方 SDK 和程式庫,您仍須遵守所有汽車應用程式品質規定。

如何使用 Google Play 管理中心發布 Android Automotive OS 應用程式?

如要進一步瞭解如何透過 Google Play 管理中心發布 Android Automotive OS 應用程式,請參閱「發布至車輛」一文。

疑難排解

請參閱下文,瞭解常見的 Android Automotive OS 疑難排解情境。

  • 即使已從系統設定解除安裝 Car App Library 應用程式,嘗試安裝新的版本時仍收到錯誤訊息。

    如要確保應用程式已解除安裝,請使用 adb uninstall app.package.name 指令。