- PVSM.RU - https://www.pvsm.ru -

Кастомизируем раскладку внешней клавиатуры на Android без root

Мне нравится раскладка клавиатур на Mac: Cmd(Ctrl) под большим пальцем и возможность, без шаманства, прямо в настройках изменить поведение CapsLock. Такого же результата легко добиться в Linux с помощью setxkbmap в консоли или, например, gnome-tweak-tool в UI. Но что делать, если клавиатура подключается к Android?

Кастомизируем раскладку внешней клавиатуры на Android без root - 1

В Android существует несколько способов кастомизировать внешнюю клавиатуру:

  1. Установка сторонней клавиатуры. Например, External Keyboard Helper [1].
  2. Правка/добавление kl [2] или kcm [3] файлов (требуется root). Как, например, в этом [4] посте.
  3. Установка приложения, которое добавляет дополнительные клавиатурные раскладки [5].

Устанавливать стороннюю клавиатуру не хочется. Рутовать телефон — тоже. Остаётся третий вариант.

Теория

Вкратце пробежимся по основным понятиям со ссылками на документацию.

Key Layout файлы

Key layout [2] (.kl) файлы отображают линуксовые коды клавиш (Linux Key Code), т.е. код, который производит конкретная клавиша на клавиатуре, на андродовские клавиши (Android  Key), т.е. TAB, ENTER или просто буква F. Отображение по-умолчанию можно посмотреть здесь [6]. Узнать, какая клавиша на клавиатуре какой код производит, можно, например, с помощью Gamepad Tester [7].

Key Character Map файлы

Key Character Map [3] (.kcm) файлы позволяют задать поведение для сочетания клавиш, а также нужны для добавления раскладок, отличных от English(US).

Дополнительные клавиатурные раскладки

Начиная с версии 4.1 [8] в Android стало возможным устанавливать вместе с приложением дополнительные раскладки клавиатуры. После установки раскладки доступны в Settings -> Language & input -> Physical keyboard. Минус этого подхода в том, что раскладки неизменяемы, и нет возможности кастомизировать их "на лету".

Практика

Вот что я хочу получить для моей клавиатуры:

  • Esc вместо CapsLock.
  • Поменять Ctrl/Win/Alt на Win/Alt/Ctrl слева и Alt/PrintScreen/Ctrl на Ctrl/Alt/Ctrl справа.
  • Поменять переключение приложений с Alt+Tab на Ctrl+Tab.
  • Скриншот на Ctrl+Shift+3.
  • Переключение языков по Win+Space.
  • Поддержка английской и русской раскладок.

Описание проекта

Т.к. мои вкусы весьма специфичны (Ты же хочешь Ctrl вместо CapsLock, мой дорогой любитель Vim?), а раскладки неизменяемы "на лету", я не предоставляю готовый apk-файл. Вместо этого создан custom-keyboard-layout [9] — проект основа для кастомизации раскладки внешней клавиатуры на Android.

Клонируем проект к себе

git clone git@github.com:ris58h/custom-keyboard-layout.git

Манифест приложения app/src/main/AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="ris58h.custom_keyboard_layout">

    <application android:label="@string/app_name">
        <receiver
            android:name=".InputDeviceReceiver"
            android:label="@string/keyboard_layouts_label">
            <intent-filter>
                <action android:name="android.hardware.input.action.QUERY_KEYBOARD_LAYOUTS" />
            </intent-filter>
            <meta-data
                android:name="android.hardware.input.metadata.KEYBOARD_LAYOUTS"
                android:resource="@xml/keyboard_layouts" />
        </receiver>
    </application>
</manifest>

Приложение состоит из одного reciever. Забавно, что само наличие класса с заданным именем (в нашем случае InputDeviceReceiver) не требуется — всё работает и без него, но имя мы задать обязаны. Этот reciever предоставляет список клавиатурных раскладок, хранящийся в app/src/main/res/xml/keyboard_layouts.xml:

<?xml version="1.0" encoding="utf-8"?>
<keyboard-layouts xmlns:android="http://schemas.android.com/apk/res/android">
    <keyboard-layout
        android:name="keyboard_layout_en_us"
        android:keyboardLayout="@raw/keyboard_layout_en_us"
        android:label="@string/keyboard_layout_en_us_label" />
</keyboard-layouts>

В списке только одна раскладка — keyboard_layout_en_us.

Кастомизация файла раскладки

Файл раскладки app/src/main/res/raw/keyboard_layout_en_us.kcm состоит из одной строки, задающей тип раскладки:

type OVERLAY

Про этот тип ничего не сказано в документации [3], но опытным путём выяснено, что раскладка с таким типом по-умолчанию берёт значения из Generic.kcm [10]. Т.е. мы уже получили английскую раскладку и всё что остаётся — это добавить наши правила.

