Integrationsleitfaden für OEMs

Auf dieser Seite wird beschrieben, wie Sie Drehknopf-Eingaben in der VHAL verarbeiten, Ihren Build so konfigurieren, dass der Drehknopfdienst enthalten ist, und wie Sie die Drehknopf-Funktion für alle Apps anpassen. Informationen zu vorinstallierten OEM-Apps, z. B. einem vom OEM bereitgestellten Launcher, finden Sie unter Auto-UI-Mediathek (car-ui-library).

VHAL

Ein Drehregler unterstützt die folgenden Aktionen:

  • Bewegen Sie den Cursor nach oben, unten, links und rechts.
  • Drehen Sie den Ring im Uhrzeigersinn und gegen den Uhrzeigersinn.
  • Drücken Sie die Mitteltaste.
  • Drücken Sie die Schaltfläche „Zurück“.
  • Drücken Sie die Startbildschirmtaste.
  • Drücken Sie andere Tasten wie „Telefon“ und „Medien“.

In hardware/interfaces/automotive/vehicle/2.0/types.hal finden Sie Informationen zu den Systemeigenschaften und den entsprechenden int32Values.

Der VHAL sollte folgende Aktionen ausführen:

Anstupsen

Wenn der Nutzer den Drehregler nach rechts drückt, sollte die VHAL die Eigenschaft HW_KEY_INPUT mit dem folgenden int32Values verwenden, um ein Ereignis an Android zu senden:

  1. ACTION_DOWN
  2. KEYCODE_SYSTEM_NAVIGATION_RIGHT
  3. Display auswählen.

Wenn der Nutzer den Drehregler loslässt, sollte die VHAL dieselbe Property und denselben Schlüsselcode mit ACTION_UP verwenden. Für Nudges in andere Richtungen sollten die entsprechenden Tastencodes verwendet werden.

Es gibt keine Tastencodes für Diagonalen. Die VHAL kann jedoch ein horizontales und ein vertikales Ereignis kombinieren, um eine Diagonale zu erzeugen, wenn die Hardware Diagonalen unterstützt. Wenn Sie beispielsweise nach oben und nach links wischen, sollte Folgendes angezeigt werden:

  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_DOWN
  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_DOWN

In beiden Fällen sollte das Loslassen des Drehreglers folgende Auswirkungen haben:

  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_UP
  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_UP

Der Nutzer kann den Drehregler in einer senkrechten Richtung drücken, bevor er ihn loslässt. Beispiel:

Senkrechte Richtung
Abbildung 1 Senkrechte Richtung

Dies sollte die folgende Abfolge von Ereignissen generieren:

  1. HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_DOWN
  2. HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_DOWN
  3. HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_UP
  4. HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_UP

Es sollten keine Wiederhol-Ereignisse generiert werden, während der Drehregler in eine Richtung gehalten wird.

Drehen

Wenn der Nutzer den Drehregler um eine Rastung (Klick) im Uhrzeigersinn dreht, sollte die VHAL die Eigenschaft HW_ROTARY_INPUT mit der folgenden int32Values verwenden, um ein Ereignis an Android zu senden:

  1. ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
  2. Eine (1) Rastung.
  3. Display auswählen.

Der Zeitstempel des Ereignisses sollte auf die verstrichene Zeit in Nanosekunden festgelegt werden.

Eine Drehung um eine Rastung gegen den Uhrzeigersinn sollte dasselbe Ereignis generieren, aber mit -1 für die Anzahl der Rastungen.

Wenn mehrere Rastungen in derselben Richtung in schneller Folge auftreten, sollte der VHAL die Rastungen zu einem einzigen Ereignis kombinieren, um das System nicht mit Ereignissen zu überlasten. In diesem Fall sollte der Zeitstempel des Ereignisses der Zeitpunkt sein, zu dem die erste Rastung der Drehung aufgetreten ist. Die int32Values sollte die Anzahl der Nanosekunden zwischen aufeinanderfolgenden Raststellungen der Drehung enthalten.

