Cette page explique comment traiter les entrées par dispositif rotatif dans le VHAL, configurer votre build d'inclure le service rotatif et de personnaliser son fonctionnement dans toutes les applications. Pour les applications OEM préinstallées, telles que le lanceur d'applications fourni par l'OEM, consultez Bibliothèque Car UI (car-ui-library).
VHAL
Un contrôleur rotatif prend en charge les actions suivantes:
- Déplacer vers le haut, le bas, la gauche et la droite.
- Faites pivoter la vue dans le sens des aiguilles d'une montre et dans le sens inverse des aiguilles d'une montre.
- Appuyez sur le bouton central.
- Appuyez sur le bouton Retour.
- Appuyez sur le bouton d'accueil.
- Appuyez sur les autres boutons, comme Téléphone et Multimédia.
Consultez hardware/interfaces/automotive/vehicle/2.0/types.hal
pour obtenir de la documentation sur
les propriétés système et les int32Values
correspondantes.
Le VHAL doit gérer les actions suivantes:
Coup de pouce
Lorsque l'utilisateur pousse le contrôleur rotatif vers la droite, le VHAL doit utiliser le
la propriété HW_KEY_INPUT
avec le int32Values
suivant pour envoyer une
vers Android:
ACTION_DOWN
KEYCODE_SYSTEM_NAVIGATION_RIGHT
- Affichage cible.
Lorsque l'utilisateur relâche le contrôleur rotatif, le VHAL doit utiliser la même propriété et
code de clavier avec ACTION_UP
. Pour les encouragements dans d'autres directions, utilisez
codes de clavier correspondants.
Il n'y a pas de codes de clavier pour les diagonales, mais le VHAL peut combiner un format horizontal et vertical pour produire une diagonale si le matériel prend en charge les diagonales. Par exemple, encourager et celui de gauche devrait produire:
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_DOWN
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_DOWN
Dans l'un ou l'autre des ordres, puis en relâchant le contrôleur rotatif, vous devriez obtenir:
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_UP
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_UP
L'utilisateur peut pousser le contrôleur rotatif vers la perpendiculaire avant de le relâcher. Prenons l'exemple du scénario suivant:
![Direction perpendiculaire](https://source.android.com/static/docs/automotive/images/rotary_06.png?authuser=1&hl=fr)
La séquence d'événements suivante devrait être générée:
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_DOWN
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_DOWN
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_UP
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_UP
Aucun événement repeat ne doit être généré lorsque le contrôleur rotatif est maintenu dans un sens.
Faire pivoter
Lorsque l'utilisateur fait pivoter le contrôleur rotatif d'un point (clic) dans le sens des aiguilles d'une montre, le VHAL
doit utiliser la propriété HW_ROTARY_INPUT
avec l'élément int32Values
suivant :
pour envoyer un événement à Android:
ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
- Une (1) tente.
- Affichage cible.
Le code temporel de l'événement doit être défini sur le temps écoulé en nanosecondes.
Une rotation d'un (1) retrait dans le sens inverse des aiguilles d'une montre devrait générer le même événement, mais avec -1 pour le nombre de retraits.
Si plusieurs dents de rotation dans la même direction se succèdent rapidement, le VHAL
doivent combiner les retenues en un seul événement afin de ne pas surcharger le système d'événements.
Dans ce cas, l'horodatage de l'événement doit correspondre au moment où le premier arrêt de rotation s'est produit.
L'élément int32Values
doit inclure le nombre de nanosecondes entre les retenues consécutives.
de rotation.
Par exemple, la séquence de rotations suivante:
- À l'instant t0, l'utilisateur a effectué une rotation d'un cran dans le sens inverse des aiguilles d'une montre.
- À l'instant t0 + 5 ns, l'utilisateur a effectué une rotation d'un cran dans le sens inverse des aiguilles d'une montre.
- À l'instant t0 + 8 ns, l'utilisateur a effectué une rotation d'un cran dans le sens inverse des aiguilles d'une montre.
doit générer l'événement suivant:
- Propriété:
HW_ROTARY_INPUT
- Code temporel:
t0
int32Values
: <ph type="x-smartling-placeholder">- </ph>
ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
- -3 (trois pressions dans le sens inverse des aiguilles d'une montre).
- Affichage cible.
- 5 ns entre le premier et le deuxième creux.
- 3 ns entre le deuxième et le troisième point d'arrêt.
Bouton central
Lorsque l'utilisateur appuie sur le bouton central, le VHAL doit utiliser HW_KEY_INPUT
avec le int32Values
suivant pour envoyer un événement à Android:
ACTION_DOWN
KEYCODE_DPAD_CENTER
- Affichage cible.
Lorsque l'utilisateur relâche le contrôleur rotatif, le VHAL doit utiliser la même propriété
et le code de clavier avec ACTION_UP
.
Ne générez pas d'événements repeat lorsque vous maintenez le bouton central enfoncé.
Bouton Retour
Lorsque l'utilisateur appuie sur le bouton "Retour", le VHAL doit utiliser HW_KEY_INPUT
avec le int32Values
suivant pour envoyer un événement à Android:
ACTION_DOWN
KEYCODE_BACK
- Affichage cible.
Lorsque l'utilisateur relâche le contrôleur rotatif, le VHAL doit utiliser la même propriété
et le code de clavier avec ACTION_UP
.
Aucun événement repeat ne doit être généré lorsque le bouton central est enfoncé.
Bouton Accueil
Gérez le bouton d'accueil comme vous le feriez pour le bouton "Retour", mais avec KEYCODE_HOME
à la place
sur KEYCODE_BACK
.
Autres boutons
Si le contrôleur rotatif inclut des boutons supplémentaires, le VHAL peut les gérer
aime l'OEM, car ils ne sont pas considérés
comme faisant partie du dispositif rotatif du point de vue d'Android.
Ceux-ci sont généralement gérés comme les boutons Retour et Accueil, mais avec des codes de clavier différents.
Exemples : KEYCODE_CALL
ou KEYCODE_MUSIC
.
Configuration de compilation
La navigation par dispositif rotatif est fournie par un service d'accessibilité appelé RotaryService
.
Pour inclure ce service dans l'image système de votre appareil, ajoutez la ligne suivante à votre
makefile:
PRODUCT_PACKAGES += CarRotaryController
Vous pouvez également inclure les packages suivants dans les versions de débogage:
RotaryPlayground
Application de référence pour le dispositif rotatif (voir RotaryPlayground).RotaryIME
IME rotatif de démonstration (voir Éditeurs de mode de saisie).CarRotaryImeRRO
: superposition deRotaryIME
.
Le service rotatif est activé automatiquement au démarrage de l'appareil et lorsqu'un utilisateur avant qu'un changement de mode ne se produise. Cela garantit que l'utilisateur peut utiliser le contrôleur rotatif pendant la configuration.
Si vous utilisez le même build pour des voitures
avec et sans contrôleur rotatif,
Ajoutez CarRotaryController
comme indiqué ci-dessus afin que le code nécessaire soit inclus.
dans la compilation. Pour empêcher l'activation du service rotatif sur des véhicules non rotatifs, créez un
RRO statique pour superposer la ressource de chaîne rotaryService
dans
packages/services/Car/service
par une chaîne vide. Vous utiliserez la même compilation,
mais ont des configurations de produit distinctes, pour les appareils rotatifs et non rotatifs. Uniquement la deuxième
inclut la superposition.
Personnalisation
Les OEM peuvent personnaliser la logique de recherche, la mise en avant et certains éléments supplémentaires via superpositions de ressources aux emplacements suivants:
- car-ui-library se trouve dans
packages/apps/Car/libs/car-ui-lib
RotaryService
se trouve àpackages/apps/Car/RotaryController
Core
se trouve àframeworks/base/core
Historique des rappels automatiques
L'OEM peut configurer l'activation ou non de chacun des deux types d'historique des rappels automatiques. la taille du cache et la règle d'expiration. Pour cela, il suffit de remplacer ressources.
Placer le curseur sur le cache de l'historique
(Android 11 QPR3, Android 11 Car,
Android 12)
Ce cache par FocusArea
stocke la dernière vue sélectionnée dans le
FocusArea
afin qu'il puisse être sélectionné lorsque vous revenez à FocusArea
.
Ce cache peut être configuré en superposant les ressources car-ui-library suivantes:
-
car_ui_focus_history_cache_type
: <ph type="x-smartling-placeholder">- </ph>
- Le cache est désactivé.
- Le cache expire au bout d'un certain temps (voir ci-dessous).
- Le cache n'expirera jamais.
car_ui_focus_history_expiration_period_ms
: nombre de millisecondes avant l'événement Le cache expire si le type de cache est défini sur deux (2) (voir ci-dessus).
Cache de l'historique FocusArea
(Android 11 QPR3, Android 11 Car,
Android 12)
Ce cache stocke un historique des rappels automatiques afin que ceux dans la direction opposée puissent
replacer le curseur sur le même FocusArea
. Ce cache peut être configuré en superposant le
ressources car-ui-library suivantes:
-
car_ui_focus_area_history_cache_type
: <ph type="x-smartling-placeholder">- </ph>
- Le cache est désactivé.
- Le cache expire au bout d'un certain temps (voir ci-dessous).
- Le cache n'expire jamais.
car_ui_focus_area_history_expiration_period_ms
: nombre de millisecondes avant le début de l'événement le cache expire si le type de cache est défini sur 2 (voir ci-dessus).car_ui_clear_focus_area_history_when_rotating
: indique si le cache doit être vidé ou non. lorsque l'utilisateur fait pivoter la manette.
Rotation
(Android 11 QPR3, Android 11 Car,
Android 12)
L'OEM peut remplacer deux ressources d'entiers dans RotaryService
pour spécifier si
la rotation entraîne une accélération, telle que l'accélération du curseur:
rotation_acceleration_3x_ms
: intervalle de temps (en millisecondes) utilisé pour décider si Google doit accélérer la rotation du contrôleur pour un blocage de rotation. Si le l'intervalle entre ce cran et le précédent est inférieur à cette valeur, on considère qu'il y a trois points de rotation. Définissez cette valeur sur 2147483647 pour désactiver 3 fois de l'accélération matérielle.rotation_acceleration_2x_ms
: semblable àrotation_acceleration_3x_ms
. Utilisé pour l'accélération × 2. Définissez cette valeur sur2147483647
pour désactiver l'accélération 2×.
L'accélération fonctionne mieux avec des codes temporels individuels pour chaque retenue de
la rotation,
obligatoire
par le VHAL. Si elles ne sont pas disponibles, le RotaryService
suppose que les retenues de
de rotation sont espacés uniformément.
/** * 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),
Sélectionner la sélection
L'OEM peut ignorer la mise en surbrillance par défaut dans le framework Android et plusieurs ressources mettent en évidence les ressources dans car-ui-library.
Mise en surbrillance par défaut du focus
Le framework Android met en évidence par défaut l'attribut
selectableItemBackground
Dans Theme.DeviceDefault
, ce
fait référence à item_background.xml
dans Core
. L'OEM peut superposer
item_background.xml
pour modifier le drawable de mise en surbrillance par défaut du focus.
Ce drawable doit généralement être un StateListDrawable
, qui ajuste l'arrière-plan
en fonction de différentes combinaisons d'états, y compris android:state_focused
et android:state_pressed
. Lorsque l'utilisateur utilise le contrôleur rotatif pour
sélectionner une vue, android:state_focused
sera true
, mais
android:state_pressed
sera false
. Si l'utilisateur appuie ensuite sur
le bouton central du contrôleur rotatif, à la fois android:state_focused
et
android:state_pressed
sera true
lorsque l'utilisateur maintiendra le bouton enfoncé.
Lorsque l'utilisateur relâche le bouton, il ne reste que android:state_focused
.
true
car-ui-library utilise un thème dérivé de Theme.DeviceDefault
. Par conséquent,
cette superposition affecte les applications qui utilisent cette bibliothèque et celles qui utilisent n'importe quel thème dérivé de
Theme.DeviceDefault
Cela n'affectera pas les applications
qui utilisent un thème sans rapport,
comme Theme.Material
.
Placer le curseur sur les ressources de la bibliothèque car-ui-library
L'OEM peut ignorer plusieurs ressources car-ui-library pour contrôler la mise en surbrillance
regarde les vues dont la mise en surbrillance n'est pas rectangulaire (arrondie ou en forme de pilule, par exemple).
Applications dont le thème ne provient pas de Theme.DeviceDefault
. Ces
les ressources doivent être superposées de sorte que l'accent soit cohérent avec
Drawable mise en surbrillance par défaut.
(Android 11 QPR3, Android 11 Car,
Android 12)
Les ressources suivantes sont utilisées pour indiquer quand une vue est sélectionnée mais pas appuyée:
car_ui_rotary_focus_fill_color
: couleur de remplissage.car_ui_rotary_focus_stroke_color
: couleur du contour.car_ui_rotary_focus_stroke_width
: épaisseur du contour.
(Android 11 QPR3, Android 11 Car,
Android 12)
Les ressources suivantes sont utilisées pour indiquer si une vue est sélectionnée et si vous appuyez dessus:
car_ui_rotary_focus_pressed_fill_color
: couleur de remplissage.car_ui_rotary_focus_pressed_stroke_color
: couleur du contour.car_ui_rotary_focus_pressed_stroke_width
: épaisseur du contour.
Parfois, un bouton se voit attribuer une couleur d'arrière-plan unie pour attirer l'attention de l'utilisateur, comme dans l'exemple présenté ici. La mise en surbrillance de l'élément peut alors être difficile à voir.
![Bouton avec un arrière-plan uni](https://source.android.com/static/docs/automotive/images/rotary_05.png?authuser=1&hl=fr)
Dans ce cas, le développeur peut spécifier une mise en surbrillance personnalisée à l'aide de couleurs secondaires: <ph type="x-smartling-placeholder">
- </ph>
- (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
Toutes les couleurs peuvent être transparentes et les deux peuvent être égales à zéro si, par exemple, voulait seulement un remplissage ou seulement un contour.
Sélection de FocusArea
(Android 11 QPR3, Android 11 Car,
Android 12)
FocusArea
peut dessiner deux types de mise en surbrillance lorsque l'un de ses descendants est
concentré. Vous pouvez les utiliser conjointement, si vous le souhaitez. Cette fonctionnalité est désactivée par défaut dans
AOSP, mais peut être activée en remplaçant les ressources car-ui-library:
car_ui_enable_focus_area_foreground_highlight
: tracez une mise en surbrillance sur leFocusArea
et ses descendants. Dans AOSP, ce drawable est un contour autour duFocusArea
. Les OEM peuvent ignorer Drawablecar_ui_focus_area_foreground_highlight
.car_ui_enable_focus_area_background_highlight
: tracez une mise en surbrillance au-dessus duFocusArea
, mais derrière ses descendants. Dans AOSP, ce drawable est un remplissage solide. Les OEM peuvent ignorer le drawablecar_ui_focus_area_background_highlight
.
Éditeurs du mode de saisie
Les éditeurs de mode de saisie (IME) sont des modes de saisie. Par exemple, un clavier à l'écran.
(Android 11 QPR3, Android 11 Car,
Android 12)
L'OEM doit superposer la ressource de chaîne default_touch_input_method
.
dans le RotaryService
pour spécifier le ComponentName
un IME basé sur l'écran tactile. Par exemple, si l'OEM utilise l'IME fourni avec Android Automotive,
il doit spécifier
com.google.android.apps.automotive.inputmethod/.InputMethodService
(Android 11 QPR3, Android 11 Car,
Android 12)
Si l'OEM a créé un IME spécifiquement pour le dispositif rotatif, il doit spécifier son
ComponentName
dans la ressource rotary_input_method
. Si cette ressource
est superposé, l'IME spécifié est utilisé chaque fois que l'utilisateur interagit avec l'unité principale.
via le bouton de rappel, la rotation et le bouton central du contrôleur rotatif. Lorsque l'utilisateur touche
à l'écran, l'IME précédent sera utilisé. Le bouton "Retour" (et les autres boutons du cadran
contrôleur) n'ont aucun effet sur la sélection de l'IME. Si cette ressource n'est pas superposée, aucun changement d'IME
se produit. Carboard n'est pas compatible avec le dispositif rotatif, de sorte que l'utilisateur ne peut pas saisir de texte via ce dispositif.
contrôleur si l'OEM n'a pas fourni d'IME rotatif.
RotaryIME
est un IME rotatif de démonstration. Bien que basique, il suffit de
essayez le basculement automatique IME décrit ci-dessus. Le code source de RotaryIME
se trouve dans packages/apps/Car/tests/RotaryIME/
.
Rappels automatiques hors écran
Par défaut, rien ne se passe lorsque l'utilisateur essaie de sortir du bord de l'écran. L'OEM peut configurer ce qui doit se passer pour chacune des quatre directions en spécifiant combinaison de:
- Une action globale définie par
AccessibilityService
. Par exemple :GLOBAL_ACTION_BACK
- Un code de touche, tel que
KEYCODE_BACK
. - Intent permettant de lancer une activité représentée sous forme d'URL.
(Android 11 QPR3, Android 11 Car,
Android 12)
Celles-ci sont spécifiées en superposant les ressources de tableau suivantes dans le
RotaryService
:
off_screen_nudge_global_actions
: tableau des actions globales à effectuer lorsque l'utilisateur pousse l'utilisateur vers le haut, le bas, la gauche ou la droite du bord de l'écran. Aucune action globale n'est si l'élément pertinent de ce tableau est -1.off_screen_nudge_key_codes
: tableau des codes de touches des événements de clic à injecter lorsque l'utilisateur pousse le doigt vers le haut, le bas, la gauche ou la droite du bord de l'écran. Aucun événement injecté si l'élément concerné de ce tableau est 0 (KEYCODE_UNKNOWN
).off_screen_nudge_intents
: tableau d'intents pour lancer une activité lorsque l'utilisateur pousse l'utilisateur vers le haut, le bas, la gauche ou la droite du bord de l'écran. Aucune activité n'est lancée si l'élément pertinent de ce tableau est vide.
Autres configurations
Vous devez superposer les ressources RotaryService
suivantes:
- (Android 11 QPR3, Android 11 Car,
Android 12)
config_showHeadsUpNotificationOnBottom
: valeur booléenne indiquant si les notifications prioritaires doivent être affichées en bas et non en haut. Cela doit ont la même valeur queconfig_showHeadsUpNotificationOnBottom
; Ressource booléenne dansframeworks/base/packages/CarSystemUI/res/values/config.xml
- (Android 11 QPR3, Android 11 Car,
Android 12)
notification_headsup_card_margin_horizontal
: marges gauche et droite de ou une fenêtre de notification prioritaire. Il doit avoir la même valeur quenotification_headsup_card_margin_horizontal
ressource de luminosité danspackages/apps/Car/Notification/res/values/dimens.xml
- (Android 12)
excluded_application_overlay_window_titles
: tableau de des fenêtres qui ne doivent pas être considérées comme des fenêtres en superposition. Cela doit inclure les titres des fenêtres d'application représentantTaskViews
ouTaskDisplayAreas
. Par défaut, cette liste ne contient que "Cartes".
Vous pouvez superposer la ressource RotaryService
suivante:
- (Android 11 QPR3, Android 11 Car,
Android 12)
long_press_ms
: valeur entière représentant le nombre de millisecondes qu'une Vous devez maintenir le bouton central enfoncé pour déclencher un appui prolongé. Le chiffre 0 indique que le système le délai par défaut d'appui prolongé doit être utilisé. Il s'agit de la valeur par défaut.