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

  • Tutorial

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



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


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

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


Теория


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


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 так и не заработало, но это может быть проблемой прошивки.


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

Ads
AdBlock has stolen the banner, but banners are not teeth — they will be back

More

Comments 10

    0

    Круто, сам долго искал способ как наладить работу клавиатуры на русском и английском. Пока что остановился на приложении free physical keyboard.
    Моя клавиатура содержит кучу доп. клавиш, интересно, можно ли их как-то тоже настроить таким способом?

      +1
      Попробовать стоит. Алгоритм простой:
      1. Выяснить какие коды (Linux key codes) производят эти клавиши. Для этого есть несколько приложений. Я использовал Gamepad Tester.
      2. Назначить этим кодам соответствующие андроидовские клавиши (Android key). Тут есть список по-умолчанию в формате key LINUX_KEY_CODE ANDROID_KEY. Назначать их нужно в kcm-файле (т.к. дополнительные раскладки задаются с его помощью) в формате map key LINUX_KEY_CODE ANDROID_KEY.
      –1
      Довольно давно работаю с андройдов. Клавиатурный дефицит присущ вплоть до последних версий AOSP. Разработчики даже наэкранную клавиатуру не могут довести до ума.
      Замечательно, что находятся такие люди, которым не все равно. Печален тот факт, что возможности скованы самоограничением в использовании рута. Хотя так иногда даже интереснее…

      Реквестирую свои хотелки по клавиатуре:
      1. Хотелось бы переключать язык раскладки не только Alt+Space, а ещё иметь горячую клавишу (например правый Alt), которая меняет раскладку на время нажатия этой клавиши, соответственно, при отпускании её язык раскладки возвращался обратно. Это очень удобно, когда работаешь всего двумя языками.
      2. Хотелось бы чтобы когда клавиатура пребывает в состоянии русского языка, горел индикатор CapsLock. Из продвинутых пользователей этой функцией все равно мало кто пользуется, у многих линуксоидов действие по клавише CapsLock переназначено на что-то более полезное.
      3. Также хочется назначать доп.функции свои коды на длительное нажатие клавиш (комбинаций клавиш). Это способствует более быстрому запоминанию и привыканию к более ужатым (и без того огромным) спискам комбинаций хоткеев.
        0
        1. В комментарии к русской раскладке (да и к другим тоже), которая поставляется с Android так и написано: «As an added convenience, English characters are accessible using ralt (Alt Gr)». Т.е. английские символы и так доступны при зажатом ALT_RIGHT. Проверено — работает.

        2. Насчёт LED не знаю. Есть небольшое упоминание в документации и список led в Generic.kl файле. Надо разбираться.

        3. Про длительность нажатия в документации ни слова не видел. Такие вещи уже приложения обрабатывать должны, как мне кажется. Возможно, самописная клавиатура будет решением.
          0
          Пришла в голову мысль включить в сборку еще один язык. Рядом с «Английский (США)», «Английский (Великобритания)» какой-нибудь «Английский (Россия)». Сделать копию английской раскладки с включенными русскими буквами в комбинации с RALT.
          Я раньше и сам не думал что длительное нажатие комбинации вообще нужно. Так было пока в руки не попал ноут с клавиатурой, где ряд клавиш с F1-F12 совмещен с рядом клавиш TILDA 0-9 + — BKSP. И к обычным привычным комбинациям приходится добавлять клавишу FN.
          Возможно, у разработчиков этой клавиатуры по 6 пальцев на руке… но, вероятнее всего, это тренд. Против моды идти бесполезно.
          Вот так выглядит это чудо
          image
            0

            Проект — основа для кастомизации. Можете себе туда добавить всё что хотите. Русские символы по ralt добавить не сложно. Нужно поправить правила в английском kcm-файле, добавив поведение при зажатом ralt для каждого символа.
            Проблема с другим символом по долгому нажатию в том, что его сложно отделить от случая, когда пользователь хочет ввести один и тот же символ несколько раз подряд. Например, АААААААААААААААААААА. Такое либо на програмном уровне должно обрабатываться (сторонняя программная клавиатура), либо на уровне самой физической клавиатуры (какая-нибудь моднейшая перепрошиваемая клавиатура).

              0
              Долгое нажатие неплохо реализовано в наэкранной клавиатуре. Покопался в xml. Вот сейчас в ветке master там чёрт ногу сломит. А еще в пятом андройде была каждая раскладка в своём едином файле, и потому все более-менее понятно. Там в описаниях раскладок у клавиш был параметр repeatable. В значение true установлен на таких клавишах как Space, Enter, Delete. Ну а большинство клавиш по длительному нажатию выдавало мини-клавиатуру с разными доп.символами.
              Я не думаю что это большая проблема отличить хочу ли я повторного нажатия, наример, комбинации Ctrl+Shift+Win+F3 или я имел в виду, например, комбинацию Ctrl+Shift+Win+Alt+F3, которая будет прописана на длительное нажатие Ctrl+Shift+Win+F3.
              Если говорить о предсказывании пользовательских действий, стоит упомянуть, что наэкранная клавиатура андройда неплохо исправляет очепятки. По моему мнению, это реализовать куда сложнее, чем реализация пользовательского списка длительных комбинаций клавиш.
              Это просто мысли вслух. Ни в коем случаем не подумайте, что прошу вас реализовать это. Мне просто тоже интересна эта тема. Очень люблю копать исходники AOSP.
                0

                Ничего не могу сказать насчёт наэкранной клавиатуры. Раскладки из статьи для физической работают и выбираются они в настройках физической клавиатуры.
                А что с xml непонятно?

                  0
                  Ну вот посмотрите как сделана раскладка в Hackers Keyboard. Несмотря на то, что клавиатура кастомная, много кода было взаимствовано с 1-4х андройдов. Структура оформления сохранилась, если мне не изменяет память, со 2го андройда. Все лаконично и вся раскладка в одном файле. Легко добавить/убрать любую клавишу.
                  А теперь посмотрим что там в ветке master у AOSP. Где тут можно добавить/убрать клавишу?
        0
        -

        Only users with full accounts can post comments. Log in, please.