터치 기기

Android는 스타일러스 기반 디지타이저 태블릿을 비롯한 다양한 터치 스크린과 터치패드를 지원합니다.

터치 스크린은 사용자가 화면의 항목을 직접 조작하는 듯이 느끼도록 디스플레이에 연결된 터치 기기입니다.

터치패드는 디지타이저 태블릿처럼 디스플레이와 연결되지 않은 터치 기기입니다. 터치패드는 일반적으로 사용자 인터페이스의 절대적 간접 위치나 동작 기반 컨트롤에 사용되거나 이를 가리키는 데 사용됩니다.

터치 기기에는 마우스 버튼과 비슷한 기능을 가진 버튼이 있을 수 있습니다.

경우에 따라서는 기본 터치 센서 기술에 따라 손가락이나 스타일러스 등의 여러 다양한 도구를 사용하여 터치 기기를 조작할 수도 있습니다.

터치 기기는 가상 키를 구현하는 데 사용되기도 합니다. 예를 들어 일부 Android 기기의 경우 터치 스크린 센서 영역이 디스플레이 가장자리 밖으로 확장되며 터치를 감지하는 키패드의 일부로 이중 용도를 제공합니다.

터치 기기는 무척 다양하므로 Android는 수많은 구성 속성에 의존하여 각 기기의 특성과 바람직한 동작을 설명합니다.

터치 기기 분류

입력 장치는 다음 조건을 둘 다 충족하는 경우 멀티터치 기기로 분류됩니다.

  • 입력 장치는 ABS_MT_POSITION_XABS_MT_POSITION_Y 절대 축의 존재를 보고합니다.
  • 입력 장치에는 게임패드 버튼이 없습니다. 이 조건은 MT 축의 코드와 중복되는 코드를 포함하는 축을 보고하는 특정 게임패드의 모호성을 해결합니다.

입력 장치는 다음 조건을 둘 다 충족하는 경우 원터치 기기로 분류됩니다.

  • 입력 장치는 멀티터치 기기로 분류되지 않습니다. 입력 장치는 원터치 기기나 멀티터치 기기로 분류되며 둘 다로 분류되는 경우는 없습니다.
  • 입력 장치는 ABS_XABS_Y 절대 축, BTN_TOUCH 키 코드가 있는지 보고합니다.

