En esta página, se describe cómo procesar entradas rotativas en la VHAL y configurar tu compilación para incluir el servicio rotativo y cómo personalizar la experiencia en todas las apps. Para apps del OEM preinstaladas, como un selector proporcionado por el OEM, consulta Biblioteca de IU del vehículo (car-ui-library).
VHAL
Un control rotativo admite las siguientes acciones:
- Empujar hacia arriba, hacia abajo, hacia la izquierda y hacia la derecha.
- Rotar en el sentido de las manecillas del reloj y en el sentido contrario.
- Presiona el botón central.
- Presiona el botón Atrás.
- Presiona el botón de inicio.
- Presiona otros botones, como Teléfono y Multimedia.
Consulta hardware/interfaces/automotive/vehicle/2.0/types.hal
para ver la documentación sobre
las propiedades del sistema y los int32Values
correspondientes
La VHAL debe controlar las siguientes acciones:
Aviso
Cuando el usuario presiona el control rotativo hacia la derecha, la VHAL debe usar el
Propiedad HW_KEY_INPUT
con los siguientes int32Values
para enviar un
a Android:
ACTION_DOWN
KEYCODE_SYSTEM_NAVIGATION_RIGHT
- Visualización de destino.
Cuando el usuario suelta el control rotativo, la VHAL debe usar la misma propiedad y
clave con ACTION_UP
. Los movimientos en otras direcciones deben utilizar el
con los códigos de teclas correspondientes.
No hay códigos de teclas para diagonales, pero el VHAL puede combinar una estructura horizontal y vertical. para producir una diagonal si el hardware admite diagonales. Por ejemplo, sugerir y a la izquierda debería producir lo siguiente:
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_DOWN
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_DOWN
En cualquier orden (y posteriormente), liberar el control rotativo debería producir lo siguiente:
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_UP
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_UP
El usuario puede empujar el control rotativo en una dirección perpendicular antes de soltarlo. Por ejemplo, la siguiente situación:
Esto debería generar la siguiente secuencia de eventos:
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
No se deben generar eventos repetir mientras el control rotativo está presionado en una dirección.
Rotar
Cuando el usuario rota el control rotativo en el sentido de las manecillas del reloj un ajuste, la VHAL
Debes usar la propiedad HW_ROTARY_INPUT
con el siguiente int32Values
Para enviar un evento a Android, sigue estos pasos:
ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
- Un (1) tipo de retención.
- Visualización de destino.
La marca de tiempo del evento debe establecerse en el tiempo transcurrido en nanosegundos.
Una (1) rotación en sentido antihorario debería generar el mismo evento, pero con -1 para la cantidad de detenciones.
Si se producen varias retenciones de rotación en la misma dirección en una sucesión rápida, el VHAL debe
se deben combinar los bloqueos en un solo evento para no sobrecargar el sistema con eventos.
En este caso, la marca de tiempo del evento debe corresponder al momento en que se produjo el primer detención de la rotación.
int32Values
debe incluir la cantidad de nanosegundos entre detenciones consecutivas.
de rotación.
Por ejemplo, la siguiente secuencia de rotaciones:
- En el tiempo t0, el usuario giró un soporte en el sentido contrario a las manecillas del reloj.
- En el tiempo t0 + 5 ns, el usuario giró un ajuste en sentido antihorario.
- En el tiempo t0 + 8 ns, el usuario giró un ajuste en sentido antihorario.
debería generar este evento:
- Propiedad:
HW_ROTARY_INPUT
- Marca de tiempo:
t0
int32Values
:ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
- -3 (tres bloqueos en sentido contrario a las manecillas del reloj).
- Visualización de destino.
- 5 ns entre el primer y el segundo detenimiento.
- 3 ns entre la segunda y la tercera retención.
Centrar botón
Cuando el usuario presiona el botón central, la VHAL debe usar el HW_KEY_INPUT
con el siguiente int32Values
para enviar un evento a Android:
ACTION_DOWN
KEYCODE_DPAD_CENTER
- Visualización de destino.
Cuando el usuario suelta el control rotativo, la VHAL debe usar la misma propiedad
y el código de clave con ACTION_UP
.
No generes eventos repetir cuando se mantenga presionado el botón central.
Botón Atrás
Cuando el usuario presiona el botón Atrás, la VHAL debe usar el HW_KEY_INPUT
con el siguiente int32Values
para enviar un evento a Android:
ACTION_DOWN
KEYCODE_BACK
- Visualización de destino.
Cuando el usuario suelta el control rotativo, la VHAL debe usar la misma propiedad
y el código de clave con ACTION_UP
.
No se deben generar eventos repetir mientras el botón central está presionado.
Botón Inicio
Controla el botón de inicio como lo harías con el botón Atrás, pero con KEYCODE_HOME
.
de KEYCODE_BACK
.
Otros botones
Si el control rotativo incluye botones adicionales, el VHAL podrá controlarlos, sin embargo,
que le gusta al OEM, ya que no se consideran parte de la versión rotativa desde la perspectiva de Android.
Por lo general, se manejan como los botones Atrás y Inicio, pero con códigos de teclas diferentes.
Por ejemplo, KEYCODE_CALL
o KEYCODE_MUSIC
.
Configuración de compilación
Un servicio de accesibilidad llamado RotaryService
proporciona navegación rotativa.
Para incluir este servicio en la imagen del sistema de tu dispositivo, agrega la siguiente línea a tu
makefile:
PRODUCT_PACKAGES += CarRotaryController
Es posible que también desees incluir los siguientes paquetes en las compilaciones de depuración:
RotaryPlayground
Es una app de referencia para rotativos (consulta RotaryPlayground).RotaryIME
Es un IME rotativo de demostración (consulta Editores de métodos de entrada).CarRotaryImeRRO
: Es la superposición deRotaryIME
.
El servicio rotativo se habilita automáticamente cuando se inicia el dispositivo y cuando un usuario se produce el cambio. Esto garantiza que el usuario pueda usar el control rotativo durante la configuración.
Si usas la misma compilación para autos con y sin control rotativo,
agrega CarRotaryController
como se muestra más arriba para que se incluya el código necesario
en la compilación. Para evitar que se habilite el servicio rotativo en automóviles no rotativos, crea un
RRO estático para superponer el recurso de cadenas rotaryService
en
packages/services/Car/service
con una cadena vacía. Usarás la misma compilación,
pero tienen configuraciones de producto separadas, para dispositivos rotativos y no rotativos. Solo los últimos
incluye la superposición.
Personalización
Los OEM pueden personalizar la lógica de búsqueda del enfoque, el enfoque destacado y algunos elementos adicionales a través de superposiciones de recursos en las siguientes ubicaciones:
- car-ui-library se encuentra en
packages/apps/Car/libs/car-ui-lib
RotaryService
se encuentra enpackages/apps/Car/RotaryController
Core
se encuentra enframeworks/base/core
Historial de sugerencias
El OEM puede configurar si se habilita cada uno de los dos tipos de historial de sugerencias y, de ser así, el tamaño de caché y la política de caducidad. Para ello, se anulan varias de Google Cloud.
Enfocar la caché del historial
(Android 11 QPR3, Android 11 Car,
Android 12)
Esta caché por FocusArea
almacena la vista enfocada más reciente dentro del
FocusArea
para que se pueda enfocar cuando se vuelve a consultar FocusArea
.
Esta caché se puede configurar superponiendo los siguientes recursos car-ui-library:
-
car_ui_focus_history_cache_type
:- La caché está inhabilitada.
- La caché vencerá después de un tiempo (consulte a continuación).
- La caché nunca vencerá.
car_ui_focus_history_expiration_period_ms
: Cantidad de milisegundos antes del se vence si el tipo de caché está establecido en dos (2) (ver arriba).
Caché del historial de FocusArea
(Android 11 QPR3, Android 11 Car,
Android 12)
Esta caché almacena un historial de sugerencias, de manera que las sugerencias en la dirección opuesta puedan
volver el enfoque a la misma FocusArea
. Para configurar esta caché, puedes superponer
Los siguientes recursos de car-ui-library:
-
car_ui_focus_area_history_cache_type
:- La caché está inhabilitada.
- La caché vence después de un tiempo (consulta a continuación).
- La caché nunca vence.
car_ui_focus_area_history_expiration_period_ms
: Cuántos milisegundos antes la caché caduca si el tipo de caché se establece en 2 (ver arriba).car_ui_clear_focus_area_history_when_rotating
: Especifica si se debe anular la caché. cuando el usuario rota el control.
Rotación
(Android 11 QPR3, Android 11 Car,
Android 12)
El OEM puede anular dos recursos enteros en RotaryService
para especificar si
hay aceleración, como la aceleración del mouse, para la rotación:
rotation_acceleration_3x_ms
: Es el intervalo de tiempo (en milisegundos) que se utiliza para decidir. si Google debe acelerar la rotación del controlador para un descenso de la rotación. Si el botón entre este límite de rotación y el anterior es menor que este valor se tratará como tres restricciones de rotación. Establece este valor en 2147483647 para inhabilitar 3× aceleración.rotation_acceleration_2x_ms
: Es similar arotation_acceleration_3x_ms
. Se usa para una aceleración de 2 veces. Establece este valor en2147483647
para inhabilitar la aceleración de 2 veces.
La aceleración funciona mejor cuando hay marcas de tiempo individuales para cada retención de
rotación, ya que
obligatorio
por el VHAL. Si no están disponibles, RotaryService
supone que los bloqueos de
rotación están espaciados uniformemente.
/** * 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),
Enfocar destacado
El OEM puede anular el enfoque predeterminado destacado en el framework de Android. varios recursos destacados de enfoque en car-ui-library
Enfoque predeterminado destacado
El framework de Android proporciona un enfoque predeterminado con el atributo
selectableItemBackground
En Theme.DeviceDefault
, esta
hace referencia a item_background.xml
en Core
. El OEM puede superponer
item_background.xml
para cambiar el elemento de diseño de resalte del foco predeterminado
Por lo general, este elemento de diseño debería ser una StateListDrawable
, que ajusta el fondo.
según diferentes combinaciones de estados, como android:state_focused
y android:state_pressed
. Cuando el usuario utiliza el control rotativo para
enfocar una vista, android:state_focused
serán true
, pero
android:state_pressed
serán false
. Si el usuario presiona
el botón central del control rotativo, tanto android:state_focused
como
android:state_pressed
estará true
mientras el usuario mantenga presionado el botón.
Cuando el usuario suelte el botón, solo permanecerá android:state_focused
true
car-ui-library usa un tema derivado de Theme.DeviceDefault
. Como resultado,
esta superposición afecta a las apps que usan esta biblioteca y a las que usan cualquier tema derivado de
Theme.DeviceDefault
No afectará a las apps que usen un tema no relacionado,
como Theme.Material
.
Enfócate en los recursos para destacar elementos en car-ui-library
El OEM puede anular varios recursos car-ui-library para controlar cómo se destaca el foco.
busca en vistas con un enfoque no rectangular (como redondo o en forma de píldora) destacado y en
Apps que usan un tema que no proviene de Theme.DeviceDefault
. Estos
recursos deben superponerse para que el enfoque destacado concuerde con
elemento de diseño destacado del foco predeterminado.
(Android 11 QPR3, Android 11 Car,
Android 12)
Los siguientes recursos se usan para indicar cuándo una vista está enfocada, pero no presionada:
car_ui_rotary_focus_fill_color
: Color de relleno.car_ui_rotary_focus_stroke_color
: Color del contorno.car_ui_rotary_focus_stroke_width
: Es el grosor del contorno.
(Android 11 QPR3, Android 11 Car,
Android 12)
Los siguientes recursos se usan para indicar cuándo una vista está enfocada y se la presiona:
car_ui_rotary_focus_pressed_fill_color
: Color de relleno.car_ui_rotary_focus_pressed_stroke_color
: Color del contorno.car_ui_rotary_focus_pressed_stroke_width
: Es el grosor del contorno.
A veces, un botón recibe un color de fondo sólido para llamar la atención del usuario, como en el ejemplo que se muestra. Esto puede hacer que el enfoque destacado sea difícil de ver.
En esta situación, el desarrollador puede especificar un enfoque destacado personalizado usando secondary (secundarios):
- (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
Cualquiera de los colores puede ser transparente y cualquier dimensión puede ser cero si, por ejemplo, solo querían un relleno o solo un contorno.
Elemento destacado del área de enfoque
(Android 11 QPR3, Android 11 Car,
Android 12)
FocusArea
puede dibujar dos tipos de resaltado cuando uno de sus subordinados es
enfocados. Si se desea, ambos pueden usarse en conjunto. Esta función está inhabilitada de forma predeterminada en
AOSP, pero se puede habilitar anulando los recursos de car-ui-library:
car_ui_enable_focus_area_foreground_highlight
: Dibuja un resaltado encima de elFocusArea
y sus elementos subordinados. En AOSP, este elemento de diseño es un esquema alrededor de laFocusArea
. Los OEM pueden anular el Elemento de diseñocar_ui_focus_area_foreground_highlight
.car_ui_enable_focus_area_background_highlight
: Dibuja un resaltado en la parte superior de laFocusArea
, pero detrás de sus elementos subordinados. En AOSP, este elemento de diseño es un relleno sólido. Los OEMs pueden anular el elemento de diseñocar_ui_focus_area_background_highlight
.
Editores de método de entrada
Los editores de métodos de entrada (IME) son métodos de entrada. Por ejemplo, un teclado en pantalla.
(Android 11 QPR3, Android 11 Car,
Android 12)
El OEM debe superponer el recurso de cadenas default_touch_input_method
.
en el RotaryService
para especificar el ComponentName
de la
un IME táctil. Por ejemplo, si el OEM usa el IME proporcionado con Android Automotive,
deberían especificar
com.google.android.apps.automotive.inputmethod/.InputMethodService
(Android 11 QPR3, Android 11 Car,
Android 12)
Si el OEM creó un IME específicamente para rotativos, debe especificar su
ComponentName
en el recurso rotary_input_method
. Si este recurso
se superpone, se usa el IME especificado cada vez que el usuario interactúa con la consola central
a través del botón de empuje, la rotación y el botón Centrar del control rotativo. Cuando el usuario toca
la pantalla, se usará el IME anterior. El botón Atrás (y otros botones de la
controlador) no influyen en la selección del IME. Si este recurso no está superpuesto, no habrá cambios de IME
de que ocurra. El cartón no es compatible con el rotativo, por lo que el usuario no puede ingresar texto a través del rotativo
si el OEM no proporcionó un IME rotativo.
RotaryIME
es un IME rotativo de demostración. Aunque es básico, es suficiente
prueba el cambio automático de IME descrito anteriormente. El código fuente de RotaryIME
se encuentran en packages/apps/Car/tests/RotaryIME/
.
Sugerencias fuera de pantalla
De forma predeterminada, cuando el usuario intenta salir del borde de la pantalla, no sucede nada. El OEM puede configurar lo que debe ocurrir para cada una de las cuatro direcciones especificando cualquier combinación de:
- Es una acción general definida por
AccessibilityService
. Por ejemplo,GLOBAL_ACTION_BACK
. - Un código de tecla, como
KEYCODE_BACK
- Es un intent para iniciar una actividad representada como una URL.
(Android 11 QPR3, Android 11 Car,
Android 12)
Estas se especifican superponiendo los siguientes recursos de array en el
RotaryService
:
off_screen_nudge_global_actions
: Array de acciones globales que se deben realizar cuando el usuario se desplaza hacia arriba, hacia abajo, hacia la izquierda o hacia la derecha fuera del borde de la pantalla. No se aplica ninguna acción global si el elemento relevante de este array es -1.off_screen_nudge_key_codes
: Es el array de códigos clave de eventos de clic para insertar. cuando el usuario se desplaza hacia arriba, hacia abajo, hacia la izquierda o hacia la derecha fuera del borde de la pantalla. No hay eventos Se inserta si el elemento relevante de este array es 0 (KEYCODE_UNKNOWN
).off_screen_nudge_intents
: Es el array de intents para iniciar una actividad cuando el usuario se desplaza hacia arriba, hacia abajo, hacia la izquierda o hacia la derecha fuera del borde de la pantalla. No hay actividad se inicia si el elemento relevante de este array está vacío.
Otras configuraciones
Debes superponer los siguientes recursos RotaryService
:
- (Android 11 QPR3, Android 11 Car,
Android 12)
config_showHeadsUpNotificationOnBottom
: valor booleano para representar si las notificaciones de atención deben aparecer en la parte inferior y no en la parte superior. Debe tienen el mismo valor queconfig_showHeadsUpNotificationOnBottom
Recurso booleano enframeworks/base/packages/CarSystemUI/res/values/config.xml
- (Android 11 QPR3, Android 11 Car,
Android 12)
notification_headsup_card_margin_horizontal
: Margen izquierdo y derecho para de notificación de atención. Debe tener el mismo valor que Recurso denotification_headsup_card_margin_horizontal
dimensión enpackages/apps/Car/Notification/res/values/dimens.xml
- (Android 12)
excluded_application_overlay_window_titles
: Un array de títulos de ventanas que no deben considerarse ventanas superpuestas; Esto debe incluir los títulos de ventanas de apps que representanTaskViews
oTaskDisplayAreas
. De forma predeterminada, esta lista solo contiene "Maps".
Puedes superponer el siguiente recurso RotaryService
:
- (Android 11 QPR3, Android 11 Car,
Android 12)
long_press_ms
: Es un número entero que representa la cantidad de milisegundos del Debes mantener presionado el botón central para mantenerlo presionado. El cero indica que el sistema se debe usar el tiempo de espera predeterminado de presión prolongada. Este es el valor predeterminado.