鍵字元對應檔案

按鍵字元對應檔案 (.kcm 檔案) 負責將 Android 按鍵代碼組合與修飾符對應至 Unicode 字元。

對於所有內部 (內建) 輸入裝置 (含有按鍵),如果只是要告知系統該裝置僅用於特殊用途 (而非完整鍵盤),則必須提供裝置專屬的按鍵版面配置檔案。

針對外接鍵盤,裝置專屬的按鍵版面配置檔案為選用,通常不必提供。系統提供一般鍵字元對應表,適用於多數外接式鍵盤。

如果沒有可用的裝置專屬按鍵版面配置檔案,系統會改為選擇預設值。

位置

鍵盤字元對應檔案的所在位置可透過 USB 供應商、產品 (和選填的版本) ID 或輸入裝置名稱來判斷。

系統會依序查詢下列路徑。

  • /odm/usr/keychars/Vendor_XXXX_Product_XXXX_Version_XXXX.kcm
  • /vendor/usr/keychars/Vendor_XXXX_Product_XXXX_Version_XXXX.kcm
  • /system/usr/keychars/Vendor_XXXX_Product_XXXX_Version_XXXX.kcm
  • /data/system/devices/keychars/Vendor_XXXX_Product_XXXX_Version_XXXX.kcm
  • /odm/usr/keychars/Vendor_XXXX_Product_XXXX.kcm
  • /vendor/usr/keychars/Vendor_XXXX_Product_XXXX.kcm
  • /system/usr/keychars/Vendor_XXXX_Product_XXXX.kcm
  • /data/system/devices/keychars/Vendor_XXXX_Product_XXXX.kcm
  • /odm/usr/keychars/DEVICE_NAME.kcm
  • /vendor/usr/keychars/DEVICE_NAME.kcm
  • /system/usr/keychars/DEVICE_NAME.kcm
  • /data/system/devices/keychars/DEVICE_NAME.kcm
  • /odm/usr/keychars/Generic.kcm
  • /vendor/usr/keychars/Generic.kcm
  • /system/usr/keychars/Generic.kcm
  • /data/system/devices/keychars/Generic.kcm
  • /odm/usr/keychars/Virtual.kcm
  • /vendor/usr/keychars/Virtual.kcm
  • /system/usr/keychars/Virtual.kcm
  • /data/system/devices/keychars/Virtual.kcm

建構包含裝置名稱的檔案路徑時,裝置名稱中的所有字元 (除了 '0'-'9'、'a'-'z'、'A'-'Z'、'-' 或 '_') 都會替換為 '_'。

一般鍵字元對應檔案

系統提供名為 Generic.kcm 的特殊內建鍵盤文字對應檔案。這個按鍵字元對應表旨在支援各種標準外接式鍵盤。

請勿修改通用鍵字元對應表!

虛擬鍵字元對應檔案

系統提供名為 Virtual.kcm 的特殊內建鍵盤文字對應檔案,供虛擬鍵盤裝置使用。

虛擬鍵盤裝置是 ID 為 -1 的合成輸入裝置 (請參閱 KeyCharacterMap.VIRTUAL_KEYBOARD)。從 Android Honeycomb 3.0 開始,所有 Android 裝置都會提供這類裝置。虛擬鍵盤裝置的目的,是提供已知的內建輸入裝置,可用於透過 IME 或測試檢測工具,將按鍵動作插入應用程式,即使是沒有內建鍵盤的裝置也一樣。

虛擬鍵盤會採用完整的 QWERTY 鍵盤配置,且在所有裝置上都相同。這樣一來,應用程式就能使用虛擬鍵盤裝置插入按鍵,並一律取得相同的結果。

請勿修改虛擬鍵字元對應表!

語法

鍵盤字元對應檔案為純文字檔案,包含鍵盤類型宣告和一組鍵宣告。

鍵盤類型宣告

鍵盤類型宣告會說明鍵盤的整體行為。鍵盤文字對應檔案必須包含鍵盤類型宣告。為了清楚起見,通常會放在檔案頂端。

type FULL

