自訂應用程式

現在,汽車 UI 庫元件和資源已整合到應用程式中,為了自訂這些應用程序,OEM 必須提供兩個覆蓋層:

  • 建置時覆蓋新增運行時資源覆蓋 (RRO) 所需的任何資源。這包括:

    • 繪圖
    • 樣式(例如,文字外觀)
    • 共享資源(例如顏色)
  • RRO 覆蓋資料夾包含用於為每個目標應用程式產生一個 RRO 的資源。這些資源只能參考:

    • 在同一 RRO 中定義的值(例如,對於顏色,這將是十六進位值)。
    • Android 框架資源(例如@android:color/accent )。
    • 在上面的建置時覆蓋中定義的資源。

整體結構

建議的客製化覆蓋結構如下:

  • <path-to-OEM-overlays>/

    • overlay/framework/base/core/res/ 。建置時覆蓋資源

    • rro/

      • Android.mk 。 Makefile 用於根據此資料夾中包含的資源為每個目標包產生 RRO。

      • AndroidManifest.xml 。上述 makefile 使用的清單檔案範本。

      • res/ 。運行時覆蓋適用於所有目標應用程式。

OEM 可能擁有多個這些結構,具體取決於他們想要在單一建置目標中處理的品牌數量(請參閱處理多個品牌)。

運行時資源覆蓋

OEM 覆蓋資料夾中的 RRO 資料夾應包含要套用於所有目標應用程式的資源。 RRO 存在一些限制,影響其覆蓋複合資源的能力。總之,RRO:

  • 無法引用目標 APK 或 RRO 本身中定義的資源識別碼。這意味著 RRO 無法新增新的標識符,例如新的繪圖、顏色或樣式。

  • 引用框架中定義的資源標識符,無論這些資源是在/frameworks/base/core/res中定義還是透過建置時覆寫定義。這些標識符必須使用android:命名空間引用:

    • 對於公共DeviceDefault RRO,請使用android
      例如, @android:style/TextAppearance.DeviceDefault.Large

    • 對於所有其他資源(非公共資源或透過建置時覆蓋新增的資源),請使用*android
      例如, @*android/style:TextAppearance.OEM.Brand1.Title

除了資源之外,RRO 資料夾還必須包含:

  • AndroidManifest.xml 。在下面的範例中, RRO_PACKAGE_NAMETARGET_PACKAGE_NAME是 makefile 的佔位符:

    <?xml version=“1.0” encoding=“utf-8”?>
    <manifest xmlns:android=“http://schemas.android.com/apk/res/android”
        package=“{{RRO_PACKAGE_NAME}}” />
        <application android:hasCode=“false” />
        <overlay android:priority=“10”
            android:targetPackage=“{{TARGET_PACKAGE_NAME}}”
            android:requiredSystemPropertyName=“ro.product.sku”
            android:requiredSystemPropertyValue=“<your-product-sku>” />
    </manifest>
    
  • Android.mk ,其中以下 makefile 中的oem定義所有產生的 RRO 將具有的前綴。
      LOCAL_PATH := $(call my-dir)
      include $(CLEAR_VARS)
      CAR_UI_RRO_SET_NAME := oem
      CAR_UI_RESOURCE_DIR := $(LOCAL_PATH)/res
      CAR_UI_RRO_TARGETS := $(CAR_UI_RRO_PACKAGE_NAMES)
      include packages/apps/Car/libs/car-ui-lib/generate_rros.mk
      

配置 RRO

支援新的設定文件, overlayable.xml ,您可以使用它來定義存取控制。例如,您可以指定誰可以覆蓋資源以及可以覆蓋哪些資源。因此,現在可以以不同的方式對資源進行分組,以便可以由不同的 RRO 覆蓋。

設定 RRO 存取控制:

  1. res/values資料夾中,建立overlayable.xml
  2. 建立<overlayable>資源標籤。
  3. 定義<overlayable>標籤的name屬性,該屬性在套件中必須是唯一的。每個覆蓋只能定位一個可覆蓋組。
  4. <overlayable>內定義<policy>標記。
  5. 定義可以疊加的資源群組。例如:
      <resources>
          <overlayable name="OverlayableResources">
              <policy type="public">
                  <item type="string" name="app_title" />
              </policy>
          </overlayable>
      </resources>
      

若要將以下變更套用到您的 RRO 專案:

  1. res/xml資料夾中,建立overlays.xml 。請參閱下面程式碼範例中的overlay條目。
  2. 定義要覆蓋的資源。
  3. android:resourcesMap="@xml/overlays"加入AndroidManifest.xml中的<overlay>標記。例如,在下面的程式碼範例中,請參閱<overlay>條目。
  4. 設定android:isStatic=”true”為靜態覆蓋。每個覆蓋只能定位可覆蓋的群組之一。

