Tuỳ chỉnh ứng dụng

Giờ đây, các thành phần và tài nguyên của thư viện Giao diện người dùng ô tô đã có trong ứng dụng, để tuỳ chỉnh những ứng dụng này, OEM phải cung cấp 2 lớp phủ:

  • Lớp phủ thời gian xây dựng thêm mọi tài nguyên cần thiết cho lớp phủ tài nguyên thời gian chạy (RRO). Trong đó có:

    • Đối tượng có thể vẽ
    • Kiểu (ví dụ: giao diện văn bản)
    • Tài nguyên dùng chung (ví dụ: màu sắc)
  • Thư mục RRO lớp phủ chứa các tài nguyên được dùng để tạo một RRO cho mỗi ứng dụng mục tiêu. Những tài nguyên này chỉ có thể đề cập đến:

    • Các giá trị được xác định trong cùng một RRO (ví dụ: đối với một màu, giá trị này sẽ là giá trị thập lục phân giá trị).
    • Tài nguyên khung Android (ví dụ: @android:color/accent).
    • Tài nguyên được xác định trong lớp phủ thời gian xây dựng ở trên.

Cấu trúc chung

Cấu trúc lớp phủ tuỳ chỉnh được đề xuất như sau:

  • <path-to-OEM-overlays>/

    • overlay/framework/base/core/res/. Tài nguyên về lớp phủ trong thời gian xây dựng

    • rro/

      • Android.mk. Makefile được dùng để tạo RRO cho mỗi gói mục tiêu dựa trên các tài nguyên có trong thư mục này.

      • AndroidManifest.xml. Mẫu tệp kê khai được sử dụng ở trên makefile.

      • res/. Lớp phủ trong thời gian chạy để áp dụng cho tất cả ứng dụng mục tiêu.

OEM có thể có nhiều cấu trúc trong số này, tuỳ thuộc vào số lượng thương hiệu mà họ muốn xử lý trong một mục tiêu bản dựng duy nhất (xem Xử lý nhiều thương hiệu).

Lớp phủ tài nguyên trong thời gian chạy

Thư mục RRO trong thư mục lớp phủ OEM phải chứa tài nguyên sẽ áp dụng cho tất cả ứng dụng đích. RRO có những hạn chế ảnh hưởng đến khả năng phủ lên các tài nguyên phức hợp. Tóm lại, RRO:

  • Không thể tham chiếu đến giá trị nhận dạng tài nguyên được xác định trong APK mục tiêu hoặc trong RRO. Tức là RRO không thể thêm các giá trị nhận dạng mới, chẳng hạn như đối tượng có thể vẽ, màu sắc hoặc kiểu.

  • Có thể tham khảo giá trị nhận dạng tài nguyên được xác định trong khung, cho dù các tài nguyên đó được xác định trong /frameworks/base/core/res hay bằng phương tiện của lớp phủ thời gian xây dựng. Các giá trị nhận dạng này phải được tham chiếu bằng android: không gian tên:

    • Đối với RRO công khai của DeviceDefault, hãy sử dụng android.
      Ví dụ: @android:style/TextAppearance.DeviceDefault.Large.

    • Dành cho tất cả những người khác (không công khai hoặc các tài nguyên được thêm qua lớp phủ thời gian xây dựng), sử dụng *android.
      Ví dụ: @*android/style:TextAppearance.OEM.Brand1.Title.

Ngoài các tài nguyên, thư mục RRO phải chứa:

  • AndroidManifest.xml. Trong mẫu bên dưới, RRO_PACKAGE_NAMETARGET_PACKAGE_NAME là phần giữ chỗ cho các tệp 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, trong đó oem trong tệp makefile sau đây xác định tiền tố mà tất cả các RRO được tạo sẽ có.
      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
      

Định cấu hình RRO

Tệp cấu hình mới được hỗ trợ, overlayable.xml và bạn có thể sử dụng tệp này để xác định các chế độ kiểm soát quyền truy cập. Ví dụ: bạn có thể chỉ định ai có thể phủ tài nguyên cũng như tài nguyên nào có thể phủ lên trên. Do đó, hiện có thể nhóm các tài nguyên theo nhiều cách để khiến chúng có thể phủ lên trên nhiều RRO.