系統可辨識下列鍵盤類型:

  • NUMERIC:數字 (12 鍵) 鍵盤。

    數字鍵盤支援使用多點觸控方式輸入文字。你可能需要多次輕觸按鍵,才能產生所需的字母或符號。

    這類鍵盤通常是為大拇指輸入而設計。

    對應至 KeyCharacterMap.NUMERIC

  • PREDICTIVE:鍵盤上有所有字母,但每個按鍵上的字母不只一個。

    這類鍵盤通常是為大拇指輸入而設計。

    對應至 KeyCharacterMap.PREDICTIVE

  • ALPHA:鍵盤上有所有字母,可能還有一些數字。

    字母鍵盤可直接輸入文字,但可能會採用小型板型規格的濃縮版版面配置。與 FULL 鍵盤不同,部分符號只能透過特殊的螢幕上字元挑選器存取。此外,為了提升輸入速度和準確度,架構會為字母鍵盤提供特殊操作元素,例如自動大寫和切換 / 鎖定 SHIFT 和 ALT 鍵。

    這類鍵盤通常是為大拇指輸入而設計。

  • FULL:完整的 PC 鍵盤。

    完整鍵盤的運作方式與電腦鍵盤相同。只要按下鍵盤上的按鍵,即可直接存取所有符號,不必使用螢幕上的支援功能或自動大寫等操作功能。

    這類鍵盤通常設計用於雙手輸入。

  • SPECIAL_FUNCTION:僅用於執行系統控制功能,而非輸入的鍵盤。

    特殊功能鍵盤只包含不顯示文字的按鍵,例如 HOME 和 POWER 鍵,這些按鍵實際上並未用於輸入。

Generic.kcmVirtual.kcm 鍵的字元對應表皆為 FULL 鍵盤。

鍵宣告

每個鍵宣告都包含關鍵字 key,後面接著 Android 鍵碼名稱、開啟大括號、一組屬性和行為,以及關閉大括號。

key A {
    label:                              'A'
    base:                               'a'
    shift, capslock:                    'A'
    ctrl, alt, meta:                    none
}

屬性

每個鍵屬性都會建立從鍵到行為的對應項目。為了讓鍵字符號對應檔案更精簡,您可以使用半形逗號將多個屬性對應至相同行為。

在上述範例中,系統會為 label 屬性指派 'A' 行為。同樣地,ctrlaltmeta 屬性都會同時指派 none 行為。

系統可辨識下列屬性:

  • label:指定實際印在按鍵上的標籤,如果按鍵僅包含一個字元。這是 KeyCharacterMap.getDisplayLabel 方法傳回的值。

  • number:指定數字文字檢視畫面獲得焦點時的行為 (應輸入的字元),例如使用者輸入電話號碼時。

    緊湊式鍵盤通常會將多個符號合併至單一按鍵,因此同一個按鍵可能會用來輸入 '1''a',或是 '#''q'。針對這些鍵,應設定 number 屬性,以指出在數字內容中應輸入哪個符號 (如果有的話)。

    部分常見的「數字」符號包括 '0''9''#''+''('')'',''.'

  • base:指定未按下修飾符時的行為 (應輸入的字元)。

  • <modifier> 或 <modifier1>+<modifier2>+...:指定按下鍵時的行為 (應輸入的字元),以及所有指定修飾符是否處於啟用狀態。

    舉例來說,修飾符屬性 shift 會指定在按下左 SHIFT 或右 SHIFT 修飾符時套用的行為。

    同樣地,修飾符屬性 rshift+ralt 會指定在同時按下 RIGHT SHIFT 和 RIGHT ALT 修飾符時套用的行為。

下列修飾符會在修飾符屬性中辨識:

  • shift:按下左 SHIFT 或右 SHIFT 修飾符時適用。
  • lshift:按下左 SHIFT 輔助鍵時套用。
  • rshift:按下右 SHIFT 輔助鍵時適用。
  • alt:按下左 ALT 或右 ALT 修飾符時適用。
  • lalt:按下左 ALT 輔助鍵時套用。
  • ralt:按下右 ALT 輔助鍵時套用。
  • ctrl:按下左控制鍵或右控制鍵輔助鍵時適用。
  • lctrl:按下左 CONTROL 輔助鍵時套用。
  • rctrl:按下右側控制鍵修飾符時套用。
  • meta:按下左側或右側 META 輔助鍵時套用。
  • lmeta:按下左側 META 輔助鍵時套用。
  • rmeta:按下右側 META 修飾鍵時適用。
  • sym:按下 SYMBOL 輔助鍵時適用。
  • fn:按下 FUNCTION 輔助鍵時套用。
  • capslock:大寫鍵修飾符已鎖定時適用。
  • numlock:當 NUM LOCK 輔助鍵處於鎖定狀態時,會套用此值。
  • scrolllock:當 SCROLL LOCK 修飾符鎖定時,會套用此值。

屬性列出的順序十分重要。將鍵對應至行為時,系統會依序掃描所有相關的屬性,並傳回最後找到的適用行為。

