本頁面介紹如何處理 VHAL 中的旋轉輸入、配置您的建置以包含旋轉服務,以及如何在所有應用程式中自訂旋轉體驗。對於預先安裝的 OEM 應用程式(例如 OEM 提供的啟動器),請參閱汽車 UI 庫 (car-ui-library) 。
虛擬哈爾
旋轉控制器支援以下操作:
- 向上、向下、向左、向右微移。
- 順時針和逆時針旋轉。
- 按中央按鈕。
- 按返回按鈕。
- 按主頁按鈕。
- 按其他按鈕,例如“電話”和“媒體”。
有關係統屬性和相應int32Values
的文檔,請參閱hardware/interfaces/automotive/vehicle/2.0/types.hal
。
VHAL 應處理以下操作:
輕推
當使用者向右推動旋轉控制器時,VHAL 應使用HW_KEY_INPUT
屬性和下列int32Values
將事件傳送至 Android:
-
ACTION_DOWN
-
KEYCODE_SYSTEM_NAVIGATION_RIGHT
- 目標顯示。
當使用者釋放旋轉控制器時,VHAL 應使用與ACTION_UP
相同的屬性和鍵碼。其他方向的輕推應使用對應的鍵碼。
對角線沒有鍵碼,但如果硬體支援對角線,VHAL 可以組合水平和垂直事件來產生對角線。例如,向上和向左輕推應該會產生:
-
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
使用者可以在釋放旋轉控制器之前沿垂直方向推動旋轉控制器。例如以下場景:
這應該會產生以下事件序列:
-
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
當旋轉控制器保持在一個方向時,不應產生重複事件。
旋轉
當使用者將旋轉控制器順時針旋轉一個煞車裝置(點擊)時,VHAL 應使用HW_ROTARY_INPUT
屬性和下列int32Values
將事件傳送到 Android:
-
ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
- 一 (1) 個煞車裝置。
- 目標顯示。
事件的時間戳記應設定為以奈秒為單位的經過時間。
一 (1) 個煞車裝置逆時針旋轉應產生相同的事件,但煞車裝置的數量為 -1。
如果沿著同一方向旋轉的多個煞車裝置快速連續發生,則 VHAL 應將煞車裝置組合成單一事件,以免事件使系統過載。在這種情況下,事件的時間戳記應該是第一次旋轉煞車發生的時間。 int32Values
應包含連續旋轉煞車之間的奈秒數。
例如,以下旋轉順序:
- 在時間 t0,使用者逆時針旋轉一個煞車裝置。
- 在時間 t0 + 5 ns 時,使用者逆時針旋轉一個煞車裝置。
- 在時間 t0 + 8 ns 時,使用者逆時針旋轉一個煞車裝置。
應產生此事件:
- 屬性:
HW_ROTARY_INPUT
- 時間戳:
t0
-
int32Values
:-
ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
- -3(逆時針方向三個煞車裝置)。
- 目標顯示。
- 第一和第二定位器之間為 5 ns。
- 第二個和第三個定位器之間為 3 ns。
-
中心按鈕
當使用者按下中心按鈕時,VHAL 應使用HW_KEY_INPUT
屬性和以下int32Values
將事件傳送到 Android:
-
ACTION_DOWN
-
KEYCODE_DPAD_CENTER
- 目標顯示。
當使用者釋放旋轉控制器時,VHAL 應使用與ACTION_UP
相同的屬性和鍵碼。
按住中心按鈕時不產生重複事件。
返回鍵
當使用者按下「後退」按鈕時,VHAL 應使用HW_KEY_INPUT
屬性和下列int32Values
將事件傳送到 Android:
-
ACTION_DOWN
-
KEYCODE_BACK
- 目標顯示。
當使用者釋放旋轉控制器時,VHAL 應使用與ACTION_UP
相同的屬性和鍵碼。
按住中心按鈕時不應產生重複事件。
主頁按鈕
像處理「後退」按鈕一樣處理「首頁」按鈕,但使用KEYCODE_HOME
而不是KEYCODE_BACK
。
其他按鈕
如果旋轉控制器包含任何附加按鈕,VHAL 可以以 OEM 喜歡的方式處理它們,因為從 Android 的角度來看,它們不被視為旋轉的一部分。這些按鈕通常像“後退”按鈕和“主頁”按鈕一樣處理,但使用不同的鍵碼。例如, KEYCODE_CALL
或KEYCODE_MUSIC
。
建置配置
旋轉導航由名為RotaryService
輔助服務提供。若要將此服務包含在您裝置的系統映像中,請將下列行新增至您的 makefile 中:
PRODUCT_PACKAGES += CarRotaryController
您可能還想在調試版本中包含以下包:
-
RotaryPlayground
旋轉的參考應用程式(請參閱RotaryPlayground )。 -
RotaryIME
示範旋轉 IME(請參閱輸入法編輯器)。 -
CarRotaryImeRRO
RotaryIME
的覆蓋層。
當裝置啟動和發生使用者切換時,旋轉服務會自動啟用。這可確保使用者可以在設定期間使用旋轉控制器。
如果您對帶有和不帶有旋轉控制器的汽車使用相同的構建,請添加如上所示的CarRotaryController
,以便在構建中包含必要的程式碼。若要防止在非旋轉汽車上啟用旋轉服務,請建立靜態 RRO,以使用空字串覆寫packages/services/Car/service
中的rotaryService
字串資源。您將使用相同的構建,但對於旋轉和非旋轉設備具有單獨的產品配置。只有後者包括覆蓋層。
客製化
OEM 可以透過以下位置的資源覆寫來自訂焦點尋找邏輯、焦點突出顯示和一些附加項目:
- car-ui-library 位於
packages/apps/Car/libs/car-ui-lib
-
RotaryService
位於packages/apps/Car/RotaryController
中 Core
位於frameworks/base/core
推動歷史
OEM 可以配置是否啟用兩種類型的微移歷史記錄中的每一種,如果啟用,則配置快取大小和過期策略。這一切都是透過覆蓋各種 car-ui-library 資源來完成的。
焦點歷史緩存
( Android 11 QPR3、Android 11 汽車、Android 12 )
每個FocusArea
快取將最近聚焦的視圖儲存在FocusArea
中,以便在微移回FocusArea
時可以將其聚焦。可以透過覆蓋以下 car-ui-library 資源來配置此快取:
-
car_ui_focus_history_cache_type
:- 快取已禁用。
- 快取將在一段時間後過期(見下文)。
- 緩存永遠不會過期。
-
car_ui_focus_history_expiration_period_ms
:如果快取類型設定為二 (2)(見上文),則快取過期前多少毫秒。
FocusArea歷史緩存
( Android 11 QPR3、Android 11 汽車、Android 12 )
此快取儲存微移的歷史記錄,以便相反方向的微移可以將焦點返回到同一FocusArea
。可以透過覆蓋以下 car-ui-library 資源來配置此快取:
-
car_ui_focus_area_history_cache_type
:- 快取已禁用。
- 快取會在一段時間後過期(見下文)。
- 快取永不過期。
-
car_ui_focus_area_history_expiration_period_ms
:如果快取類型設定為 2(見上文),則快取過期前多少毫秒。 -
car_ui_clear_focus_area_history_when_rotating
:當使用者旋轉控制器時是否廢棄快取。
迴轉
( Android 11 QPR3、Android 11 汽車、Android 12 )
OEM可以重寫RotaryService
中的兩個整數資源來指定旋轉是否有加速,例如滑鼠加速:
-
rotation_acceleration_3x_ms
:用於決定 Google 是否應加速控制器旋轉以實現旋轉煞車的時間間隔(以毫秒為單位)。如果本次旋轉定位與前一個旋轉定位的間隔小於該值,則視為三個旋轉定位。將其設定為 2147483647 以停用 3 倍加速。 -
rotation_acceleration_2x_ms
:與rotation_acceleration_3x_ms
類似。用於 2 倍加速。將其設定為2147483647
以停用 2 倍加速。
根據 VHAL 的要求,當每個旋轉煞車都有單獨的時間戳時,加速效果最佳。如果這些不可用, RotaryService
會假定旋轉煞車裝置是均勻分佈的。
/** * 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),
重點突出
OEM 可以覆蓋 Android 框架中的預設焦點突出顯示以及 car-ui-library 中的多個焦點突出顯示資源。
預設焦點突出顯示
Android 框架透過屬性selectableItemBackground
提供預設的焦點突出顯示。在Theme.DeviceDefault
中,此屬性引用Core
中的item_background.xml
。 OEM 可以覆寫item_background.xml
來變更預設焦點反白顯示可繪製物件。
這個可繪製物件通常應該是StateListDrawable
,它會根據不同的狀態組合調整背景,包括android:state_focused
和android:state_pressed
。當使用者使用旋轉控制器聚焦視圖時, android:state_focused
將為true
,但android:state_pressed
將為false
。如果使用者隨後按下旋轉控制器上的中央按鈕,則在使用者按住按鈕時android:state_focused
和android:state_pressed
都會為true
。當使用者釋放按鈕時,只有android:state_focused
會保持true
。
car-ui-library 使用衍生自Theme.DeviceDefault
的主題。因此,此覆蓋會影響使用此程式庫的應用程式以及使用從Theme.DeviceDefault
派生的任何主題的應用程式。它不會影響使用不相關主題的應用程序,例如Theme.Material
。
重點關注 car-ui-library 中的突出資源
OEM 可以覆蓋多個 car-ui-library 資源,以控制焦點突出顯示在具有非矩形(例如圓形或藥丸形)焦點突出顯示的視圖上以及使用並非從Theme.DeviceDefault
.這些資源應該重疊,以便焦點突出顯示與預設的焦點突出顯示可繪製一致。
( Android 11 QPR3、Android 11 汽車、Android 12 )
以下資源用於指示視圖何時獲得焦點但未按下:
-
car_ui_rotary_focus_fill_color
:填滿顏色。 -
car_ui_rotary_focus_stroke_color
:輪廓顏色。 -
car_ui_rotary_focus_stroke_width
:輪廓的厚度。
( Android 11 QPR3、Android 11 汽車、Android 12 )
以下資源用於指示視圖何時獲得焦點和按下:
-
car_ui_rotary_focus_pressed_fill_color
:填滿顏色。 -
car_ui_rotary_focus_pressed_stroke_color
:輪廓顏色。 -
car_ui_rotary_focus_pressed_stroke_width
:輪廓的厚度。
有時,按鈕會被賦予純色背景色以吸引使用者的注意,如範例所示。這可能會使焦點突出顯示難以看到。
在這種情況下,開發人員可以使用輔助色指定自訂焦點突出顯示:- ( Android 11 QPR3、Android 11 汽車、Android 12 )
car_ui_rotary_focus_fill_secondary_color
car_ui_rotary_focus_stroke_secondary_color
- (安卓12 )
car_ui_rotary_focus_pressed_fill_secondary_color
car_ui_rotary_focus_pressed_stroke_secondary_color
任何顏色都可以是透明的,並且任一尺寸都可以為零,例如,如果您只需要填充或只需要輪廓。
焦點區域突出顯示
( Android 11 QPR3、Android 11 汽車、Android 12 )
當 FocusArea 的後代之一獲得焦點時, FocusArea
可以繪製兩種類型的突出顯示。如果需要,兩者可以結合使用。此功能在 AOSP 中預設為停用狀態,但可以透過覆寫 car-ui-library 資源來啟用:
-
car_ui_enable_focus_area_foreground_highlight
:在FocusArea
及其後代的頂部繪製高亮顯示。在 AOSP 中,此可繪製物件是FocusArea
周圍的輪廓。 OEM 可以覆寫car_ui_focus_area_foreground_highlight
可繪製物件。 -
car_ui_enable_focus_area_background_highlight
:在FocusArea
頂部但在其後代後面繪製高亮顯示。在 AOSP 中,此可繪製物件是實心填充。 OEM 可以覆寫car_ui_focus_area_background_highlight
可繪製物件。
輸入法編輯器
輸入法編輯器 (IME) 是輸入法。例如,螢幕鍵盤。
( Android 11 QPR3、Android 11 汽車、Android 12 )
OEM 必須覆寫RotaryService
中的default_touch_input_method
字串資源,以指定基於觸控的 IME 的ComponentName
。例如,如果 OEM 使用 Android Automotive 提供的 IME,則應指定com.google.android.apps.automotive.inputmethod/.InputMethodService
。
( Android 11 QPR3、Android 11 汽車、Android 12 )
如果 OEM 專門為旋轉建立了 IME,則應在rotary_input_method
資源中指定其ComponentName
。如果此資源被覆寫,則每當使用者透過旋轉控制器的微移、旋轉和中心按鈕與主機互動時,都會使用指定的 IME。當使用者觸碰螢幕時,將使用先前的 IME。返回按鈕(以及旋轉控制器上的其他按鈕)對 IME 選擇沒有影響。如果此資源未覆蓋,則不會發生 IME 切換。 Carboard 不支援旋轉輸入法,因此如果 OEM 未提供旋轉輸入法,使用者將無法透過旋轉控制器輸入文字。
RotaryIME
是一個示範旋轉 IME。雖然很基本,但嘗試上述自動 IME 切換就足夠了。 RotaryIME
的原始碼可以在packages/apps/Car/tests/RotaryIME/
中找到。
螢幕外輕推
預設情況下,當使用者嘗試輕移螢幕邊緣時,不會發生任何事情。 OEM 可以透過指定以下任意組合來配置四個方向中每個方向應發生的情況:
- 由
AccessibilityService
定義的全域操作。例如,GLOBAL_ACTION_BACK
。 - 關鍵程式碼,例如
KEYCODE_BACK
。 - 啟動以 URL 表示的活動的意圖。
( Android 11 QPR3、Android 11 汽車、Android 12 )
這些是透過在RotaryService
中覆寫以下數組資源來指定的:
-
off_screen_nudge_global_actions
:當使用者向上、向下、向左或向右微移螢幕邊緣時要執行的全域操作數組。如果該陣列的相關元素為 -1,則不執行全域操作。 -
off_screen_nudge_key_codes
:當使用者向上、向下、向左或向右微移螢幕邊緣時注入的點擊事件的鍵代碼數組。如果此陣列的相關元素為 0 (KEYCODE_UNKNOWN
),則不會注入任何事件。 -
off_screen_nudge_intents
:當使用者向上、向下、向左或向右輕移螢幕邊緣時啟動活動的意圖陣列。如果該陣列的相關元素為空,則不會啟動任何活動。
其他配置
您應該覆蓋以下RotaryService
資源:
- ( Android 11 QPR3、Android 11 汽車、Android 12 )
config_showHeadsUpNotificationOnBottom
:布林值,表示平視通知是否應顯示在底部而不是頂部。該值必須與frameworks/base/packages/CarSystemUI/res/values/config.xml
中的config_showHeadsUpNotificationOnBottom
布林資源具有相同的值 - ( Android 11 QPR3、Android 11 汽車、Android 12 )
notification_headsup_card_margin_horizontal
:平視通知視窗的左右邊距。它必須與packages/apps/Car/Notification/res/values/dimens.xml
中的notification_headsup_card_margin_horizontal
ntal dimen 資源具有相同的值 - (安卓12 )
excluded_application_overlay_window_titles
:不應被視為覆蓋視窗的視窗標題陣列。這應包括代表TaskViews
或TaskDisplayAreas
的應用程式視窗的標題。預設情況下,此清單僅包含“地圖”。
您可以覆蓋以下RotaryService
資源:
- ( Android 11 QPR3、Android 11 汽車、Android 12 )
long_press_ms
:整數值,表示必須按住中心按鈕多少毫秒才能觸發長按。零表示應使用系統預設的長按逾時。這是預設值。