키 문자 맵 파일

키 문자 맵 파일(.kcm 파일)은 특수키를 포함하는 Android 키 코드 조합을 유니코드 문자로 매핑하는 역할을 합니다.

기기가 전체 키보드가 아니라 단지 특수 용도 전용임을 시스템에 알려야 하는 경우에는 기기별 키 레이아웃 파일이 키를 보유한 모든 내부(내장형) 입력 장치에 대해 필수입니다.

외부 키보드의 경우에는 기기별 키 레이아웃 파일이 선택사항이며 아예 필요 없는 경우도 많습니다. 시스템은 다수의 외부 키보드에 적합한 일반 키 문자 맵을 제공합니다.

기기별 키 레이아웃 파일이 없는 경우 시스템은 대신 기본값을 선택합니다.

위치

키 문자 맵 파일은 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: 모든 문자를 갖추고 있지만 키당 2개 이상의 문자가 포함되는 키보드입니다.

    이 키보드 유형은 보통 엄지 손가락을 이용한 입력을 위해 설계됩니다.

    KeyCharacterMap.PREDICTIVE에 해당합니다.

  • ALPHA: 모든 문자를 갖추고 있으며 일부 숫자를 보유할 수 있는 키보드입니다.

    알파벳 키보드는 직접적으로 텍스트 입력을 지원하지만 소규모 폼 팩터가 적용된 축소된 레이아웃을 보유할 수 있습니다. FULL 키보드와 달리 특수 온스크린 문자 선택기를 사용해야만 일부 기호에 액세스할 수 있습니다. 또한 속도와 정확성을 개선하기 위해 프레임워크에서 알파벳 키보드를 위한 특수 어포던스를 제공합니다(예: 자동 대문자화 및 전환/SHIFT 및 ALT 키 잠금).

    이 키보드 유형은 보통 엄지 손가락을 이용한 입력을 위해 설계됩니다.

  • FULL: 전체 PC 스타일의 키보드입니다.

    전체 키보드가 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' 동작에 할당됩니다. 마찬가지로 ctrl, alt, meta 속성이 모두 동시에 none 동작에 할당됩니다.

인식되는 속성은 다음과 같습니다.

  • label: 단일 문자로 구성되는 키에 실제로 출력되는 라벨을 지정합니다. 이는 KeyCharacterMap.getDisplayLabel 메서드에 의해 반환되는 값입니다.

  • number: 숫자 텍스트 뷰에 포커스가 맞춰진 경우의 동작(입력해야 하는 문자)을 지정합니다(예: 사용자가 전화번호를 입력하는 경우).

    콤팩트 키보드는 여러 기호를 단일 키로 결합하여 같은 키가 유형 '1''a' 또는 '#''q' 등에 사용되도록 하는 경우가 많습니다. 이러한 키에는 number 속성을 설정하여 어떤 기호를 숫자 컨텍스트에 입력해야 하는지 나타내야 합니다(있는 경우).

    일반적인 '숫자' 기호의 예로는 숫자 '0'~'9', '#', '+', '(', ')', ',', '.'가 있습니다.

  • base: 특수키를 누르지 않았을 때의 동작(입력해야 하는 문자)을 지정합니다.

  • <modifier> 또는 <modifier1>+<modifier2>+: 키를 눌렀고 지정된 모든 특수키가 활성 상태인 경우의 동작(입력해야 하는 문자)을 지정합니다.

    예를 들어 특수키 속성 shift는 LEFT SHIFT 또는 RIGHT SHIFT 특수키를 누르면 적용되는 동작을 지정합니다.

    마찬가지로 특수키 속성 rshift+ralt는 RIGHT SHIFT 및 RIGHT ALT 특수키를 함께 누르면 적용되는 동작을 지정합니다.

다음 특수키는 특수키 속성에서 인식됩니다.

  • shift: LEFT SHIFT 또는 RIGHT SHIFT 특수키를 누르면 적용됩니다.
  • lshift: LEFT SHIFT 특수키를 누르면 적용됩니다.
  • rshift: RIGHT SHIFT 특수키를 누르면 적용됩니다.
  • alt: LEFT ALT 또는 RIGHT ALT 특수키를 누르면 적용됩니다.
  • lalt: LEFT ALT 특수키를 누르면 적용됩니다.
  • ralt: RIGHT ALT 특수키를 누르면 적용됩니다.
  • ctrl: LEFT CONTROL 또는 RIGHT CONTROL 특수키를 누르면 적용됩니다.
  • lctrl: LEFT CONTROL 특수키를 누르면 적용됩니다.
  • rctrl: RIGHT CONTROL 특수키를 누르면 적용됩니다.
  • meta: LEFT META 또는 RIGHT META 특수키를 누르면 적용됩니다.
  • lmeta: LEFT META 특수키를 누르면 적용됩니다.
  • rmeta: RIGHT META 특수키를 누르면 적용됩니다.
  • sym: SYMBOL 특수키를 누르면 적용됩니다.
  • fn: FUNCTION 특수키를 누르면 적용됩니다.
  • capslock: CAPS LOCK 특수키를 누르면 적용됩니다.
  • numlock: NUM LOCK 특수키를 누르면 적용됩니다.
  • scrolllock: SCROLL LOCK 특수키를 누르면 적용됩니다.