Beispiel:

  • Zum Zeitpunkt t0 hat der Nutzer den Knopf um eine Rastung gegen den Uhrzeigersinn gedreht.
  • Um t0 + 5 ns hat der Nutzer den Knopf um eine Rastung gegen den Uhrzeigersinn gedreht.
  • Um t0 + 8 ns hat der Nutzer den Knopf um eine Rastung gegen den Uhrzeigersinn gedreht.

sollte dieses Ereignis generieren:

  • Property: HW_ROTARY_INPUT
  • Zeitstempel: t0
  • int32Values:
    1. ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
    2. -3 (drei Rastungen gegen den Uhrzeigersinn)
    3. Display auswählen.
    4. 5 ns zwischen erster und zweiter Rastung.
    5. 3 ns zwischen zweitem und drittem Rastpunkt.

Mitteltaste

Wenn der Nutzer die mittlere Schaltfläche drückt, sollte die VHAL die HW_KEY_INPUT-Property mit dem folgenden int32Values verwenden, um ein Ereignis an Android zu senden:

  1. ACTION_DOWN
  2. KEYCODE_DPAD_CENTER
  3. Display auswählen.

Wenn der Nutzer den Drehregler loslässt, sollte die VHAL dieselbe Property und denselben Schlüsselcode mit ACTION_UP verwenden.

Generieren Sie keine Wiederhol-Ereignisse, wenn die mittlere Taste gedrückt gehalten wird.

Schaltfläche „Zurück“

Wenn der Nutzer die Schaltfläche „Zurück“ drückt, sollte die VHAL die HW_KEY_INPUT-Property mit dem folgenden int32Values verwenden, um ein Ereignis an Android zu senden:

  1. ACTION_DOWN
  2. KEYCODE_BACK
  3. Display auswählen.

Wenn der Nutzer den Drehregler loslässt, sollte die VHAL dieselbe Property und denselben Schlüsselcode mit ACTION_UP verwenden.

Während die mittlere Taste gedrückt gehalten wird, sollten keine Wiederhol-Ereignisse generiert werden.

Startbildschirmtaste

Verwenden Sie die Startbildschirmtaste wie die Schaltfläche „Zurück“, aber mit KEYCODE_HOME anstelle von KEYCODE_BACK.

Andere Tasten

Wenn der Drehregler zusätzliche Tasten hat, kann der VHAL diese nach Belieben des OEMs verarbeiten, da sie aus Sicht von Android nicht als Teil des Drehreglers betrachtet werden. Sie werden in der Regel wie die Schaltflächen „Zurück“ und „Startseite“ behandelt, haben aber andere Tastencodes. Beispiel: KEYCODE_CALL oder KEYCODE_MUSIC.

Build-Konfiguration

Die Drehknopfnavigation wird von einer Bedienungshilfe namens RotaryService bereitgestellt. Wenn Sie diesen Dienst in das System-Image für Ihr Gerät aufnehmen möchten, fügen Sie Ihrer Makefile-Datei die folgende Zeile hinzu:

PRODUCT_PACKAGES += CarRotaryController

Sie können auch die folgenden Pakete in Debug-Builds einschließen:

Der Drehknopfdienst wird automatisch aktiviert, wenn das Gerät gestartet wird und wenn ein Nutzerwechsel stattfindet. So kann der Nutzer den Drehregler während der Einrichtung verwenden.

Wenn Sie denselben Build für Autos mit und ohne Drehregler verwenden, fügen Sie CarRotaryController wie oben gezeigt hinzu, damit der erforderliche Code in den Build aufgenommen wird. Wenn Sie verhindern möchten, dass der Dienst für Kreisverkehre für Fahrzeuge ohne Kreisverkehr aktiviert wird, erstellen Sie eine statische RRO, um die Stringressource rotaryService in packages/services/Car/service mit einem leeren String zu überlagern. Sie verwenden dieselbe Version, aber separate Produktkonfigurationen für Geräte mit und ohne Drehknopf. Nur Letztere enthält das Overlay.

