Chromebook 입력 호환성

노트북 사용자는 종종 스마트폰에서와 다른 입력 기기를 사용합니다.

Chromebook에서 실행되는 Android 앱은 최적화되지 않은 환경에 있으며 마우스, 터치패드 및 키보드가 장착된 노트북의 창 내부에 표시됩니다. Android는 이러한 기기를 지원하지만 앱에서 제대로 구현되는 경우는 거의 없습니다. 이러한 앱을 작동하기 위해 Chromebook은 기본적으로 모든 앱에 적용되는 호환성 모드를 사용합니다.

호환성 모드

호환성 모드에서는 Android API에서 이벤트를 제공하는 방식과 다르게 앱이 이벤트를 수신합니다. 이 모드는 Chromebook 관련 기능을 구현하고 싶지 않지만 터치 중심의 앱을 작동하려는 개발자에게 유용합니다.

호환성 모드에는 다음과 같은 동작이 도입되었습니다.

  • 터치패드 스크롤은 두 '손가락'을 사용한 터치 화면 스크롤을 에뮬레이션할 수 있습니다.
  • 마우스 휠 스크롤도 동일하게 작동할 수 있습니다.
  • 모든 측정 및 이벤트가 앱 창이 전체 화면으로 표시되는 것처럼 작동합니다. getRawXgetRawY와 같은 메서드는 화면 공간 좌표가 아니라 창 공간 좌표를 반환할 수 있습니다.

호환성 모드는 앱이 타겟팅하는 API 레벨에 따라 적절한 정도의 호환성 처리를 제공합니다.

android.hardware.type.pc 사용

Chromebook에서 실행되도록 앱을 최적화하고 입력 기기를 효율적으로 사용하려면 앱 manifest에서 다음을 선언하세요.

<uses-feature
        android:name="android.hardware.type.pc"
        android:required="false" />
    

이를 통해 일반적으로 키보드, 마우스 및 터치패드와 함께 사용되는 PC 기기를 타겟팅한다는 것을 Android에 알립니다. 호환성 모드를 사용 중지하고 마우스와 터치패드의 맞춤 동작을 개발할 수 있도록 합니다.

DecorCaptionView 주의사항

자유 형식 창 모드에서 앱 자막 표시줄은 뷰 계층 구조의 일부이며 제어할 수 있습니다. 일반적으로는 이 사항을 인지할 필요가 없지만 다음과 같이 주의해야 하는 경우가 있습니다.

  • Window.getDecorView()를 사용하지 마세요. 최상위 수준 뷰를 추가하려면 Activity.setContentView()로 설정한 뷰에 추가하세요.
  • Activity.setContentView()가 앱의 (0, 0)에 있지 않을 수도 있습니다. 자막 표시줄이 있는 위치입니다.
  • 가능하면 MotionEvent.getRawX() 또는 MotionEvent.getRawY()를 사용하지 마세요. 이러한 메서드를 사용하는 경우 View.getLocationOnScreen()과 함께 사용하여 좌표를 뷰 공간 좌표로 변환하세요.

입력 기기 지원

android.hardware.type.pc 플래그를 통해 PC 기기를 타겟팅하면 다음과 같은 이벤트가 발생할 수 있습니다.

마우스 및 터치패드 지원

