Personalize aplicativos

Agora que os componentes e recursos da biblioteca Car UI estão incluídos nos aplicativos, para personalizar esses aplicativos, os OEMs devem fornecer duas sobreposições:

  • A sobreposição de tempo de construção adiciona todos os recursos necessários para a sobreposição de recursos de tempo de execução (RROs). Isso inclui:

    • Drawables
    • Estilos (por exemplo, aparências de texto)
    • Recursos compartilhados (por exemplo, cores)
  • A pasta de sobreposição RRO contém os recursos usados ​​para gerar um RRO por aplicativo de destino. Esses recursos só podem se referir a:

    • Valores definidos dentro do mesmo RRO (por exemplo, para uma cor seria um valor hexadecimal).
    • Recursos da estrutura Android (por exemplo, @android:color/accent ).
    • Um recurso definido na sobreposição de tempo de construção acima.

Estrutura geral

A estrutura de sobreposição de personalização proposta é a seguinte:

  • <path-to-OEM-overlays>/

    • overlay/framework/base/core/res/ . Recursos de sobreposição em tempo de construção

    • rro/

      • Android.mk . Makefile usado para gerar os RROs para cada pacote de destino com base nos recursos contidos nesta pasta.

      • AndroidManifest.xml . Um modelo de arquivo de manifesto usado pelo makefile acima.

      • res/ . Sobreposições de tempo de execução para aplicar a todos os aplicativos de destino.

Os OEMs podem ter mais de uma dessas estruturas, dependendo do número de marcas que desejam manipular em um único destino de construção (consulte Lidar com diversas marcas ).

Sobreposições de recursos de tempo de execução

A pasta RRO na pasta de sobreposição OEM deve conter recursos a serem aplicados a todos os aplicativos de destino. Os RROs têm limitações que afectam a sua capacidade de sobrepor recursos compostos. Em resumo, um RRO:

  • Não é possível fazer referência a identificadores de recursos definidos no APK de destino ou no próprio RRO. Isso significa que os RROs não podem adicionar novos identificadores, como novos drawables, cores ou estilos.

  • Pode referem-se a identificadores de recursos definidos na estrutura, sejam esses recursos definidos em /frameworks/base/core/res ou por meio de uma sobreposição em tempo de construção. Esses identificadores devem ser referenciados usando o name-space android: ::

    • Para RROs DeviceDefault públicos , use android .
      Por exemplo, @android:style/TextAppearance.DeviceDefault.Large .

    • Para todos os outros (não públicos ou recursos adicionados por meio de sobreposição em tempo de compilação), use *android .
      Por exemplo, @*android/style:TextAppearance.OEM.Brand1.Title .

Além dos recursos, a pasta RRO deve conter:

  • AndroidManifest.xml . No exemplo abaixo, RRO_PACKAGE_NAME e TARGET_PACKAGE_NAME são espaços reservados para os makefiles:

    <?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 em que oem no makefile a seguir define o prefixo que todos os RROs gerados teriam.
      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
      

Configurar RROs

Um novo arquivo de configuração é suportado, overlayable.xml , que pode ser usado para definir controles de acesso. Por exemplo, você pode especificar quem pode sobrepor recursos, bem como quais recursos podem ser sobrepostos. Como resultado, os recursos podem agora ser agrupados de diferentes maneiras para disponibilizá-los para serem sobrepostos por diferentes RROs.

Para configurar o controle de acesso RRO:

  1. Na pasta res/values , crie overlayable.xml .
  2. Crie as tags de recursos <overlayable> .
  3. Defina o atributo name para a tag <overlayable> , que deve ser exclusivo no pacote. Cada sobreposição pode ter como alvo apenas um grupo de sobreposição.
  4. Defina a tag <policy> dentro de <overlayable> .
  5. Defina os grupos de recursos que podem ser sobrepostos. Por exemplo:
      <resources>
          <overlayable name="OverlayableResources">
              <policy type="public">
                  <item type="string" name="app_title" />
              </policy>
          </overlayable>
      </resources>
      

Para aplicar as seguintes alterações ao seu projeto RRO:

  1. Na pasta res/xml , crie overlays.xml . Veja a entrada no exemplo de código abaixo para overlay .
  2. Defina os recursos a serem substituídos.
  3. Adicione android:resourcesMap="@xml/overlays" à tag <overlay> em AndroidManifest.xml . Por exemplo, no exemplo de código abaixo, consulte a entrada para <overlay> .
  4. Defina android:isStatic=”true” para uma sobreposição estática. Cada sobreposição pode ter como alvo apenas um dos grupos que podem ser sobrepostos.

Considere o seguinte exemplo. A primeira seção pertence a AndroidManifest.xml enquanto a segunda seção pertence a 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>
  

Com uma ressalva, os RROs existentes anteriormente funcionam no Android 10. A ressalva é que, para serem instalados com o PackageManagerRRO, os pacotes devem ser pré-instalados ou assinados com a mesma chave do aplicativo de destino. No Android 10, os arquivos de layout podem ser sobrepostos. No entanto, fazer isso requer o uso de requireViewById() ao obter a visualização em vez de findViewById() . No Android 10, essa mudança foi implementada em car-ui-lib para oferecer suporte a sobreposições de layout.

A próxima grande versão do Android permitirá sobrepor um arquivo de layout e definir novos recursos no pacote RRO e consultá-los internamente.

Adicione recursos específicos de OEM

Para superar as limitações de RRO que impedem a adição de recursos OEM:

  • Estenda estruturas/base usando uma sobreposição de tempo de construção , adicionando quaisquer recursos necessários.
  • Consulte esses recursos dos RROs OEM usando *android: namespace.

Por exemplo, a seguir está uma maneira de adicionar um drawable específico do OEM e usá-lo em um 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>
        

Lidar com várias marcas

Os arquivos de manifesto RRO possuem uma sintaxe que permite que sejam aplicados condicionalmente com base nas propriedades do sistema. Para lidar com várias marcas em uma única imagem de sistema, os OEMs podem usar isso da seguinte maneira (consulte Estrutura geral ).

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

A sintaxe para android:requiredSystemPropertyName e android:requiredSystemPropertyValue faria com que esse RRO fosse ativado somente se a propriedade do sistema correspondente corresponder ao valor fornecido. Os OEMs podem então definir vários desses RROs, todos eles habilitados estaticamente e ter apenas um ativo por vez.

Adicionar biblioteca Car UI a um destino

Para incorporar a biblioteca Car UI a um destino Android, você deve incluir o seguinte snippet de código:

# 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 \
      ...
  • Faz com que <path-to-OEM-overlays>/rro/Android.mk gere um RRO para cada um dos pacotes nomeados em CAR_UI_RRO_PACKAGE_NAMES .

  • Inclui os RROs gerados em PRODUCT_PACKAGES .

  • Inclui uma sobreposição de tempo de construção em PRODUCT_PACKAGE_OVERLAYS para adicionar recursos específicos do OEM.

Para saber quais pacotes suportam car-ui-lib , consulte Lista de pacotes contendo car-ui-lib .