Personalisierung

OEMs können die Logik für die Fokussuche, die Fokusmarkierung und einige weitere Elemente an den folgenden Stellen über Ressourcen-Overlays anpassen:

  • car-ui-library befindet sich in packages/apps/Car/libs/car-ui-lib
  • RotaryService befindet sich in packages/apps/Car/RotaryController
  • Core befindet sich in frameworks/base/core

Verlauf der automatischen Erinnerungen

Der OEM kann konfigurieren, ob die beiden Arten von Nudge-Verlauf aktiviert sind und, falls ja, die Cache-Größe und die Ablaufrichtlinie. Dazu werden verschiedene Ressourcen der car-ui-library überschrieben.

Cache für den Fokusverlauf

(Android 11 QPR3, Android 11 Car, Android 12)
In diesem Cache für FocusArea wird die zuletzt fokussierte Ansicht im FocusArea gespeichert, damit sie beim Zurückwechseln zum FocusArea wieder fokussiert werden kann. Dieser Cache kann konfiguriert werden, indem die folgenden car-ui-library-Ressourcen überlagert werden:

  • car_ui_focus_history_cache_type:
    1. Der Cache ist deaktiviert.
    2. Der Cache läuft nach einiger Zeit ab (siehe unten).
    3. Der Cache läuft nie ab.
  • car_ui_focus_history_expiration_period_ms: Gibt an, nach wie vielen Millisekunden der Cache abläuft, wenn der Cachetyp auf „2“ (siehe oben) gesetzt ist.

Cache für den Fokusbereich-Verlauf

(Android 11 QPR3, Android 11 Auto, Android 12)
In diesem Cache wird ein Verlauf von Richtungsänderungen gespeichert, damit der Fokus durch eine Richtungsänderung in die entgegengesetzte Richtung wieder auf dasselbe Element FocusArea gelenkt werden kann. Dieser Cache kann konfiguriert werden, indem die folgenden car-ui-library-Ressourcen überlagert werden:

  • car_ui_focus_area_history_cache_type:
    1. Der Cache ist deaktiviert.
    2. Der Cache läuft nach einiger Zeit ab (siehe unten).
    3. Der Cache läuft nie ab.
  • car_ui_focus_area_history_expiration_period_ms: Gibt an, nach wie vielen Millisekunden der Cache abläuft, wenn der Cachetyp auf „2“ gesetzt ist (siehe oben).
  • car_ui_clear_focus_area_history_when_rotating: Gibt an, ob der Cache gelöscht werden soll, wenn der Nutzer den Controller dreht.

Ausrichtung

(Android 11 QPR3, Android 11 Car, Android 12)
Der OEM kann zwei Ganzzahlressourcen in der RotaryService überschreiben, um anzugeben, ob es eine Beschleunigung für die Drehung gibt, z. B. eine Mausbeschleunigung:

  • rotation_acceleration_3x_ms: Zeitintervall (in Millisekunden), anhand dessen entschieden wird, ob Google die Controller-Drehung für eine Raststellung beschleunigen soll. Wenn das Intervall zwischen dieser Raststellung und der vorherigen Raststellung der Drehung kleiner als dieser Wert ist, wird sie als drei Raststellungen der Drehung behandelt. Legen Sie diesen Wert auf 2147483647 fest, um die dreifache Beschleunigung zu deaktivieren.
  • rotation_acceleration_2x_ms: Ähnlich wie rotation_acceleration_3x_ms. Wird für eine doppelte Beschleunigung verwendet. Legen Sie hier 2147483647 fest, um die doppelte Beschleunigung zu deaktivieren.