입력 장치가 터치 기기로 분류되면 가상 키의 존재가 기기의 가상 키 맵 파일 로드 시도에 의해 결정됩니다. 가상 키 맵이 제공되는 경우에는 기기의 키 레이아웃 파일도 로드됩니다. 이러한 파일의 위치와 형식에 관한 자세한 내용은 [가상 키 맵 파일](#virtual-key-map-files)을 참고하세요.

이어서 시스템은 터치 기기의 입력 장치 구성 파일을 로드합니다.

모든 내장 터치 기기에는 입력 장치 구성 파일이 있어야 합니다. 입력 장치 구성 파일이 없으면 시스템은 외장 USB 또는 블루투스 HID 터치 스크린 또는 터치패드와 같은 범용 터치 주변기기에 적절한 기본 구성을 선택합니다. 이러한 기본값은 내장 터치 스크린용으로 설계되지 않아 잘못된 동작이 발생할 수 있습니다.

입력 장치 구성이 로드되면 시스템은 입력 장치를 터치 스크린, 터치패드 또는 포인터 기기로 분류합니다.

  • 터치 스크린 기기는 화면의 객체를 직접적으로 조작하는 데 사용됩니다. 사용자가 스크린을 직접 터치하므로 시스템에는 조작되는 객체를 나타내기 위한 추가 어포던스가 필요하지 않습니다.
  • 터치패드 기기는 주어진 센서 영역의 터치에 관한 절대 위치 정보를 앱에 제공하는 데 사용됩니다. 이는 디지타이저 태블릿에 유용할 수 있습니다.
  • 포인터 기기는 커서를 사용하여 화면의 객체를 간접적으로 조작하는 데 사용됩니다. 손가락은 멀티터치 포인터 동작으로 해석됩니다. 스타일러스와 같은 다른 도구는 절대 위치를 사용하는 것으로 해석됩니다. 자세한 내용은 간접적 멀티터치 포인터 동작을 참고하세요.

다음 규칙은 입력 장치를 터치 스크린, 터치패드 또는 포인터 기기로 분류하는 데 사용됩니다.

  • touch.deviceType 속성이 설정되면 기기 유형이 표시된 대로 설정됩니다.
  • 입력 장치가 EVIOCGPROP ioctl을 통해 INPUT_PROP_DIRECT 입력 속성의 존재를 보고하는 경우 기기 유형이 터치 스크린으로 설정됩니다. 이 조건의 경우, 직접 입력 터치 기기가 역시 연결 상태인 디스플레이에 연결되어 있을 것으로 가정합니다.
  • 입력 장치가 EVIOCGPROP ioctl을 통해 INPUT_PROP_POINTER 입력 속성의 존재를 보고하는 경우 기기 유형이 포인터로 설정됩니다.
  • 입력 장치가 REL_X 또는 REL_Y 상대 축의 존재를 보고하는 경우에는 기기 유형이 터치패드로 설정됩니다. 이 조건은 마우스와 터치패드 둘 다로 구성되는 입력 장치의 모호성을 해결합니다. 이 경우 터치패드는 포인터를 제어하는 데 사용되지 않습니다. 마우스가 이미 포인터를 제어하기 때문입니다.
  • 나머지 경우에는 기기 유형이 포인터로 설정됩니다. 이러한 기본값을 사용하면 다른 특수 용도로 지정되지 않은 터치패드가 포인터를 제어하게 됩니다.

버튼

버튼은 앱에서 추가 기능을 실행하는 데 사용할 수 있는 선택적 컨트롤입니다. 터치 기기의 버튼은 마우스 버튼과 비슷하게 동작하며 주로 포인터 유형 터치 기기 또는 스타일러스와 함께 사용됩니다.

지원되는 버튼은 다음과 같습니다.

  • BTN_LEFT: MotionEvent.BUTTON_PRIMARY에 매핑됩니다.
  • BTN_RIGHT: MotionEvent.BUTTON_SECONDARY에 매핑됩니다.
  • BTN_MIDDLE: MotionEvent.BUTTON_MIDDLE에 매핑됩니다.
  • BTN_BACKBTN_SIDE: MotionEvent.BUTTON_BACK에 매핑됩니다. 또한 이 버튼을 누르면 키 누름과 키 코드 KeyEvent.KEYCODE_BACK가 합성됩니다.
  • BTN_FORWARDBTN_EXTRA: MotionEvent.BUTTON_FORWARD에 매핑됩니다. 또한 이 버튼을 누르면 키 누름과 키 코드 KeyEvent.KEYCODE_FORWARD가 합성됩니다.
  • BTN_STYLUS: MotionEvent.BUTTON_SECONDARY에 매핑됩니다.
  • BTN_STYLUS2: MotionEvent.BUTTON_TERTIARY에 매핑됩니다.

도구 및 도구 유형

도구는 터치 기기와 상호작용하는 데 사용되는 손가락, 스타일러스 또는 기타 주변기기입니다. 일부 터치 기기는 여러 유형의 도구를 구분할 수 있습니다.

MotionEvent API의 경우처럼 Android의 다른 영역에서는 도구를 포인터로 부르는 경우도 많습니다.

지원되는 도구 유형은 다음과 같습니다.

  • BTN_TOOL_FINGERMT_TOOL_FINGER: MotionEvent.TOOL_TYPE_FINGER에 매핑됩니다.
  • BTN_TOOL_PENMT_TOOL_PEN: MotionEvent.TOOL_TYPE_STYLUS에 매핑됩니다.
  • BTN_TOOL_RUBBER: MotionEvent.TOOL_TYPE_ERASER에 매핑됩니다.
  • BTN_TOOL_BRUSH: MotionEvent.TOOL_TYPE_STYLUS에 매핑됩니다.
  • BTN_TOOL_PENCIL: MotionEvent.TOOL_TYPE_STYLUS에 매핑됩니다.
  • BTN_TOOL_AIRBRUSH: MotionEvent.TOOL_TYPE_STYLUS에 매핑됩니다.
  • BTN_TOOL_MOUSE: MotionEvent.TOOL_TYPE_MOUSE에 매핑됩니다.
  • BTN_TOOL_LENS: MotionEvent.TOOL_TYPE_MOUSE에 매핑됩니다.
  • BTN_TOOL_DOUBLETAP, BTN_TOOL_TRIPLETAP, BTN_TOOL_QUADTAP: MotionEvent.TOOL_TYPE_FINGER에 매핑됩니다.

마우스 오버 대 터치 도구

도구는 터치 기기와 접촉하거나 범위 내에서 위에 마우스를 가져갈 수 있습니다. 일부 터치 기기는 터치 기기 위에 마우스 오버되는 도구의 존재를 감지할 수 없습니다. RF 기반 스타일러스 디지타이저와 같이 감지가 가능한 기기는 도구가 디지타이저의 제한된 범위 내에 있을 때 감지가 가능한 경우가 많습니다.

InputReader 구성요소는 터치 도구를 마우스 오버 도구와 구별합니다. 마찬가지로 터치 도구와 마우스 오버 도구는 서로 다른 방식으로 앱에 보고됩니다.

터치 도구는 MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE, MotionEvent.ACTION_DOWN, MotionEvent.ACTION_POINTER_DOWNMotionEvent.ACTION_POINTER_UP을 사용하여 터치 이벤트로 앱에 보고됩니다.

마우스 오버 도구는 MotionEvent.ACTION_HOVER_ENTER, MotionEvent.ACTION_HOVER_MOVEMotionEvent.ACTION_HOVER_EXIT를 사용하여 일반 모션 이벤트로 앱에 보고됩니다.

터치 기기 드라이버 요구사항

  • 터치 기기 드라이버는 지원하는 축과 버튼에 관한 축과 키 코드만 등록해야 합니다. 지원되지 않는 축이나 키 코드를 등록하면 기기 분류 알고리즘에 혼동이 발생하거나 시스템이 기기의 기능을 잘못 감지할 수 있습니다. 예를 들어 기기가 BTN_TOUCH 키 코드를 보고하면 시스템은 도구가 화면을 터치하는지 나타내기 위해 항상 BTN_TOUCH가 사용된다고 가정합니다. 따라서 BTN_TOUCH는 도구가 단순히 범위에 있고 마우스 오버 중임을 나타내는 데 사용되면 안 됩니다.
  • 원터치 기기는 다음과 같은 Linux 입력 이벤트를 사용합니다.
    • ABS_X: (필수) 도구의 X 좌표를 보고합니다.
    • ABS_Y: (필수) 도구의 Y 좌표를 보고합니다.
    • ABS_PRESSURE: (선택) 도구 끝에 적용된 실제 압력이나 터치 접점의 신호 강도를 보고합니다.
    • ABS_TOOL_WIDTH: (선택) 크로스 섹션 영역을 보고하거나 터치 접점 또는 도구 자체의 너비를 보고합니다.
    • ABS_DISTANCE: (선택) 터치 기기 표면부터 도구까지의 거리를 보고합니다.
    • ABS_TILT_X: (선택) X 축을 따르는 터치 기기 표면으로부터의 도구 기울기를 보고합니다.
    • ABS_TILT_Y: (선택) Y 축을 따르는 터치 기기 표면으로부터의 도구 기울기를 보고합니다.
    • BTN_TOUCH: (필수) 도구가 기기를 터치하고 있는지 나타냅니다.
    • BTN_LEFT, BTN_RIGHT, BTN_MIDDLE, BTN_BACK, BTN_SIDE, BTN_FORWARD, BTN_EXTRA, BTN_STYLUS, BTN_STYLUS2: (선택) 버튼 상태를 보고합니다.
    • BTN_TOOL_FINGER, BTN_TOOL_PEN, BTN_TOOL_RUBBER, BTN_TOOL_BRUSH, BTN_TOOL_PENCIL, BTN_TOOL_AIRBRUSH, BTN_TOOL_MOUSE, BTN_TOOL_LENS, BTN_TOOL_DOUBLETAP, BTN_TOOL_TRIPLETAP, BTN_TOOL_QUADTAP: (선택) 도구 유형을 보고합니다.
  • 멀티터치 기기는 다음과 같은 Linux 입력 이벤트를 사용합니다.
    • ABS_MT_POSITION_X: (필수) 도구의 X 좌표를 보고합니다.
    • ABS_MT_POSITION_Y: (필수) 도구의 Y 좌표를 보고합니다.
    • ABS_MT_PRESSURE: (선택) 도구 끝에 적용된 실제 압력이나 터치 접점의 신호 강도를 보고합니다.
    • ABS_MT_TOUCH_MAJOR: (선택) 터치 접점의 크로스 섹션 영역이나 터치 접점의 더 긴 크기의 길이를 보고합니다.
    • ABS_MT_TOUCH_MINOR: (선택) 터치 접점의 더 짧은 크기의 길이를 보고합니다. ABS_MT_TOUCH_MAJOR가 영역 측정을 보고 중인 경우에는 이 축을 사용하면 안 됩니다.
    • ABS_MT_WIDTH_MAJOR: (선택) 도구 자체의 크로스 섹션 영역 또는 도구 자체의 더 긴 크기의 길이를 보고합니다. 도구 자체의 크기를 알고 있지 않다면 이 축을 사용하지 마세요.
    • ABS_MT_WIDTH_MINOR: (선택) 도구 자체의 더 짧은 크기의 길이를 보고합니다. ABS_MT_WIDTH_MAJOR가 영역 측정을 보고 중이거나 도구 자체의 크기를 알 수 없는 경우에는 이 축을 사용하면 안 됩니다.
    • ABS_MT_ORIENTATION: (선택) 도구 방향을 보고합니다.
    • ABS_MT_DISTANCE: (선택) 터치 기기 표면부터 도구까지의 거리를 보고합니다.
    • ABS_MT_TOOL_TYPE: (선택) 도구 유형MT_TOOL_FINGER 또는 MT_TOOL_PEN으로 보고합니다.
    • ABS_MT_TRACKING_ID: (선택) 도구의 추적 ID를 보고합니다. 추적 ID는 음수가 아닌 임의의 정수입니다. 이 정수는 여러 도구가 활성화 상태일 때 각 도구를 별개로 식별하고 추적하는 데 사용됩니다. 예를 들어 여러 개의 손가락으로 기기를 터치하는 경우에는 손가락이 접촉을 유지하는 이상 각 손가락에 고유한 추적 ID가 할당되어야 합니다. 추적 ID는 연결된 도구가 범위를 벗어나면 다시 사용할 수 있습니다.
    • ABS_MT_SLOT: (선택) Linux 멀티터치 프로토콜 'B'를 사용할 때 도구의 슬롯 ID를 보고합니다. 자세한 내용은 Linux 멀티터치 프로토콜 문서를 참고하세요.
    • BTN_TOUCH: (필수) 도구가 기기를 터치하고 있는지 나타냅니다.
    • BTN_LEFT, BTN_RIGHT, BTN_MIDDLE, BTN_BACK, BTN_SIDE, BTN_FORWARD, BTN_EXTRA, BTN_STYLUS, BTN_STYLUS2: (선택) 버튼 상태를 보고합니다.
    • BTN_TOOL_FINGER, BTN_TOOL_PEN, BTN_TOOL_RUBBER, BTN_TOOL_BRUSH, BTN_TOOL_PENCIL, BTN_TOOL_AIRBRUSH, BTN_TOOL_MOUSE, BTN_TOOL_LENS, BTN_TOOL_DOUBLETAP, BTN_TOOL_TRIPLETAP, BTN_TOOL_QUADTAP: (선택) 도구 유형을 보고합니다.
  • 원터치 및 멀티터치 프로토콜의 축이 둘 다 정의된 경우에는 멀티터치 축만 사용되고 원터치 축은 무시됩니다.
  • ABS_X, ABS_Y, ABS_MT_POSITION_XABS_MT_POSITION_Y 축의 최솟값과 최댓값은 기기별 표면 단위에 속하는 기기 활성 영역의 경계를 정의합니다. 터치 스크린의 경우에는 활성 영역이 실제로 디스플레이를 덮는 터치 기기의 일부를 설명합니다.

    터치 스크린의 경우 시스템에서 표면 단위의 보고된 터치 위치를 자동으로 보간하여 다음 계산에 따라 디스플레이 픽셀의 터치 위치를 가져옵니다.

        displayX = (x - minX) * displayWidth / (maxX - minX + 1)
        displayY = (y - minY) * displayHeight / (maxY - minY + 1)
        

    터치 스크린은 보고된 활성 영역 밖의 터치를 보고할 수 있습니다.

    활성 영역 밖에서 시작된 터치는 앱으로 전달되지 않지만 가상 키에는 사용될 수 있습니다.

    활성 영역 내에서 시작되었거나 디스플레이 영역에 진입 후 이탈하는 터치는 앱으로 전달됩니다. 따라서 터치가 앱 경계 내에서 시작된 다음 활성 영역 밖으로 움직이면 앱은 음수이거나 디스플레이 경계를 벗어나는 디스플레이 좌표를 포함하는 터치 이벤트를 수신할 수 있습니다. 이것은 예상되는 동작입니다.

    터치 기기는 활성 영역의 경계에 터치 좌표를 고정해서는 안 됩니다. 활성 영역을 이탈하는 터치는 활성 영역 밖에 있는 것으로 보고되어야 하며, 나머지 경우에는 아예 보고되면 안 됩니다.

    예를 들어 사용자의 손가락이 터치 스크린 왼쪽 상단 근처를 터치하고 있는 경우에는 (minX, minY)의 좌표를 보고할 수 있습니다. 손가락이 계속해서 활성 영역 바깥으로 움직이는 경우 터치 스크린은 minX 및 minY보다 작은 구성요소를 포함하는 좌표를 보고해야 하거나(예: minX - 2, minY - 3) 아예 터치에 대한 보고를 중지해야 합니다. 즉, 사용자의 손가락이 실제로 활성 영역 밖을 터치할 때에는 터치 스크린이 (minX, minY)를 보고하면 안 됩니다.

    좌표를 디스플레이 가장자리에 고정하면 화면 가장자리 주변에 인위적인 하드 경계가 생성됩니다. 이러한 경계는 시스템이 디스플레이 영역의 경계에 진입하거나 이탈하는 모션을 원활하게 추적하지 못하게 합니다.

  • ABS_PRESSURE 또는 ABS_MT_PRESSURE에 의해 보고된 값은(보고된 경우) 도구가 기기를 터치할 때는 0이 아니어야 하고 터치하지 않을 때는 도구가 마우스 오버 중임을 나타낼 수 있도록 0이어야 합니다.

    압력 정보 보고는 선택사항이지만 가능하면 보고하는 것이 좋습니다. 앱은 압력 정보를 사용하여 압력 감지 드로잉 및 기타 효과를 구현할 수 있습니다.

  • ABS_TOOL_WIDTH, ABS_MT_TOUCH_MAJOR, ABS_MT_TOUCH_MINOR, ABS_MT_WIDTH_MAJOR 또는 ABS_MT_WIDTH_MINOR에 의해 보고된 값은 도구가 기기를 터치할 때는 0이 아니어야 하고 터치하지 않을 때는 0이어야 하지만 필수는 아닙니다. 예를 들어 터치 기기는 손가락 터치 접점의 크기는 측정할 수 있지만 스타일러스 터치 접점의 크기는 측정하지 못할 수도 있습니다.

    크기 정보 보고는 선택사항이지만 가능하면 보고하는 것이 좋습니다. 앱은 압력 정보를 사용하여 크기 감지 드로잉 및 기타 효과를 구현할 수 있습니다.

  • ABS_DISTANCE 또는 ABS_MT_DISTANCE에 의해 보고된 값은 도구가 기기를 터치할 때 0에 근접해야 합니다. 거리는 도구가 직접 접촉하지 않는 경우에도 0이 아닌 상태를 유지할 수 있습니다. 보고되는 정확한 값은 하드웨어가 거리를 측정하는 방식에 따라 다릅니다.

    거리 정보 보고는 선택사항이지만 가능하면 보고하는 것이 좋습니다.

  • ABS_TILT_XABS_TILT_Y에 의해 보고된 값은 도구가 기기와 수직을 이룰 경우 0이어야 합니다. 0이 아닌 기울기는 도구가 기울어져 있음을 나타냅니다.

    X 및 Y 축을 따르는 경사각은 수직 각도로 지정된 것으로 가정됩니다. 완벽한 수직을 이루는 중심점은 (max + min) / 2에 의해 각 축에 대해 부여됩니다. 중심점보다 작은 값은 위나 왼쪽으로 기울이기를 나타내며 중심점보다 큰 값은 아래나 오른쪽으로 기울이기를 나타냅니다.

    InputReader는 X 및 Y 기울이기 구성요소를 0~PI / 2라디안의 수직 경사각과 -PI~PI라디안의 평면 방향각으로 변환합니다. 이러한 표시 내용은 손가락 터치를 설명하는 데 사용되는 요소와 호환되는 방향 설명으로 이어집니다.

    기울이기 정보 보고는 선택사항이지만 스타일러스 기기에는 사용하는 것이 좋습니다.

  • ABS_MT_TOOL_TYPE에 의해 보고된 도구 유형은 BTN_TOOL_*에 의해 보고된 모든 도구 유형 정보를 대체합니다. 도구 유형 정보가 전혀 제공되지 않는 경우에는 도구 유형이 MotionEvent.TOOL_TYPE_FINGER로 기본 설정됩니다.

  • 도구는 다음 조건에 따라 활성인 것으로 판단됩니다.

    • 원터치 프로토콜을 사용 중일 때에는 BTN_TOUCH 또는 BTN_TOOL_*이 1인 경우에 도구가 활성 상태입니다.

      이 조건은 InputReader에 적어도 도구의 특성에 관한 어느 정도의 정보(예: 터치 여부 또는 최소한의 도구 유형)는 포함되어야 함을 의미합니다. 제공되는 정보가 없으면 도구는 비활성(범위 밖)인 것으로 가정됩니다.

    • 멀티터치 프로토콜 'A'를 사용 중일 때에는 도구가 가장 최근의 동기화 보고서에 표시될 때마다 활성 상태입니다. 동기화 보고서에 더 이상 표시되지 않는 도구는 더 이상 존재하지도 않습니다.
    • 멀티터치 프로토콜 'B'를 사용 중일 때에는 도구가 활성 슬롯이 있는 경우에 한해 활성 상태입니다. 슬롯이 제거되면 도구는 더 이상 존재하지 않습니다.
  • 도구는 다음 조건에 따라 마우스 오버 상태인 것으로 판단됩니다.
    • 도구가 BTN_TOOL_MOUSE 또는 BTN_TOOL_LENS인 경우 다음 조건 중 하나가 true이더라도 도구는 마우스 오버 상태가 아닙니다.
    • 도구가 활성 상태이고 드라이버가 압력 정보를 보고하며 보고된 압력이 0인 경우 도구는 마우스 오버 상태입니다.
    • 도구가 활성 상태이고 드라이버가 BTN_TOUCH 키 코드를 지원하며 BTN_TOUCH의 값이 0인 경우 도구는 마우스 오버 상태입니다.
  • InputReader는 멀티터치 프로토콜 'A' 및 'B'를 모두 지원합니다. 새 드라이버는 'B' 프로토콜을 사용해야 하지만 둘 다 작동하기는 합니다.
  • Android 4.0부터는 Linux 입력 프로토콜 사양을 준수하기 위해 터치 스크린 드라이버를 변경해야 할 수 있습니다.

    다음과 같이 변경해야 할 수 있습니다.

    • 비활성화(손가락이 '위'로 이동)된 도구는 후속 멀티터치 동기화 보고서에 더 이상 표시되면 안 됩니다. 모든 도구가 비활성화(모든 손가락이 '위'로 이동)되면 드라이버는 SYN_MT_REPORT에 이은 SYN_REPORT와 같은 빈 동기화 보고서 패킷을 전송해야 합니다.

      이전 버전의 Android에서는 'up' 이벤트가 압력 값 0을 전송하여 보고될 것으로 예상했습니다. 기존 동작은 Linux 입력 프로토콜 사양과 호환되지 않았으며 이제 더 이상 지원되지 않습니다.

    • 실제 압력 또는 신호 강도 정보는 ABS_MT_PRESSURE를 사용하여 보고해야 합니다.

      이전 버전의 Android는 ABS_MT_TOUCH_MAJOR에서 압력 정보를 가져왔습니다. 기존 동작은 Linux 입력 프로토콜 사양과 호환되지 않았으며 이제 더 이상 지원되지 않습니다.

    • 터치 크기 정보는 ABS_MT_TOUCH_MAJOR를 사용하여 보고해야 합니다.

      이전 버전의 Android는 ABS_MT_TOOL_MAJOR에서 크기 정보를 가져왔습니다. 기존 동작은 Linux 입력 프로토콜 사양과 호환되지 않았으며 이제 더 이상 지원되지 않습니다.

    터치 기기 드라이버에는 더 이상 Android 관련 맞춤설정이 필요 없습니다. Android는 표준 Linux 입력 프로토콜에 의존할 경우 수정되지 않은 드라이버를 사용하여 더욱 다양한 터치 주변기기(예: 외부 HID 멀티터치 터치 스크린)를 지원할 수 있습니다.

터치 기기 작동

다음은 Android의 터치 기기 작동에 관한 간단한 요약입니다.

  1. EventHubevdev 드라이버의 원본 이벤트를 읽습니다.
  2. InputReader는 원본 이벤트를 소비하고 각 도구의 위치 및 기타 특성에 관한 내부 상태를 업데이트하며 버튼 상태도 추적합니다.
  3. BACK 또는 FORWARD를 눌렀거나 손을 뗀 경우 InputReader는 키 이벤트에 관해 InputDispatcher에 알립니다.
  4. InputReader는 가상 키 누름이 발생했는지 파악합니다. 발생한 경우에는 키 이벤트에 관한 내용을 InputDispatcher에 알립니다.
  5. InputReader는 터치가 디스플레이의 경계 내에서 시작되었는지 파악합니다. 경계 내에서 시작된 경우에는 터치 이벤트에 관한 내용을 InputDispatcher에 알립니다.
  6. 터치 도구는 없지만 1개 이상의 마우스 오버 도구는 있는 경우 InputReader는 마우스 오버 이벤트에 관한 내용을 InputDispatcher에 알립니다.
  7. 기기 유형이 포인터인 경우 InputReader는 포인터 동작 감지를 실행하고 상황에 맞게 포인터와 스팟을 이동한 다음 포인터 이벤트에 관한 내용을 InputDispatcher에 알립니다.
  8. InputDispatcherWindowManagerPolicy를 사용하여, 이벤트를 전송해야 하는지 그리고 이벤트에 의해 기기의 절전 모드가 해제되어야 하는지를 결정합니다. 그러면 InputDispatcher는 이벤트를 적절한 앱에 전달합니다.

터치 기기 구성

터치 기기 동작은 기기의 축, 버튼, 입력 속성, 입력 장치 구성, 가상 키 맵 및 키 레이아웃에 의해 결정됩니다.

키보드 구성에 참여하는 파일에 관한 자세한 내용은 다음 섹션을 참고하세요.

속성

시스템은 터치 기기 동작을 구성하고 보정하기 위해 다수의 입력 장치 구성 속성에 의존합니다.

한 가지 이유는 터치 기기의 기기 드라이버가 기기별 단위를 사용하여 터치의 특성을 보고하는 경우가 잦기 때문입니다.

예를 들어 다수의 터치 기기는 내부 기기별 척도(예: 터치로 트리거된 총 센서 노드 수)를 사용하여 터치 접촉 영역을 측정합니다. 이러한 원본 크기 값이 앱에 의미가 없는 이유는 터치 기기 센서 노드의 실제 크기와 기타 특성에 관해 인지해야 하기 때문입니다.

시스템은 입력 장치 구성 파일에서 인코딩된 보정 매개변수를 사용하여 터치 기기가 보고한 값을 앱이 이해할 수 있는 좀 더 단순한 표준 표현으로 디코딩, 변환 및 정규화합니다.

문서화 규칙

문서화 목적을 위해 다음 규칙을 사용하여 보정 프로세스 도중 시스템에서 사용하는 값을 설명합니다.

원본 축 값

다음 표현식은 터치 기기 드라이버가 보고한 원본 값을 EV_ABS 이벤트로 나타냅니다.

raw.x
ABS_X 또는 ABS_MT_POSITION_X 축의 값입니다.
raw.y
ABS_Y 또는 ABS_MT_POSITION_Y 축의 값입니다.
raw.pressure
ABS_PRESSURE 또는 ABS_MT_PRESSURE 축의 값입니다. 없는 경우 0입니다.
raw.touchMajor
ABS_MT_TOUCH_MAJOR 축의 값입니다. 없는 경우 0입니다.
raw.touchMinor
ABS_MT_TOUCH_MINOR 축의 값입니다. 없는 경우 raw.touchMajor입니다.
raw.toolMajor
ABS_TOOL_WIDTH 또는 ABS_MT_WIDTH_MAJOR 축의 값입니다. 없는 경우 0입니다.
raw.toolMinor
ABS_MT_WIDTH_MINOR 축의 값입니다. 없는 경우 raw.toolMajor입니다.
raw.orientation
ABS_MT_ORIENTATION 축의 값입니다. 없는 경우 0입니다.
raw.distance
ABS_DISTANCE 또는 ABS_MT_DISTANCE 축의 값입니다. 없는 경우 0입니다.
raw.tiltX
ABS_TILT_X 축의 값입니다. 없는 경우 0입니다.
raw.tiltY
ABS_TILT_Y 축의 값입니다. 없는 경우 0입니다.

원본 축 범위

다음 표현식은 원본 값의 경계를 나타냅니다. 이는 각 축에 EVIOCGABS ioctl을 호출하여 획득됩니다.

raw.*.min
원본 축의 포괄적인 최솟값입니다.
raw.*.max
원본 축의 포괄적인 최댓값입니다.
raw.*.range
raw.*.max - raw.*.min과 같습니다.
raw.*.fuzz
원본 축의 정확도입니다. 예를 들어 fuzz = 1은 값이 +/- 1 단위로 정확함을 의미합니다.
raw.width
터치 영역의 포괄적인 너비로, raw.x.range + 1과 같습니다.
raw.height
터치 영역의 포괄적인 높이로, raw.y.range + 1과 같습니다.

출력 범위

다음 표현식은 출력 좌표계의 특성을 나타냅니다. 시스템은 선형 보간 유형을 사용하여 터치 기기가 사용하는 표면 단위의 터치 위치 정보를 앱에 보고되는 디스플레이 픽셀 등의 출력 단위로 변환합니다.

output.width
출력 너비입니다. 디스플레이에 연결된 터치 스크린의 경우에는 픽셀 단위의 디스플레이 너비입니다. 디스플레이에 연결되지 않은 터치패드의 경우 출력 너비가 raw.width와 같습니다. 이는 보간 유형이 실행되지 않음을 나타냅니다.
output.height
출력 높이입니다. 디스플레이에 연결된 터치 스크린의 경우에는 픽셀 단위의 디스플레이 높이입니다. 디스플레이에 연결되지 않은 터치패드의 경우 출력 높이가 raw.height와 같습니다. 이는 보간 유형이 실행되지 않음을 나타냅니다.
output.diag
출력 좌표계의 대각선 길이입니다. sqrt(output.width ^2 + output.height ^2)와 같습니다.

기본 구성

터치 입력 매퍼는 입력 장치 구성 파일에 다수의 구성 속성을 사용하여 보정 값을 지정합니다. 다음 표는 구성 속성의 몇몇 일반적인 용도를 설명합니다. 다른 모든 속성, 그리고 보정을 위해 속성이 사용되는 필드에 관한 설명은 다음 섹션을 참고하세요.

touch.deviceType

정의: touch.deviceType = touchScreen | touchPad | pointer | default

터치 기기 유형을 지정합니다.

  • 값이 touchScreen인 경우 터치 기기는 디스플레이에 연결된 터치 스크린입니다.

  • 값이 touchPad인 경우 터치 기기는 디스플레이에 연결되지 않은 터치패드입니다.

  • 값이 pointer인 경우 터치 기기는 디스플레이에 연결되지 않은 터치패드이며, 모션이 간접적 멀티터치 포인터 동작에 사용됩니다.

  • 값이 default인 경우 시스템에서 분류 알고리즘에 따라 자동으로 기기 유형을 감지합니다.

기기 유형이 터치 기기 동작에 영향을 미치는 방식에 관해 자세히 알아보려면 분류 섹션을 참고하세요.

Android 3 이하에서는 모든 터치 기기를 터치 스크린으로 가정했습니다.

touch.orientationAware

정의: touch.orientationAware = 0 | 1

터치 기기가 디스플레이 방향 변경 시 반응해야 하는지 지정합니다.

  • 값이 1인 경우 디스플레이 방향이 바뀔 때마다 터치 기기에 의해 보고된 터치 위치가 회전합니다.

  • 값이 0인 경우 터치 기기에 의해 보고된 터치 위치가 디스플레이 방향 변경에 따른 영향을 받지 않습니다.

기본값은 기기가 터치 스크린인 경우 1이며 아닌 경우 0입니다.

시스템은 내부 및 외부 터치 스크린과 디스플레이를 구분합니다. 방향을 인식하는 내부 터치 스크린은 내부 디스플레이의 방향에 따라 회전합니다. 방향을 인식하는 외부 터치 스크린은 외부 디스플레이의 방향에 따라 회전합니다.

방향 인식은 Nexus One과 같은 기기의 터치 스크린 회전을 지원하는 데 사용됩니다. 예를 들어 기기가 자연스러운 방향에서 시계 방향으로 90도 회전하면 터치 스크린 왼쪽 상단 절대 좌표 위치의 터치가 디스플레이 왼쪽 상단 회전된 좌표계의 터치로 보고되도록 터치의 절대 위치가 다시 매핑됩니다. 이 과정은 앱에서 시각적 요소를 그리기 위해 사용하는 동일한 좌표계로 터치가 보고되도록 진행됩니다.

Honeycomb 이전에는 모든 터치 기기가 방향을 인식한다고 가정했습니다.

touch.gestureMode

정의: touch.gestureMode = pointer | spots | default

포인터 동작의 프레젠테이션 모드를 지정합니다. 이 구성 속성은 터치 기기 유형이 포인터인 경우에만 관련성을 지닙니다.

  • 값이 pointer인 경우 터치패드 동작이 마우스 포인터와 비슷한 커서 방식으로 표현됩니다.

  • 값이 spots인 경우에는 터치패드 동작이 동작 중심을 나타내는 앵커, 그리고 각 손가락의 위치를 나타내는 원형 스팟으로 표현됩니다.

기본값은 INPUT_PROP_SEMI_MT 입력 속성이 설정된 경우 pointer, 설정되지 않은 경우 spots입니다.

X 및 Y 필드

X 및 Y 필드는 접촉 영역 중앙의 위치 정보를 제공합니다.

계산

계산은 간단하며, 터치 드라이버의 위치 정보가 출력 좌표계에 선형으로 보간됩니다.

xScale = output.width / raw.width
yScale = output.height / raw.height

If not orientation aware or screen rotation is 0 degrees:
output.x = (raw.x - raw.x.min) * xScale
output.y = (raw.y - raw.y.min) * yScale
Else If rotation is 90 degrees:
    output.x = (raw.y - raw.y.min) * yScale
    output.y = (raw.x.max - raw.x) * xScale
Else If rotation is 180 degrees:
    output.x = (raw.x.max - raw.x) * xScale
    output.y = (raw.y.max - raw.y) * yScale
Else If rotation is 270 degrees:
    output.x = (raw.y.max - raw.y) * yScale
    output.y = (raw.x - raw.x.min) * xScale
End If

touchMajor, touchMinor, toolMajor, toolMinor, 크기 필드

touchMajortouchMinor 필드는 접촉 영역의 대략적인 크기(출력 단위: 픽셀)를 설명합니다.

toolMajortoolMinor 필드는 도구 자체의 대략적인 크기(출력 단위: 픽셀)를 설명합니다.

size 필드는 터치 기기가 감지할 수 있는 최대 크기의 터치를 기준으로 하는 터치의 정규화된 크기를 설명합니다. 정규화된 최소 크기는 0.0(접점이 없거나 측정할 수 없음), 정규화된 최대 크기는 1.0(센서 영역이 포화됨)입니다.

대략적인 길이와 범위를 둘 다 측정할 수 있는 경우에는 touchMajor 필드에서 더 긴 크기를 지정하고 touchMinor 필드에서는 접촉 영역의 더 짧은 크기를 지정합니다. 접촉 영역의 대략적인 지름만 측정할 수 있는 경우에는 touchMajortouchMinor 필드가 같아집니다.

마찬가지로 toolMajor 필드는 더 긴 크기를 지정하며 toolMinor 필드는 도구의 크로스 섹션 영역의 더 짧은 크기를 지정합니다.

터치 크기는 사용할 수 없지만 도구 크기는 사용이 가능한 경우 도구 크기가 터치 크기와 같은 값으로 설정됩니다. 반대로 도구 크기를 사용할 수 없지만 터치 크기는 사용이 가능한 경우에는 터치 크기가 도구 크기와 같은 값으로 설정됩니다.

터치 기기는 다양한 방식으로 터치 크기와 도구 크기를 측정하거나 보고합니다. 현재 구현은 지름, 영역 및 표면 단위의 기하학적 경계 상자, 이렇게 세 가지 유형의 측정을 지원합니다.

정의: touch.size.calibration = none | geometric | diameter | area | default

터치 드라이버가 터치 크기와 도구 크기를 보고하는 데 사용하는 측정 유형을 지정합니다.

  • 값이 none인 경우 크기가 0으로 설정됩니다.

  • 값이 geometric인 경우 값이 위치와 같은 표면 단위로 지정되는 것으로 가정되므로 동일한 방식으로 조정됩니다.

  • 값이 diameter인 경우 크기가 터치 또는 도구의 지름(너비)에 비례하는 것으로 가정됩니다.

  • 값이 area인 경우 크기가 터치 또는 도구의 면적에 비례하는 것으로 간주됩니다.

  • 값이 default면 시스템은 raw.touchMajor 또는 raw.toolMajor 축이 있는 경우 geometric 보정, 없는 경우에는 none 보정을 사용합니다.

touch.size.scale

정의: touch.size.scale = <음수가 아닌 부동 소수점 수>

보정에 사용되는 상수 배율을 지정합니다.

기본값은 1.0입니다.

touch.size.bias

정의: touch.size.bias = <음수가 아닌 부동 소수점 수>

보정에 사용되는 상수 바이어스 값을 지정합니다.

기본값은 0.0입니다.

touch.size.isSummed

정의: touch.size.isSummed = 0 | 1

크기가 모든 활성 접촉의 크기를 더한 값으로 보고되는지 아니면 각 접촉에 관해 개별적으로 보고되는지 지정합니다.

  • 값이 1이면 보고된 크기는 사용 전 접촉 수로 나뉩니다.

  • 값이 0이면 보고된 크기는 그대로 사용됩니다.

기본값은 0입니다.

특히 '반 MT' 기기를 비롯한 일부 터치 기기는 여러 접촉의 개별적인 크기를 구분할 수 없으므로 총 면적이나 너비를 나타내는 크기 측정을 보고합니다. 이러한 기기의 경우 속성을 1로만 설정해야 합니다. 확실하지 않은 경우에는 이 값을 0으로 설정합니다.

계산

touchMajor, touchMinor, toolMajor, toolMinor, size 필드의 계산은 지정된 보정 매개변수에 따라 다릅니다.

If raw.touchMajor and raw.toolMajor are available:
    touchMajor = raw.touchMajor
    touchMinor = raw.touchMinor
    toolMajor = raw.toolMajor
    toolMinor = raw.toolMinor
Else If raw.touchMajor is available:
    toolMajor = touchMajor = raw.touchMajor
    toolMinor = touchMinor = raw.touchMinor
Else If raw.toolMajor is available:
    touchMajor = toolMajor = raw.toolMajor
    touchMinor = toolMinor = raw.toolMinor
Else
    touchMajor = toolMajor = 0
    touchMinor = toolMinor = 0
    size = 0
End If

size = avg(touchMajor, touchMinor)

If touch.size.isSummed == 1:
    touchMajor = touchMajor / numberOfActiveContacts
    touchMinor = touchMinor / numberOfActiveContacts
    toolMajor = toolMajor / numberOfActiveContacts
    toolMinor = toolMinor / numberOfActiveContacts
    size = size / numberOfActiveContacts
End If

If touch.size.calibration == "none":
    touchMajor = toolMajor = 0
    touchMinor = toolMinor = 0
    size = 0
Else If touch.size.calibration == "geometric":
    outputScale = average(output.width / raw.width, output.height / raw.height)
    touchMajor = touchMajor * outputScale
    touchMinor = touchMinor * outputScale
    toolMajor = toolMajor * outputScale
    toolMinor = toolMinor * outputScale
Else If touch.size.calibration == "area":
    touchMajor = sqrt(touchMajor)
    touchMinor = touchMajor
    toolMajor = sqrt(toolMajor)
    toolMinor = toolMajor
Else If touch.size.calibration == "diameter":
    touchMinor = touchMajor
    toolMinor = toolMajor
End If

If touchMajor != 0:
    output.touchMajor = touchMajor * touch.size.scale + touch.size.bias
Else
    output.touchMajor = 0
End If

If touchMinor != 0:
    output.touchMinor = touchMinor * touch.size.scale + touch.size.bias
Else
    output.touchMinor = 0
End If

If toolMajor != 0:
    output.toolMajor = toolMajor * touch.size.scale + touch.size.bias
Else
    output.toolMajor = 0
End If

If toolMinor != 0:
    output.toolMinor = toolMinor * touch.size.scale + touch.size.bias
Else
    output.toolMinor = 0
End If

output.size = size

압력 필드

pressure 필드는 0.0(터치 없음)~1.0(최대 압력)의 정규화된 값으로 터치 기기에 적용된 대략적인 실제 압력을 설명합니다.

압력이 0인 경우 도구가 마우스 오버 상태임을 나타냅니다.

touch.pressure.calibration

정의: touch.pressure.calibration = none | physical | amplitude | default

터치 드라이버가 압력을 보고하기 위해 사용하는 측정 유형을 지정합니다.

  • 값이 none인 경우 압력을 알 수 없습니다. 따라서 터치 시에는 1.0, 마우스 오버 시에는 0.0으로 설정됩니다.

  • 값이 physical인 경우 압력 축이 터치패드에 적용되는 압력의 실제 강도를 측정하는 것으로 가정됩니다.

  • 값이 amplitude인 경우 압력 축이 접촉 크기와 적용된 압력과 관련성을 가지는 신호 진폭을 측정하는 것으로 가정됩니다.

  • 값이 default이면 시스템에서 압력 축을 사용할 수 있는 경우 physical 보정을, 사용할 수 없는 경우 none을 사용합니다.

touch.pressure.scale

정의: touch.pressure.scale = <음수가 아닌 부동 소수점 수>

보정에 사용되는 상수 배율을 지정합니다.

기본값은 1.0 / raw.pressure.max입니다.

계산

pressure 필드의 계산은 지정된 보정 매개변수에 따라 다릅니다.

If touch.pressure.calibration == "physical" or "amplitude":
    output.pressure = raw.pressure * touch.pressure.scale
Else
    If hovering:
        output.pressure = 0
    Else
        output.pressure = 1
    End If
End If

방향 및 기울이기 필드

orientation 필드는 터치와 도구의 방향을 각 측정으로 설명합니다. 0의 방향은 주요 축이 수직 방향임을 나타내고 -PI/2는 주요 축이 왼쪽 방향임을 나타내며 PI/2는 주요 축이 오른쪽 방향임을 나타냅니다. 스타일러스 도구가 있는 경우 방향 범위가 -PI 또는 PI의 전체 원 범위로 설명될 수 있습니다.

tilt 필드는 도구의 경사도를 각 측정으로 설명합니다. 0의 기울기는 도구가 Surface에 대해 수직임을 나타냅니다. PI/2의 기울기는 도구가 표면에서 수평임을 나타냅니다.

touch.orientation.calibration

정의: touch.orientation.calibration = none | interpolated | vector | default

터치 드라이버가 방향을 보고하기 위해 사용하는 측정 유형을 지정합니다.

  • 값이 none인 경우 방향을 알 수 없으므로 0으로 설정됩니다.
  • 값이 interpolated인 경우 raw.orientation.min의 원본 값이 -PI/2에, raw.orientation.max의 원본 값이 PI/2에 매핑되도록 방향이 선형으로 보간됩니다. (raw.orientation.min + raw.orientation.max) / 2의 중심값은 0에 매핑됩니다.
  • 값이 vector인 경우 방향이 2개의 서명된 4비트 필드로 이루어진 가득 찬 벡터로 해석됩니다. 이러한 표현은 Atmel 객체 기반 프로토콜의 일부에 사용됩니다. 벡터는 디코딩될 때 방향각과 신뢰도를 생성합니다. 신뢰도는 크기 정보를 조정하는 데 사용되며 기하학적 정보는 예외입니다.
  • 값이 default이면 시스템에서 방향 축을 사용할 수 있는 경우 interpolated 보정을, 사용할 수 없는 경우 none을 사용합니다.

계산

orientationtilt 필드 계산은 지정된 보정 매개변수와 가용한 입력에 따라 다릅니다.

If touch.tiltX and touch.tiltY are available:
    tiltXCenter = average(raw.tiltX.min, raw.tiltX.max)
    tiltYCenter = average(raw.tiltY.min, raw.tiltY.max)
    tiltXAngle = (raw.tiltX - tiltXCenter) * PI / 180
    tiltYAngle = (raw.tiltY - tiltYCenter) * PI / 180
    output.orientation = atan2(-sin(tiltXAngle), sinf(tiltYAngle))
    output.tilt = acos(cos(tiltXAngle) * cos(tiltYAngle))
Else If touch.orientation.calibration == "interpolated":
    center = average(raw.orientation.min, raw.orientation.max)
    output.orientation = PI / (raw.orientation.max - raw.orientation.min)
    output.tilt = 0
Else If touch.orientation.calibration == "vector":
    c1 = (raw.orientation & 0xF0) >> 4
    c2 = raw.orientation & 0x0F

    If c1 != 0 or c2 != 0:
        If c1 >= 8 Then c1 = c1 - 16
        If c2 >= 8 Then c2 = c2 - 16
        angle = atan2(c1, c2) / 2
        confidence = sqrt(c1*c1 + c2*c2)

        output.orientation = angle

        If touch.size.calibration == "diameter" or "area":
            scale = 1.0 + confidence / 16
            output.touchMajor *= scale
            output.touchMinor /= scale
            output.toolMajor *= scale
            output.toolMinor /= scale
        End If
    Else
        output.orientation = 0
    End If
    output.tilt = 0
Else
    output.orientation = 0
    output.tilt = 0
End If

If orientation aware:
    If screen rotation is 90 degrees:
        output.orientation = output.orientation - PI / 2
    Else If screen rotation is 270 degrees:
        output.orientation = output.orientation + PI / 2
    End If
End If

거리 필드

distance 필드는 도구와 터치 기기 표면 간의 거리를 설명합니다. 값 0.0은 직접 접촉을, 더 큰 값은 표면으로부터의 증가하는 거리를 나타냅니다.

touch.distance.calibration

정의: touch.distance.calibration = none | scaled | default

터치 드라이버가 거리를 보고하기 위해 사용하는 측정 유형을 지정합니다.

  • 값이 none인 경우 거리를 알 수 없으므로 0으로 설정됩니다.

  • 값이 scaled인 경우 보고된 거리가 상수 배율로 곱하기됩니다.

  • 값이 default이면 시스템에서 거리 축을 사용할 수 있는 경우 scaled 보정을, 사용할 수 없는 경우 none을 사용합니다.

touch.distance.scale

정의: touch.distance.scale = <음수가 아닌 부동 소수점 수>

보정에 사용되는 상수 배율을 지정합니다.

기본값은 1.0입니다.

계산

distance 필드의 계산은 지정된 보정 매개변수에 따라 다릅니다.

If touch.distance.calibration == "scaled":
    output.distance = raw.distance * touch.distance.scale
Else
    output.distance = 0
End If

# Input device configuration file for a touch screen that supports pressure,
# size and orientation. The pressure and size scale factors were obtained
# by measuring the characteristics of the device itself and deriving
# useful approximations based on the resolution of the touch sensor and the
# display.
#
# Note that these parameters are specific to a particular device model.
# Different parameters need to be used for other devices.

# Basic Parameters
touch.deviceType = touchScreen
touch.orientationAware = 1

# Size
# Based on empirical measurements, we estimate the size of the contact
# using size = sqrt(area) * 28 + 0.
touch.size.calibration = area
touch.size.scale = 28
touch.size.bias = 0
touch.size.isSummed = 0

# Pressure
# Driver reports signal strength as pressure.
#
# A normal index finger touch typically registers about 80 signal strength
# units although we don't expect these values to be accurate.
touch.pressure.calibration = amplitude
touch.pressure.scale = 0.0125

# Orientation
touch.orientation.calibration = vector

호환성 정보

Android Ice Cream Sandwich 4.0에서는 터치 기기의 구성 속성이 크게 변경되었으며, 터치 기기의 모든 입력 장치 구성 파일이 새 구성 속성을 사용하도록 업데이트해야 합니다.

기존 터치 기기 드라이버도 업데이트해야 할 수 있습니다.

가상 키 맵 파일

터치 기기는 가상 키를 구현하는 데 자주 사용됩니다.

터치 컨트롤러의 기능에 따라 다양한 구현 방식이 존재합니다. 일부 터치 컨트롤러는 펌웨어 레지스터를 설정하여 소프트 키를 구현하도록 직접적으로 구성할 수 있습니다. 또한 터치 좌표에서 소프트웨어의 키 코드로의 매핑을 실행하는 것이 적합한 경우도 있습니다.

소프트웨어에 가상 키가 구현되면 커널은 virtualkeys.<devicename>이라는 가상 키 맵 파일을 보드 속성으로 내보내야 합니다. 예를 들어 터치 스크린 기기 드라이버가 이름을 'touchyfeely'로 보고하는 경우에는 가상 키 맵 파일에 경로 /sys/board_properties/virtualkeys.touchyfeely가 있어야 합니다.

가상 키 맵 파일은 터치 스크린에 있는 가상 키의 좌표와 Linux 키 코드를 설명합니다.

또한 가상 키 맵 파일 외에 Linux 키 코드를 Android 키 코드에 매핑하고 키보드 기기의 유형(보통 SPECIAL_FUNCTION)을 지정하기 위한 일치하는 키 레이아웃 파일과 키 문자 맵 파일도 있어야 합니다.

구문

가상 키 맵 파일은 줄바꿈이나 콜론으로 구분된 가상 키 레이아웃 설명의 시퀀스로 구성된 일반 텍스트 파일입니다.

주석 행은 '#'으로 시작하여 행 끝까지 계속됩니다.

각 가상 키는 콜론으로 구분된 6개의 구성요소로 설명됩니다.

  • 0x01: 버전 코드입니다. 항상 0x01이어야 합니다.
  • <Linux key code>: 가상 키의 Linux 키 코드입니다.
  • <centerX>: 가상 키 중심의 X픽셀 좌표입니다.
  • <centerY>: 가상 키 중심의 Y픽셀 좌표입니다.
  • <width>: 가상 키의 너비(픽셀)입니다.
  • <height>: 가상 키의 높이(픽셀)입니다.

모든 좌표와 크기는 디스플레이 좌표계와 관련하여 지정됩니다.

다음은 한 개의 행에 모든 내용이 작성된 가상 키 맵 파일입니다.

# All on one line
0x01:158:55:835:90:55:0x01:139:172:835:125:55:0x01:102:298:835:115:55:0x01:217:412:835:95:55

같은 가상 키 맵 파일을 여러 행에 작성할 수도 있습니다.

# One key per line
0x01:158:55:835:90:55
0x01:139:172:835:125:55
0x01:102:298:835:115:55
0x01:217:412:835:95:55

위의 예에서는 터치 스크린의 해상도가 480x800입니다. 따라서 모든 가상 키의 <centerY> 좌표가 835이며, 이는 터치 스크린의 가시 영역에 약간 못 미치는 수치입니다.

첫 번째 키에는 158의 Linux 스캔 코드(KEY_BACK), 55의 centerX, 835의 centerY, 90의 너비와 55의 높이가 포함됩니다.

가상 키 맵 파일: /sys/board_properties/virtualkeys.touchyfeely.

0x01:158:55:835:90:55
0x01:139:172:835:125:55
0x01:102:298:835:115:55
0x01:217:412:835:95:55

키 레이아웃 파일: /system/usr/keylayout/touchyfeely.kl.

key 158 BACK
key 139 MENU
key 172 HOME
key 217 SEARCH

키 문자 맵 파일: /system/usr/keychars/touchyfeely.kcm

type SPECIAL_FUNCTION

간접 멀티터치 포인터 동작

포인터 모드에서는 시스템이 다음과 같은 동작을 해석합니다.

  • 한 손가락으로 탭: 클릭
  • 한 손가락의 움직임: 포인터 이동.
  • 한 손가락의 움직임 및 버튼 누름: 포인터 드래그
  • 두 손가락의 움직임(두 손가락 모두 같은 방향으로 움직임): 포인터 아래의 영역을 그 방향으로 이동. 포인터 자체는 움직이지 않습니다.
  • 두 손가락의 움직임(두 손가락 모두 서로를 향해 움직이거나 서로 다른 방향으로 움직임): 포인터 주변 영역 이동/확대/축소/회전. 포인터 자체는 움직이지 않습니다.
  • 여러 손가락의 움직임: 자유 동작

손바닥 움직임 무시

Android 13부터, 내장 프레임워크가 사용 설정되면 시스템에서 손바닥의 입력을 자동으로 거부할 수 있습니다. 사내에서 빌드된 커스텀 솔루션은 계속 지원되지만, 손바닥이 감지되면 TOOL_TYPE_PALM 플래그를 반환하도록 수정해야 할 수 있습니다. 내장 프레임워크는 맞춤 솔루션과 함께 사용할 수도 있습니다.

실제 모델은 처음 90밀리초의 동작 데이터, 현재 포인터, 주변 포인터를 살펴본 후 터치가 디스플레이 가장자리에서 얼마나 떨어져 있는지를 고려합니다. 그런 다음 포인터별로 어느 포인터가 손바닥인지를 판단합니다. touchMajortouchMinor에서 보고하는 각 접촉의 크기도 고려합니다. 그러면 Android 프레임워크가 손바닥이라고 표시된 포인터를 터치 스트림에서 삭제합니다.

포인터가 앱으로 이미 전송된 경우 시스템은 다음 중 하나를 실행합니다.

  • (다른 활성 포인터가 있는 경우) ACTION_POINTER_UPFLAG_CANCELED가 설정된 포인터를 취소합니다.
  • (이것이 유일한 포인터인 경우) ACTION_CANCEL을 사용하여 포인터를 취소합니다.

공개 API인 MotionEvent.FLAG_CANCELED는 현재 이벤트가 사용자 동작을 트리거해서는 안 된다는 것을 나타냅니다. 이 플래그는 ACTION_CANCELACTION_POINTER_UP 양쪽에 대해 설정됩니다.

손바닥 포인터가 앱으로 전송되지 않은 경우에는 시스템에서 포인터가 삭제됩니다.

손바닥 움직임 무시 사용 설정하기

  1. 터치 드라이버에서 input_abs_set_res 매크로를 사용하여 다음 필드의 해상도를 설정합니다(단위는 밀리미터당 픽셀).
    • ABS_MT_POSITION_X
    • ABS_MT_POSITION_Y
    • ABS_MT_TOUCH_MAJOR
    • ABS_MT_TOUCH_MINOR

    ABS_MT_TOUCH_MINOR 지원은 선택사항입니다. 단, 기기가 ABS_MT_TOUCH_MINOR를 지원하는 경우에는 해상도를 알맞게 설정해야 합니다.

  2. 필드가 알맞게 설정되었는지 확인하려면 다음을 실행합니다.
        $ adb shell getevent -li
    
  3. 런타임 중에 이 기능을 사용 설정하려면 다음을 실행합니다.
        $ adb shell device_config put input_native_boot palm_rejection_enabled 1
    
  4. system_server 프로세스를 다시 시작합니다.
         $ adb shell stop && adb shell start
        
  5. adb shell dumpsys input에서 UnwantedInteractionBlocker 내부에 손바닥 움직임 무시 동작이 있다고 표시되는지 확인합니다. 그렇지 않은 경우 입력 관련 로그를 확인하여 어느 항목이 잘못 구성되었는지 알아봅니다.

    다음 예시를 참고하세요.

    UnwantedInteractionBlocker:
      mEnablePalmRejection: true
      isPalmRejectionEnabled (flag value): true
      mPalmRejectors:
        deviceId = 3:
          mDeviceInfo:
            max_x = 
            max_y = 
            x_res = 11.00
            y_res = 11.00
            major_radius_res = 1.00
            minor_radius_res = 1.00
            minor_radius_supported = true
            touch_major_res = 1
            touch_minor_res = 1
          mSlotState:
            mSlotsByPointerId:
    
            mPointerIdsBySlot:
    
          mSuppressedPointerIds: {}
    
  6. 이 기능을 영구적으로 사용 설정하려면 init**rc 파일에 대응되는 sysprop 명령어를 추가합니다.

    setprop persist.device_config.input_native_boot.palm_rejection_enabled 1
    

추가 자료