Но сперва небольшое отступление про Key Layout файлы. Раскладки задаётся как kcm-файл, но для того чтобы поменять местами, например, Ctrl и Alt необходим kl-файл. Тут на помощь приходит ещё одна незадокументированная фича: с помощью команды map можно добавлять правила из kl-файла в kcm-файл.

Файл keyboard_layout_en_us.kcm с моими правилами:

type OVERLAY

map key 58  ESCAPE

map key 29  META_LEFT
map key 56  CTRL_LEFT
map key 125 ALT_LEFT

map key 99  ALT_RIGHT
map key 100 CTRL_RIGHT

key TAB {
    label:                              't'
    base:                               't'
    ctrl:                               fallback APP_SWITCH
}

key 3 {
    label:                              '3'
    base:                               '3'
    shift:                              '#'
    ctrl+shift:                         fallback SYSRQ
}

К сожалению, у меня не получилось задать переключение языков по Win+Space — такое правило просто не срабатывало.

Добавляем раскладку с другим языком

Для добавления раскладки другого языка, отличного от English(US), нужно сперва составить kcm-файл с раскладкой этого языка, затем добавить к нему наши правила. Взять готовый файл для своего языка можно отсюда [11]. Берём keyboard_layout_russian.kcm [12], кладём в app/src/main/res/raw/ и, соответственно, добавляем ещё одну раскладку в app/src/main/res/xml/keyboard_layouts.xml:

<?xml version="1.0" encoding="utf-8"?>
<keyboard-layouts xmlns:android="http://schemas.android.com/apk/res/android">
    <keyboard-layout
        android:name="keyboard_layout_en_us"
        android:keyboardLayout="@raw/keyboard_layout_en_us"
        android:label="@string/keyboard_layout_en_us_label" />
    <keyboard-layout
        android:name="keyboard_layout_ru"
        android:keyboardLayout="@raw/keyboard_layout_ru"
        android:label="@string/keyboard_layout_ru_label" />
</keyboard-layouts>

Не забываем добавить keyboard_layout_ru_label в app/src/main/res/values/strings.xml.
Теперь можно добавить наши правила, как в примере с английской раскладкой, но с небольшим изменением. В русской раскладке уже есть правило для '3', поэтому нужно лишь изменить его, а не добавлять новое:

key 3 {
    label:                              '3'
    base:                               '3'
    shift:                              'u2116'
    ralt:                               '#'
    ctrl+shift:                         fallback SYSRQ
}

Состояние проекта после этой кастомизации можно посмотреть в ветке Vendor_17ef_Product_6048 [13].

Установка

Собираем и устанавливаем наше приложение. Проще всего это сделать с помощью Android Studio [14] следуя официальной документации [15].

Если всё сделано правильно, то в Settings -> Language & input -> Physical keyboard появятся наши раскладки, а в списке приложений — Custom Keyboard Layout.

Заключение

Кастомизация внешней клавиатуры без root возможна. Не все хотелки при этом достижимы: переключение языков по Win+Space так и не заработало, но это может быть проблемой прошивки.

Статья нарочно сделана краткой — все подробности можно найти по ссылкам.

Автор: ris58h

Источник [16]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/open-source/353084

Ссылки в тексте:

[1] External Keyboard Helper: https://play.google.com/store/apps/details?id=com.apedroid.hwkeyboardhelperdemo

[2] kl: https://source.android.com/devices/input/key-layout-files

[3] kcm: https://source.android.com/devices/input/key-character-map-files

[4] этом: https://habr.com/ru/post/140384/

[5] дополнительные клавиатурные раскладки: https://developer.android.com/reference/android/hardware/input/InputManager#ACTION_QUERY_KEYBOARD_LAYOUTS

[6] здесь: https://android.googlesource.com/platform/frameworks/base/+/master/data/keyboards/Generic.kl

[7] Gamepad Tester: https://play.google.com/store/apps/details?id=ru.elron.gamepadtester

[8] 4.1: https://developer.android.com/about/versions/jelly-bean.html#android-4.1

[9] custom-keyboard-layout: https://github.com/ris58h/custom-keyboard-layout

[10] Generic.kcm: https://android.googlesource.com/platform/frameworks/base/+/master/data/keyboards/Generic.kcm

[11] отсюда: https://android.googlesource.com/platform/frameworks/base/+/master/packages/InputDevices/res/raw

[12] keyboard_layout_russian.kcm: https://android.googlesource.com/platform/frameworks/base/+/master/packages/InputDevices/res/raw/keyboard_layout_russian.kcm

[13] Vendor_17ef_Product_6048: https://github.com/ris58h/custom-keyboard-layout/tree/Vendor_17ef_Product_6048

[14] Android Studio: https://developer.android.com/studio

[15] официальной документации: https://developer.android.com/studio/run/device

[16] Источник: https://habr.com/ru/post/502274/?utm_source=habrahabr&utm_medium=rss&utm_campaign=502274