Die Beschleunigung funktioniert am besten, wenn es für jede Raststellung der Drehung individuelle Zeitstempel gibt, wie vom VHAL erforderlich. Wenn diese nicht verfügbar sind, wird in RotaryService davon ausgegangen, dass die Rasten der Drehung gleichmäßig verteilt sind.

/**
     * Property to feed H/W rotary events to android
     *
     * int32Values[0] : RotaryInputType identifying which rotary knob rotated
     * int32Values[1] : number of detents (clicks), positive for clockwise,
     *                  negative for counterclockwise
     * int32Values[2] : target display defined in VehicleDisplay. Events not
     *                  tied to specific display must be sent to
     *                  VehicleDisplay#MAIN.
     * int32values[3 .. 3 + abs(number of detents) - 2]:
     *                  nanosecond deltas between pairs of consecutive detents,
     *                  if the number of detents is > 1 or < -1
     *
     * VehiclePropValue.timestamp: when the rotation occurred. If the number of
     *                             detents is > 1 or < -1, this is when the
     *                             first detent of rotation occurred.
     *
     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
     * @data_enum RotaryInputType
     * @access VehiclePropertyAccess:READ
     */
    HW_ROTARY_INPUT = (
        0x0A20
        | VehiclePropertyGroup:SYSTEM
        | VehiclePropertyType:INT32_VEC
        | VehicleArea:GLOBAL),

Fokus hervorheben

Der OEM kann das standardmäßige Fokus-Highlight im Android-Framework und mehrere Fokus-Highlight-Ressourcen in der car-ui-library überschreiben.

Standard-Fokus hervorheben

Das Android-Framework bietet über das Attribut selectableItemBackground eine standardmäßige Fokus-Hervorhebung. In Theme.DeviceDefault bezieht sich dieses Attribut auf item_background.xml in Core. Der OEM kann item_background.xml überlagern, um das standardmäßige Zeichnen des Fokus hervorzuheben.

Dieses drawable sollte in der Regel ein StateListDrawable sein, das den Hintergrund anhand verschiedener Kombinationen von Status anpasst, einschließlich android:state_focused und android:state_pressed. Wenn der Nutzer den Drehregler verwendet, um den Fokus auf eine Ansicht zu legen, ist android:state_focused = true, aber android:state_pressed = false. Wenn der Nutzer dann die Mitteltaste am Drehregler drückt, sind sowohl android:state_focused als auch android:state_pressed true, solange er die Taste gedrückt hält. Wenn der Nutzer die Schaltfläche loslässt, bleibt nur android:state_focusedtrue übrig.

In der car-ui-library wird ein von Theme.DeviceDefault abgeleitetes Design verwendet. Daher wirkt sich dieses Overlay auf Apps aus, die diese Bibliothek verwenden, und auf Apps, die ein daraus abgeleitetes Design verwenden.Theme.DeviceDefault Apps, die ein anderes Design verwenden, sind davon nicht betroffen, z. B. Theme.Material.

Ressourcen für den Fokus hervorheben in der car-ui-library

Der OEM kann mehrere Ressourcen der Car-UI-Bibliothek überschreiben, um festzulegen, wie der Fokus hervorgehoben wird, wenn die Ansicht nicht rechteckig ist (z. B. rund oder oval) und in Apps, die ein nicht von Theme.DeviceDefault abgeleitetes Design verwenden. Diese Ressourcen sollten überlagert werden, damit die Akzentfarbe für den Fokus mit dem drawable-Element default focus highlight übereinstimmt.

(Android 11 QPR3, Android 11 Car, Android 12)
Die folgenden Ressourcen werden verwendet, um anzugeben, dass eine Ansicht zwar den Fokus hat, aber nicht gedrückt wird:

  • car_ui_rotary_focus_fill_color: Füllfarbe.
  • car_ui_rotary_focus_stroke_color: Umrissfarbe.
  • car_ui_rotary_focus_stroke_width: Dicke des Umrisses.