因此,後面指定的屬性會覆寫先前為特定金鑰指定的屬性。

行為

每個屬性都會對應至一項行為。最常見的行為是輸入字元,但也有其他行為。

系統會辨識下列行為:

  • none:請勿輸入任何字元。

    在未指定字元時,系統會採用這個預設行為。您可以選擇是否要指定 none,但這樣做可提高清晰度。

  • 'X':輸入指定的字元常值。

    這項行為會導致指定字元輸入至已聚焦的文字檢視畫面。字元值可以是任何 ASCII 字元,或下列逸出序列之一:

    • '\\':輸入反斜線字元。
    • '\n':輸入換行字元 (用於 Enter / Return 鍵)。
    • '\t':輸入 Tab 字元。
    • '\'':輸入撇號字元。
    • '\"':輸入引號字元。
    • '\uXXXX':輸入萬國碼字元,其碼點以 XXXX 的十六進制表示。
  • fallback <Android 鍵代碼名稱>:如果應用程式未處理鍵,則執行預設動作。

    這項行為會導致系統在應用程式未原生處理指定按鍵時,模擬按下其他按鍵。這項功能可支援新鍵的預設行為,但並非所有應用程式都知道如何處理,例如 ESCAPE 或數字鍵盤鍵 (在未按下 NumLock 的情況下)。

    執行備用行為時,應用程式會收到兩次按鍵:一個是原始按鍵,另一個是所選備用按鍵。如果應用程式在按下按鍵時處理原始按鍵,則備用按鍵事件將會取消 (KeyEvent.isCanceled 會傳回 true)。

系統會保留兩個 Unicode 字元來執行特殊功能:

  • '\uef00':執行此行為時,文字檢視畫面會使用並移除游標前四個字元,將其解讀為十六進位數字,並插入對應的 Unicode 代碼點。

  • '\uef01':執行此行為時,文字檢視畫面會顯示包含各種符號的字元挑選器對話方塊。

系統會將下列 Unicode 字元視為組合變音死鍵字元:

  • '\u0300':重音符。
  • '\u0301':尖音符。
  • '\u0302':揚抑符號。
  • '\u0303':波浪號。
  • '\u0308':變音符號。

當您輸入無效鍵後接著輸入其他字元時,系統會組合無效鍵和後續字元。舉例來說,如果使用者輸入重音符號死鍵,接著輸入字母「a」,結果就是「à」。

如要進一步瞭解無效鍵處理方式,請參閱 KeyCharacterMap.getDeadChar

留言

註解行以 '#' 開頭,並延伸至行尾。如下所示:

# A comment!

系統會忽略空行。

按鍵組合如何對應至行為

當使用者按下按鍵時,系統會查詢與該按鍵組合和目前按下的修飾鍵相關聯的行為。

SHIFT + A

假設使用者同時按下 A 和 SHIFT 鍵。系統會先找出與 KEYCODE_A 相關的屬性和行為組合。

key A {
    label:                              'A'
    base:                               'a'
    shift, capslock:                    'A'
    ctrl, alt, meta:                    none
}

系統會從第一個到最後一個,從左到右掃描屬性,並忽略特殊的 labelnumber 屬性。

遇到的第一個屬性是 base。無論按下哪些修飾符,base 屬性一律會套用至按鍵。除非覆寫下列屬性,否則它基本上會指定鍵的預設行為。由於 base 屬性會套用至此按鍵,系統會記錄其行為為 'a' (輸入字元 a)。

接著,系統會繼續掃描後續屬性,以便在任何屬性比 base 更具體且覆寫 base 時使用。它會遇到 shift,這也適用於按下 SHIFT + A 的按鍵。因此系統決定忽略 base 屬性的行為,並選擇與 shift 屬性相關聯的行為,也就是 'A' (輸入字元 A)。

接著,它會繼續掃描資料表,但不會將其他屬性套用至此按鍵 (大寫鎖定鍵未鎖定,且未按下 CONTROL 鍵、ALT 鍵和 META 鍵)。

因此,按鍵組合 SHIFT + A 的結果行為為 'A'

CONTROL + A

接著,請思考如果使用者同時按下 A 和 CONTROL 鍵,會發生什麼情況。

如先前所述,系統會掃描屬性表格。系統會注意到已套用 base 屬性,但也會繼續掃描,直到最終到達 control 屬性為止。在這種情況下,control 屬性會顯示在 base 之後,因此其行為會覆寫 base 行為。