마우스와 터치패드 모두 터치 이벤트와 같은 MotionEvents를 생성합니다. SOURCE_MOUSESOURCE_TOUCHSCREEN을 구별하려면 MotionEvent.getSource()를 확인하세요.

  • 마우스/터치패드 움직임: ACTION_HOVER_MOVE 이벤트를 생성합니다. 이러한 이벤트는 View.onGenericMotionEvent()에서 처리됩니다.
  • 마우스/터치패드 버튼: ACTION_BUTTON_PRESSACTION_BUTTON_RELEASE 이벤트를 View.onGenericMotionEvent()에 전송합니다. getButtonState()를 사용하여 모든 마우스/터치패드 이벤트에서 누른 버튼을 확인할 수도 있습니다.
  • 터치패드 스크롤: 터치패드에서 두 손가락을 사용하여 스크롤하는 것은 터치스크린 드래그 이벤트와 유사하게 보고되므로 부드러운 키네틱 스크롤이 가능합니다. 터치스크린 드래그와 터치패드 스크롤이 다르게 작동하도록 하려면 getSource()를 사용하세요.
  • 마우스 휠 스크롤: 마우스 휠 스크롤은 View.onGenericMotionEvent()ACTION_SCROLL 이벤트로 보고됩니다.
  • 마우스/터치패드 클릭 및 드래그: 클릭 및 드래그 이벤트는 터치스크린 드래그 이벤트와 매우 유사합니다. 클릭 및 드래그를 터치패드 스크롤 이벤트와 구별하려면 getButtonState()를 사용하세요. 클릭 및 드래그에는 항상 버튼이 수반되지만 터치패드 스크롤은 그러지 않습니다.

오른쪽 클릭 지원

컨텍스트 클릭이라고도 하는 오른쪽 클릭 이벤트는 뷰에 View.OnContextClickListener를 설정하여 간단하게 처리할 수 있습니다.

Kotlin

    yourView.setOnContextClickListener {
        //display context click options
        true
    }
    

자바

    yourView.setOnContextClickListener(new View.OnContextClickListener() {
    @Override
      public boolean onContextClick(View view) {
        //display context click options
        return true;
      }
    });
    

이 메서드는 API 레벨 23에서 추가되었으므로 이전 버전의 Android를 실행 중일 수 있는 다른 기기에서 동일한 기능을 허용하려면 위에 표시된 대로 일반 모션 이벤트를 사용하면 됩니다.

키보드

키보드 입력은 데스크톱 및 노트북 기기에서 중요하며 접근성을 위해서도 필요합니다.

적절한 입력 포커스를 활성화하려면 기본 Android API에 설명된 대로 일반 리소스 추가 작업을 따라야 합니다.

  • 키보드 입력을 직접 처리하려면 KeyEvent.callback을 통해 기본 함수를 사용하세요. TextEdit 요소 내에서 키보드 입력을 처리할 필요가 없습니다.
  • 텍스트를 직접 수정하려면 onKeyDown, onKeyLongPress, onKeyUp을 사용해야 하지만 전체 범위의 IME를 구현하지 않는 한 onKeyPreIME 이벤트를 사용하지 않아야 합니다. 전체 범위의 IME는 권장되지 않습니다.

스타일러스

스타일러스는 View.onTouchEvent()를 통해 터치스크린과 유사한 이벤트를 보고합니다. 하지만 스타일러스 이벤트에는 고려해야 하는 추가 정보가 있습니다.

  • MotionEvent.getToolType(): 이 도구 유형을 사용하여 TOOL_TYPE_FINGERTOOL_TYPE_STYLUS 이벤트와 구별할 수 있습니다. 또한 사용자가 펜을 가지고 있는 경우 TOOL_TYPE_ERASER를 통해 펜의 지우개 쪽 사용을 인식할 수 있습니다.
  • MotionEvent.getPressure(): 지원되는 경우 스타일러스 펜에 적용되는 물리적 압력을 나타냅니다.
  • MotionEvent.AXIS_TILT/AXIS_ORIENTATION: MotionEvent.getAxisValue()와 함께 사용하여 지원되는 경우 스타일러스의 물리적 기울기 및 방향을 읽을 수 있습니다.

이전 포인트

Android는 프레임당 한 번 전달될 입력 이벤트를 일괄 처리합니다. 그러나 스타일러스 펜은 훨씬 더 높은 주파수(일반적으로 200Hz)에서 보고할 수 있습니다. 그리기 앱을 만들 때 이전 API에서 획득한 포인트를 사용하는 것이 중요합니다.

  • MotionEvent.getHistoricalX()
  • MotionEvent.getHistoricalY()
  • MotionEvent.getHistoricalPressure()
  • MotionEvent.getHistoricalAxisValue()