(Android 11 QPR3, Android 11 Auto, Android 12)
Die folgenden Ressourcen geben an, wann eine Ansicht und gedrückt wird:

  • car_ui_rotary_focus_pressed_fill_color: Füllfarbe.
  • car_ui_rotary_focus_pressed_stroke_color: Umrissfarbe.
  • car_ui_rotary_focus_pressed_stroke_width: Dicke des Umrisses.

Manchmal wird einer Schaltfläche eine durchgehende Hintergrundfarbe zugewiesen, um die Aufmerksamkeit der Nutzer darauf zu lenken, wie im Beispiel gezeigt. Dadurch ist der Fokusbereich möglicherweise schwer zu erkennen.

Schaltfläche mit durchgehendem Hintergrund
Abbildung 2. Schaltfläche mit durchgehender Farbe

In diesem Fall kann der Entwickler mithilfe von sekundären Farben ein benutzerdefiniertes Fokus-Highlight angeben:
  • (Android 11 QPR3, Android 11 Car, Android 12)
    car_ui_rotary_focus_fill_secondary_color
    car_ui_rotary_focus_stroke_secondary_color
  • (Android 12)
    car_ui_rotary_focus_pressed_fill_secondary_color
    car_ui_rotary_focus_pressed_stroke_secondary_color

Alle Farben können transparent sein und eine der beiden Dimensionen kann null sein, wenn Sie beispielsweise nur eine Füllung oder nur einen Umriss wünschen.

Fokusbereich hervorheben

(Android 11 QPR3, Android 11 Auto, Android 12)
FocusArea kann zwei Arten von Highlights zeichnen, wenn einer seiner Nachkommen im Fokus ist. Sie können bei Bedarf auch gemeinsam verwendet werden. Diese Funktion ist in AOSP standardmäßig deaktiviert, kann aber durch Überschreiben der Ressourcen der Car-UI-Bibliothek aktiviert werden:

  • car_ui_enable_focus_area_foreground_highlight: Zeichnen Sie ein Highlight über dem FocusArea und seinen untergeordneten Elementen. In AOSP ist dieses Drawable ein Umriss um die FocusArea. OEMs können das car_ui_focus_area_foreground_highlight-Zeichnen überschreiben.
  • car_ui_enable_focus_area_background_highlight: Zeichnen Sie einen Akzent über dem FocusArea, aber hinter seinen Nachkommen. In AOSP ist dieses Drawable eine durchgehende Füllung. OEMs können das car_ui_focus_area_background_highlight-Zeichnen überschreiben.

Eingabemethoden-Editoren

Eingabemethoden-Editoren (IME) sind Eingabemethoden. Beispielsweise eine Bildschirmtastatur.

(Android 11 QPR3, Android 11 Car, Android 12)
Der OEM muss die Stringressource default_touch_input_method in der RotaryService überlagern, um die ComponentName der berührungsbasierten IME anzugeben. Wenn der OEM beispielsweise die mit Android Automotive bereitgestellte IME verwendet, sollte er com.google.android.apps.automotive.inputmethod/.InputMethodService angeben.

(Android 11 QPR3, Android 11 für Autos, Android 12)
Wenn der OEM eine IME speziell für Drehknöpfe erstellt hat, sollte er die zugehörige ComponentName in der rotary_input_method-Ressource angeben. Wenn diese Ressource überlagert ist, wird die angegebene IME verwendet, wenn der Nutzer über die Schaltflächen „Nudge“, „Drehen“ und „Mitte“ des Drehreglers mit der Infotainment-Einheit interagiert. Wenn der Nutzer den Bildschirm berührt, wird die vorherige Eingabemethode verwendet. Die Schaltfläche „Zurück“ und andere Tasten am Drehregler haben keine Auswirkungen auf die Auswahl der IME. Wenn diese Ressource nicht überlagert ist, wird die IME nicht umgeschaltet. Cardboard unterstützt keine Drehknöpfe. Wenn der OEM keine Drehknopf-IME zur Verfügung gestellt hat, kann der Nutzer also keinen Text über den Drehknopf eingeben.

