Мне нравится раскладка клавиатур на Mac: Cmd(Ctrl) под большим пальцем и возможность, без шаманства, прямо в настройках изменить поведение CapsLock. Такого же результата легко добиться в Linux с помощью setxkbmap
в консоли или, например, gnome-tweak-tool
в UI. Но что делать, если клавиатура подключается к Android?
В Android существует несколько способов кастомизировать внешнюю клавиатуру:
- Установка сторонней клавиатуры. Например, External Keyboard Helper.
- Правка/добавление kl или kcm файлов (требуется root). Как, например, в этом посте.
- Установка приложения, которое добавляет дополнительные клавиатурные раскладки.
Устанавливать стороннюю клавиатуру не хочется. Рутовать телефон — тоже. Остаётся третий вариант.
Теория
Вкратце пробежимся по основным понятиям со ссылками на документацию.
Key Layout файлы
Key layout (.kl) файлы отображают линуксовые коды клавиш (Linux Key Code), т.е. код, который производит конкретная клавиша на клавиатуре, на андродовские клавиши (Android Key), т.е. TAB, ENTER или просто буква F. Отображение по-умолчанию можно посмотреть здесь. Узнать, какая клавиша на клавиатуре какой код производит, можно, например, с помощью Gamepad Tester.
Key Character Map файлы
Key Character Map (.kcm) файлы позволяют задать поведение для сочетания клавиш, а также нужны для добавления раскладок, отличных от English(US).
Дополнительные клавиатурные раскладки
Начиная с версии 4.1 в 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 — проект основа для кастомизации раскладки внешней клавиатуры на 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
Про этот тип ничего не сказано в документации, но опытным путём выяснено, что раскладка с таким типом по-умолчанию берёт значения из Generic.kcm. Т.е. мы уже получили английскую раскладку и всё что остаётся — это добавить наши правила.
Но сперва небольшое отступление про 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-файл с раскладкой этого языка, затем добавить к нему наши правила. Взять готовый файл для своего языка можно отсюда. Берём keyboard_layout_russian.kcm, кладём в 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.
Установка
Собираем и устанавливаем наше приложение. Проще всего это сделать с помощью Android Studio следуя официальной документации.
Если всё сделано правильно, то в Settings -> Language & input -> Physical keyboard
появятся наши раскладки, а в списке приложений — Custom Keyboard Layout
.
Заключение
Кастомизация внешней клавиатуры без root возможна. Не все хотелки при этом достижимы: переключение языков по Win+Space так и не заработало, но это может быть проблемой прошивки.
Статья нарочно сделана краткой — все подробности можно найти по ссылкам.
Автор: ris58h