손바닥 움직임 무시

Chrome OS는 화면에 닿는 손바닥을 인식하려고 시도하므로 손바닥 움직임이 앱에 보고되지 않습니다. 그러나 이것이 항상 가능한 것은 아닙니다. OS에서 터치를 손바닥으로 인식하기 전에 터치가 보고될 수도 있습니다. 이 경우 ACTION_CANCEL 이벤트를 보고하면 터치가 취소됩니다.

이 이벤트는 앱에 모든 터치가 무효이며 터치로 인해 발생하는 모든 상호작용을 실행취소해야 한다고 알립니다. 예를 들어 그리기 앱의 경우 앱이 임시로 새로운 선을 그리고 터치 시리즈가 완전히 완료된 후에만 이 선을 캔버스에 커밋합니다. 터치가 취소되면 임시 선을 쉽게 삭제할 수 있습니다.

메모 작성 인텐트

Chrome OS는 다음 코드 스니펫에서와 같이 org.chromium.arc.intent.action.CREATE_NOTE 작업 및 Intent.CATEGORY_DEFAULT(android.intent.category.DEFAULT) 카테고리를 포함하는 인텐트를 처리하도록 등록된 앱 목록을 표시합니다.

  <intent-filter>
        <action android:name="org.chromium.arc.intent.action.CREATE_NOTE" />
        <category android:name="android.intent.category.DEFAULT" />
      </intent-filter>
    

사용자가 앱을 선택할 수 있으며 나중에 메모 작성 앱이 요청될 때 해당하는 앱이 실행됩니다.

사용자가 새 메모 만들기를 요청하면 앞서 언급한 작업 및 카테고리만 포함하는 인텐트를 사용하여 앱이 실행됩니다. 앱은 사용자가 스타일러스를 사용하여 작성할 수 있는 모드로 빈 메모를 만들어야 합니다.

사용자가 이미지(예: 스크린샷 또는 다운로드한 이미지) 환경설정에 주석을 달도록 요청하면 content:// URI가 있는 하나 이상의 항목이 포함된 ClipData를 비롯하여 앞서 언급한 작업과 카테고리를 포함하는 인텐트를 사용하여 앱이 실행됩니다. 앱은 사용자가 스타일러스를 사용하여 그릴 수 있는 모드로 첫 번째 첨부된 이미지를 배경 이미지로 사용하는 메모를 만들어야 합니다.

스타일러스 없이 테스트

  1. dev 모드로 전환하여 기기를 쓰기 가능하게 만듭니다.
  2. Ctrl + Alt + F2(앞으로 화살표)를 눌러 셸을 엽니다.
  3. sudo vi /etc/chrome_dev.conf 명령어를 실행합니다.
  4. 파일 끝의 새 줄에 --ash-enable-palette를 추가합니다.
  5. Ctrl + Alt + F1(뒤로 화살표)을 눌러 UI로 돌아갑니다.
  6. 로그아웃했다가 다시 로그인합니다.

이제 스타일러스 진입점이 표시됩니다. 실행기에서 스타일러스 버튼을 탭하고 '새 메모'를 선택할 수 있습니다. 그러면 애플리케이션에 빈 그림 메모가 열립니다. 스크린샷을 찍거나(실행기에서 스타일러스 버튼 > 화면 캡처) 이미지를 다운로드하면 알림에 '이미지에 주석 달기' 옵션이 표시됩니다. 이 옵션은 이미지에 주석을 달 준비가 된 상태로 앱을 엽니다.

게임패드

Chromebook은 최대 4개의 게임패드를 지원하며 게임패드를 보고하기 위해 표준 Android API를 따릅니다. 안타깝게도 Android용으로 설계되지 않은 게임패드가 올바른 버튼 매핑을 표시하는 것은 매우 일반적입니다.