因此,按下 CONTROL + A 鍵組合後,系統會顯示 none

ESCAPE 鍵

假設使用者按下 ESCAPE 鍵。

key ESCAPE {
    base:                               fallback BACK
    alt, meta:                          fallback HOME
    ctrl:                               fallback MENU
}

這次系統會取得行為 fallback BACK,也就是備用行為。由於沒有字元常值顯示,因此不會輸入任何字元。

處理鍵時,系統會先將 KEYCODE_ESCAPE 傳送至應用程式。如果應用程式未處理,系統會再次嘗試,但這次會根據備用行為的要求,將 KEYCODE_BACK 傳送至應用程式。

因此,支援 KEYCODE_ESCAPE 的應用程式可以直接處理,但其他不支援的應用程式則可執行備用動作,將鍵視為 KEYCODE_BACK

有或沒有 NUM LOCK 的 NUMPAD_0

數字鍵盤按鍵的解讀方式會因 NUM LOCK 鍵是否鎖定而有很大差異。

下列鍵宣告可確保在按下 NUM LOCK 時,KEYCODE_NUMPAD_0 會輸入 0。當未按下 NUM LOCK 時,系統會照常將按鍵傳送至應用程式,如果未處理,則會改為傳送備用按鍵 KEYCODE_INSERT

key NUMPAD_0 {
    label, number:                      '0'
    base:                               fallback INSERT
    numlock:                            '0'
    ctrl, alt, meta:                    none
}

如您所見,備用鍵宣告可大幅提升與舊版應用程式的相容性,這些應用程式無法辨識或直接支援完整 PC 風格鍵盤上的所有按鍵。

範例

完整鍵盤

# This is an example of part of a key character map file for a full keyboard
# include a few fallback behaviors for special keys that few applications
# handle themselves.

type FULL

key C {
    label:                              'C'
    base:                               'c'
    shift, capslock:                    'C'
    alt:                                '\u00e7'
    shift+alt:                          '\u00c7'
    ctrl, meta:                         none
}

key SPACE {
    label:                              ' '
    base:                               ' '
    ctrl:                               none
    alt, meta:                          fallback SEARCH
}

key NUMPAD_9 {
    label, number:                      '9'
    base:                               fallback PAGE_UP
    numlock:                            '9'
    ctrl, alt, meta:                    none
}

英數鍵盤

# This is an example of part of a key character map file for an alphanumeric
# thumb keyboard.  Some keys are combined, such as `A` and `2`.  Here we
# specify `number` labels to tell the system what to do when the user is
# typing a number into a dial pad.
#
# Also note the special character '\uef01' mapped to ALT+SPACE.
# Pressing this combination of keys invokes an on-screen character picker.

type ALPHA

key A {
    label:                              'A'
    number:                             '2'
    base:                               'a'
    shift, capslock:                    'A'
    alt:                                '#'
    shift+alt, capslock+alt:            none
}

key SPACE {
    label:                              ' '
    number:                             ' '
    base:                               ' '
    shift:                              ' '
    alt:                                '\uef01'
    shift+alt:                          '\uef01'
}

遊戲控制器

# This is an example of part of a key character map file for a game pad.
# It defines fallback actions that enable the user to navigate the user interface
# by pressing buttons.

type SPECIAL_FUNCTION

key BUTTON_A {
    base:                               fallback BACK
}

key BUTTON_X {
    base:                               fallback DPAD_CENTER
}

key BUTTON_START {
    base:                               fallback HOME
}

key BUTTON_SELECT {
    base:                               fallback MENU
}

相容性附註

在 Android Honeycomb 3.0 之前,Android 主要字元對應表是使用非常不同的語法指定,並在建構期間編譯為二進位檔案格式 (.kcm.bin)。

雖然新格式使用相同的擴充功能 .kcm,但語法卻截然不同 (且功能更強大)。

自 Android Honeycomb 3.0 起,所有 Android 鍵字符映射檔案都必須使用本文所述的新語法和純文字檔案格式。系統不支援舊版語法,因此無法辨識舊版 .kcm.bin 檔案。

語言附註

Android 目前不支援多語言鍵盤。此外,內建的通用鍵字元對應表會假設使用美式英文鍵盤配置。

如果原始設備製造商 (OEM) 的鍵盤是為其他語言設計,建議他們提供自訂按鍵字元對應表。

未來版本的 Android 可能會提供更完善的多語言鍵盤或使用者可選鍵盤版面配置支援功能。

驗證

請務必使用「Validate Keymaps」工具驗證鍵字元對應檔案。