속성이 나열되는 순서는 중요합니다. 시스템은 키를 동작에 매핑할 때 모든 관련 속성을 순서대로 스캔하며 적용 가능한 마지막 동작을 감지하여 반환합니다.

따라서 나중에 지정된 속성이 특정 키에 대해 앞서 지정된 속성보다 우선 적용됩니다.

동작

각 속성은 동작에 매핑됩니다. 가장 일반적인 동작은 문자 입력이지만 다른 동작도 있습니다.

인식되는 동작은 다음과 같습니다.

  • none: 문자를 입력하면 안 됩니다.

    이는 지정된 문자가 없는 경우의 기본 동작입니다. none 지정은 선택사항이지만 명확성을 개선합니다.

  • 'X': 지정된 문자 리터럴을 입력합니다.

    이 동작은 지정된 문자가 포커스가 맞춰진 텍스트 뷰에 입력되도록 합니다. 문자 리터럴은 ASCII 문자 또는 다음과 같은 이스케이프 시퀀스 중 하나일 수 있습니다.

    • '\\': 백슬래시 문자를 입력합니다.
    • '\n': 줄바꿈 문자를 입력합니다(ENTER/RETURN에 사용).
    • '\t': TAB 문자를 입력합니다.
    • '\'': 아포스트로피 문자를 입력합니다.
    • '\"': 따옴표 문자를 입력합니다.
    • '\uXXXX': XXXX에 의해 16진수 코드 포인트가 주어진 유니코드 문자를 입력합니다.
  • fallback <Android 키 코드 이름>: 애플리케이션에서 키를 처리하지 않는 경우 기본 작업을 실행합니다.

    이 동작은 애플리케이션이 지정된 키를 기본으로 처리하지 않는 경우 다른 키 누름을 시뮬레이션하게 만듭니다. 일부 애플리케이션에서 처리 방법을 모르는 새 키의 기본 동작을 지원하는 데 사용됩니다(예: ESCAPE 또는 numlock을 누르지 않는 경우의 숫자 키패드 키).

    대체 동작이 실행되면 애플리케이션은 2개의 키 누름을 수신합니다(원래 키와 선택된 대체 키에 대해 하나씩). 키를 놓는 동안 애플리케이션에서 원래 키를 처리하면 대체 키 이벤트가 취소됩니다(KeyEvent.isCanceledtrue를 반환함).

시스템에서 두 가지 특수 기능을 수행하기 위해 2개의 유니코드 문자를 예약합니다.

  • '\uef00': 이 동작이 실행되면 텍스트 뷰는 커서 앞의 문자 4개를 소비하고 제거한 후 이를 16진수 숫자로 변환하여 상응하는 유니코드 코드 포인트를 삽입합니다.

  • '\uef01': 이 동작이 실행되면 텍스트 뷰에 기타 기호가 포함된 문자 선택기 대화상자가 표시됩니다.

시스템은 다음과 같은 유니코드 문자를 발음 구별용 데드키 문자의 조합으로 인식합니다.

  • '\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보다 구체적인 경우를 대비하여 계속해서 후속 속성을 스캔하고 재정의합니다. 그러면 SHIFT + A를 누를 때도 적용되는 shift가 발생합니다. 따라서 시스템은 base 속성의 동작을 무시하도록 결정하고 shift 속성인 'A'(문자 A 입력)에 연결된 동작을 선택합니다.

이어서 시스템은 아무리 다른 속성이 이 키 누름에 적용되지 않더라도 계속해서 테이블을 스캔합니다(CAPS LOCK이 잠기지 않으며 CONTROL, ALT 또는 META 키가 눌리지 않음).

따라서 키 조합 SHIFT + A의 결과적인 동작은 'A'입니다.

CONTROL + A

이제 사용자가 A 및 CONTROL 키를 함께 눌렀을 때 어떤 결과가 발생할지 고려해 보겠습니다.

전과 마찬가지로 시스템은 속성 테이블을 스캔합니다. 시스템은 base 속성이 적용되었음을 인지하지만 이번에도 결국 control 속성에 도달할 때까지 스캔을 계속합니다. 이 과정에서 control 속성이 base 이후에 표시되므로 관련 동작이 base 동작보다 우선 적용됩니다.

따라서 키 조합 CONTROL + A의 결과적인 동작은 none입니다.

Esc

사용자가 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_00을 입력하도록 합니다. 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 버전은 다국어 키보드 또는 사용자가 선택 가능한 키보드 레이아웃의 향상된 지원을 제공할 수 있습니다.

유효성 검사

키 맵 유효성 검사 도구를 사용하여 키 문자 맵 파일의 유효성을 검사하세요.