RotaryIME ist eine Demo-IME für Drehrad. Das ist zwar einfach, reicht aber aus, um die oben beschriebene automatische IME-Umstellung zu testen. Den Quellcode für RotaryIME finden Sie in packages/apps/Car/tests/RotaryIME/.

Push-Benachrichtigungen

Standardmäßig passiert nichts, wenn der Nutzer versucht, den Bildschirmrand zu berühren. Der OEM kann konfigurieren, was für jede der vier Richtungen passieren soll, indem er eine beliebige Kombination aus folgenden Optionen angibt:

  1. Eine globale Aktion, die von AccessibilityService definiert wird. Beispiel: GLOBAL_ACTION_BACK.
  2. Einen Schlüsselcode, z. B. KEYCODE_BACK.
  3. Ein Intent zum Starten einer Aktivität, der als URL dargestellt wird.

(Android 11 QPR3, Android 11 Auto, Android 12)
Diese werden durch Überlagern der folgenden Arrayressourcen in der RotaryService angegeben:

  • off_screen_nudge_global_actions: Array globaler Aktionen, die ausgeführt werden, wenn der Nutzer den Bildschirmrand nach oben, unten, links oder rechts berührt. Es wird keine globale Aktion ausgeführt, wenn das entsprechende Element dieses Arrays „-1“ ist.
  • off_screen_nudge_key_codes: Array von Tastencodes für Klickereignisse, die eingefügt werden, wenn der Nutzer den Bildschirmrand nach oben, unten, links oder rechts verlässt. Es werden keine Ereignisse eingefügt, wenn das entsprechende Element dieses Arrays „0“ (KEYCODE_UNKNOWN) ist.
  • off_screen_nudge_intents: Array von Intents, um eine Aktivität zu starten, wenn der Nutzer den Bildschirmrand nach oben, unten, links oder rechts berührt. Es wird keine Aktivität gestartet, wenn das entsprechende Element dieses Arrays leer ist.

Andere Konfigurationen

Sie sollten die folgenden RotaryService-Ressourcen überlagern:

  • (Android 11 QPR3, Android 11 Car, Android 12)
    config_showHeadsUpNotificationOnBottom: Boolescher Wert, der angibt, ob sich die Benachrichtigungen unten statt oben anzeigen lassen sollen. Dieser muss mit dem Wert der booleschen Ressource config_showHeadsUpNotificationOnBottom in frameworks/base/packages/CarSystemUI/res/values/config.xml übereinstimmen.
  • (Android 11 QPR3, Android 11 Car, Android 12)
    notification_headsup_card_margin_horizontal: Linker und rechter Rand für das Fenster für die Pop-up-Benachrichtigung. Dieser muss mit dem Wert der notification_headsup_card_margin_horizontal-Dimension in packages/apps/Car/Notification/res/values/dimens.xml übereinstimmen.
  • (Android 12)
    excluded_application_overlay_window_titles: Ein Array von Titeln von Fenstern, die nicht als Overlayfenster betrachtet werden sollten. Dazu gehören auch Titel von App-Fenster, die TaskViews oder TaskDisplayAreas darstellen. Standardmäßig enthält diese Liste nur „Maps“.

Sie können die folgende RotaryService-Ressource als Overlay verwenden:

  • (Android 11 QPR3, Android 11 Car, Android 12)
    long_press_ms: Ganzzahlwert, der angibt, wie lange die mittlere Taste gedrückt gehalten werden muss, um ein langes Drücken auszulösen. „0“ gibt an, dass die Standardzeitüberschreitung für das lange Drücken verwendet werden soll. Dies ist der Standardwert.