- PVSM.RU - https://www.pvsm.ru -
Мне нравится раскладка клавиатур на Mac: Cmd(Ctrl) под большим пальцем и возможность, без шаманства, прямо в настройках изменить поведение CapsLock. Такого же результата легко добиться в Linux с помощью setxkbmap
в консоли или, например, gnome-tweak-tool
в UI. Но что делать, если клавиатура подключается к Android?
В Android существует несколько способов кастомизировать внешнюю клавиатуру:
Устанавливать стороннюю клавиатуру не хочется. Рутовать телефон — тоже. Остаётся третий вариант.
Вкратце пробежимся по основным понятиям со ссылками на документацию.
Key layout [2] (.kl) файлы отображают линуксовые коды клавиш (Linux Key Code), т.е. код, который производит конкретная клавиша на клавиатуре, на андродовские клавиши (Android Key), т.е. TAB, ENTER или просто буква F. Отображение по-умолчанию можно посмотреть здесь [6]. Узнать, какая клавиша на клавиатуре какой код производит, можно, например, с помощью Gamepad Tester [7].
Key Character Map [3] (.kcm) файлы позволяют задать поведение для сочетания клавиш, а также нужны для добавления раскладок, отличных от English(US).
Начиная с версии 4.1 [8] в Android стало возможным устанавливать вместе с приложением дополнительные раскладки клавиатуры. После установки раскладки доступны в Settings -> Language & input -> Physical keyboard
. Минус этого подхода в том, что раскладки неизменяемы, и нет возможности кастомизировать их "на лету".
Вот что я хочу получить для моей клавиатуры:
Т.к. мои вкусы весьма специфичны (Ты же хочешь 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
Нажмите здесь для печати.