考慮以下範例。第一部分屬於AndroidManifest.xml ,而第二部分屬於overlays.xml

  <manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.android.car.ui.rro"
      android:versionCode="1"
      android:versionName="1.0">
      <overlay android:targetName="OverlayableResources"
               android:resourcesMap="@xml/overlays"
               android:targetPackage="com.android.car.ui"
               android:priority="1"
               android:isStatic="false" />
  </manifest>
  <overlay>
      <item target="string/app_title" value="@ string/app_title" />
  </overlay>
  

有一點要注意的是,先前存在的 RRO 可在 Android 10 中使用。需要注意的是,要與 PackageManagerRRO 一起安裝,軟體包必須預先安裝或使用與目標應用程式相同的金鑰進行簽署。在Android 10中,佈局檔案可以疊加。但是,這樣做需要在取得視圖時使用requireViewById()而不是findViewById() 。在 Android 10 中,此變更已在 car-ui-lib 中實現,以支援佈局疊加。

Android 的下一個主要版本將使您能夠覆蓋佈局文件並在 RRO 包中定義新資源並在內部引用它們。

新增 OEM 特定資源

要克服阻止添加 OEM 資源的 RRO 限制:

  • 使用建置時覆蓋擴充框架/基礎,新增任何必要的資源。
  • 使用*android:命名空間從 OEM RRO 引用這些資源。

例如,以下是添加 OEM 特定可繪製物件並在 RRO 中使用它的方法:

  • <path-to-OEM-overlays>

    • overlay/framework/base/core/res/res/drawable/

      • oem_background_drawable.xml

    • rro/res/values

      • drawables.xml

        <resources>
            <item type="drawable" name="car_ui_toolbar_background">
                @*android:drawable/oem_background_drawable
            </item>
        </resources>
        

經營多個品牌

RRO 清單檔案具有允許根據系統屬性有條件地應用它們的語法。要在單一系統映像中處理多個品牌,OEM 可以如下使用它(請參閱一般結構)。

<?xml version=“1.0” encoding=“utf-8”?>
<manifest xmlns:android=“http://schemas.android.com/apk/res/android”
    package=“{{RRO_PACKAGE_NAME}}”/>
    <application android:hasCode=“false”/>
    <overlay android:priority=“10”
        android:targetPackage=“{{TARGET_PACKAGE_NAME}}”
        android:requiredSystemPropertyName=“ro.product.sku”
        android:requiredSystemPropertyValue=“<your-product-sku>”/>
</manifest>

android:requiredSystemPropertyNameandroid:requiredSystemPropertyValue語法將導致當對應的系統屬性與提供的值相符時啟用此 RRO。然後,OEM 可以定義多個 RRO,所有這些 RRO 均靜態啟用,並且一次只有一個處於活動狀態。

將汽車 UI 庫新增至目標

要將 Car UI 庫合併到 Android 目標中,您必須包含以下程式碼片段:

# Include build-time overlays
    PRODUCT_PACKAGE_OVERLAYS += \
      <path-to-oem-overlays>/overlay
    # Define package names to generate RROs for
    CAR_UI_RRO_PACKAGE_NAMES += \
      com.android.car.ui.paintbooth \
      com.android.car.media \
      com.android.car.dialer \
      com.android.car.linkviewer \
      com.android.car.settings \
      com.android.car.systemupdater \
      com.google.android.apps.automotive.inputmethod \
      com.google.android.apps.automotive.templates.host \
      ...
    # Include generated RROs
    PRODUCT_PACKAGES += \
      oem-com-android-car-ui-paintbooth \
      oem-com-android-car-media \
      oem-com-android-car-dialer \
      oem-com-android-car-linkviewer \
      oem-com-android-car-settings \
      oem-com-android-car-systemupdater \
      oem-com-google-android-apps-automotive-inputmethod \
      oem-com-google-android-apps-automotive-templates-host \
      ...
  • 導致<path-to-OEM-overlays>/rro/Android.mkCAR_UI_RRO_PACKAGE_NAMES中指定的每個套件產生一個 RRO。

  • 將產生的 RRO 包含在PRODUCT_PACKAGES中。

  • PRODUCT_PACKAGE_OVERLAYS中包含建置時覆蓋,以新增特定於 OEM 的資源。

若要了解哪些軟體套件支援car-ui-lib ,請參閱包含 car-ui-lib 的軟體包清單