Để thiết lập tính năng kiểm soát quyền truy cập RRO, hãy làm như sau:

  1. Trong thư mục res/values, hãy tạo overlayable.xml.
  2. Tạo các thẻ tài nguyên <overlayable>.
  3. Xác định thuộc tính name cho thẻ <overlayable>. phải là duy nhất trong gói. Mỗi lớp phủ chỉ có thể nhắm mục tiêu đến một nhóm có thể phủ.
  4. Xác định thẻ <policy> bên trong <overlayable>.
  5. Xác định các nhóm tài nguyên có thể phủ lên trên. Ví dụ:
      <resources>
          <overlayable name="OverlayableResources">
              <policy type="public">
                  <item type="string" name="app_title" />
              </policy>
          </overlayable>
      </resources>
      

Cách áp dụng các thay đổi sau cho dự án RRO:

  1. Trong thư mục res/xml, hãy tạo overlays.xml. Xem mục nhập trong mã mẫu bên dưới cho overlay.
  2. Xác định các tài nguyên cần ghi đè.
  3. Thêm android:resourcesMap="@xml/overlays" vào <overlay> trong AndroidManifest.xml. Ví dụ: trong mã mẫu bên dưới, hãy xem mục nhập cho <overlay> .
  4. Đặt android:isStatic=”true” cho lớp phủ tĩnh. Mỗi lớp phủ chỉ có thể nhắm mục tiêu một trong các nhóm có thể phủ lên trên.

Hãy xem ví dụ sau đây. Phần đầu tiên thuộc về AndroidManifest.xml còn phần thứ hai liên quan đến 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>
  

Một lưu ý là các RRO hiện có trước đây sẽ hoạt động trong Android 10. Lưu ý là được cài đặt bằng PackageManagerRRO, các gói phải được cài đặt trước hoặc ký bằng chính khoá của ứng dụng đích. Trong Android 10, bạn có thể phủ các tệp bố cục. Tuy nhiên, để làm như vậy, bạn sẽ phải sử dụng requireViewById() trong khi tải khung hiển thị thay vì findViewById() Trong Android 10, thay đổi này đã được triển khai cho car-ui-lib để và hỗ trợ lớp phủ bố cục.

Bản phát hành chính tiếp theo của Android sẽ cho phép bạn phủ tệp bố cục và xác định các tài nguyên mới trong gói RRO và tham chiếu nội bộ chúng.

Thêm tài nguyên dành riêng cho OEM (Nhà sản xuất thiết bị gốc)

Cách khắc phục các hạn chế về RRO khiến tài nguyên của OEM không được thêm vào:

  • Mở rộng khung/cơ sở bằng cách sử dụng lớp phủ thời gian xây dựng, thêm mọi thông tin cần thiết của chúng tôi.
  • Tham khảo các tài nguyên này từ RRO của OEM bằng cách sử dụng không gian tên *android:.

Ví dụ: sau đây là cách thêm một đối tượng có thể vẽ cụ thể của OEM và sử dụng đối tượng đó trong 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>
        

Xử lý nhiều thương hiệu

Tệp kê khai RRO có cú pháp để cho phép áp dụng có điều kiện dựa trên hệ thống các thuộc tính. Để xử lý nhiều thương hiệu trong một hình ảnh hệ thống duy nhất, OEM có thể sử dụng giá trị này làm như sau (xem Cấu trúc chung).

<?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>

Cú pháp cho android:requiredSystemPropertyNameandroid:requiredSystemPropertyValue sẽ khiến RRO này chỉ bật nếu thuộc tính hệ thống tương ứng khớp với giá trị đã cho. Sau đó, OEM có thể xác định bội số của các RRO này, tất cả đều được bật theo phương thức tĩnh và chỉ có một RRO hoạt động tại một thời điểm.

Thêm thư viện Giao diện người dùng trên ô tô vào một mục tiêu

Để tích hợp thư viện Giao diện người dùng ô tô vào một mục tiêu Android, bạn phải thêm đoạn mã sau:

# 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 \
      ...
  • Nguyên nhân <path-to-OEM-overlays>/rro/Android.mk tạo ra một RRO cho mỗi nguyên nhân của các gói có tên trong CAR_UI_RRO_PACKAGE_NAMES.

  • Bao gồm các RRO đã tạo trong PRODUCT_PACKAGES.

  • Thêm lớp phủ thời gian xây dựng trong PRODUCT_PACKAGE_OVERLAYS để thêm thông tin dành riêng cho OEM của chúng tôi.

Để tìm hiểu gói nào hỗ trợ car-ui-lib, hãy xem Danh sách các gói chứa car-ui-lib.