今回は具体的にキーボードのkey layoutファイル(以下KLファイルと略す)やkey character mapファイル(同KCMファイル)を作ってみることにしよう。機材として使ったのは前回と同じくLogicoolのdiNove Mini(写真01)とGalaxy Nexusである。前回の例のように、dumpsysコマンドでベンダーコードなどを調べておく。そこからこのキーボードに自動割り当てされるファイル名を以下のように決定した。

写真01: 今回、実際にKLとKCMを作ったのはロジクール社のdiNovo Mini。bluetoothのコンパクトキーボード

Vendor_046d_Product_b30c

さて、ユーザーがあとからKLファイルなどを作成した場合、/Systemディレクトリ以下に置くのには手間がかかる。なぜなら、ここは標準でリードオンリーでマウントされており、書き込む必要があるたびにremountする必要があるからだ。そこで、/data/system/devicesディレクトリ以下にkeylayout、keycharsディレクトリを作り、ここにファイルを置くことにする。この作業にはroot権限が必要だ。また、/system以下にあるkeylayoutディレクトリなどは、標準ではsystemグループのユーザーsystemの所有となっており、またパーミッション設定も行われている。今回は、ディレクトリの設定には、776を、ファイル自体には644を設定した。ファイルを作成したらchownやchmodコマンドで設定を行っておく。他のパーミッションやオーナーでのテストは行っていないため、エラーなどの場合には、作成したディレクトリやファイルのオーナーやパーミッションを確認されたい。

まず、KLファイルだが、システム側にlogitechのキーボード用のファイルがあったので、これをベースにファイルを書き換えた。また、KCMファイルについては、汎用のGeneric.kcmファイルをベースに書き換えを行った。また、idcファイルは作成せず、それぞれのファイル名をデバイス名表記とすることで、自動的に割り当てが行われるようにした。

なお、この自動割り当てだが、dumpsysコマンド、

dumpsys input

を使うと、デバイスごとにどのファイルを使っているかを表示できる(図01)。ファイルにエラーなどがあった場合、Generic.kcm、Generic.klファイルなどが使われることになるので注意が必要だ。もし試行錯誤的にファイルを作るのであれば、ときどきdumpsysコマンドで、ファイルの割り当てを調べるようにする。なお、接続が開始されると、ファイルが読み込まれ、メモリ上にデータが展開されて利用されるようなので、ファイルを変更したら一回Bluetoothをオフにして接続を切り、再度接続して、修正したファイルを読み込ませる。これをやらないと、いくらファイルを直しても動作に何も影響しないので注意されたい。

・図01

    27: Logitech diNovo Mini
      Classes: 0x8000012b
      Path: /dev/input/event6
      Descriptor: 97dd8f6772c63f793af21b2409d71addec8256af
      Location: 9C:02:98:E4:06:9E
      UniqueId: 00:07:61:B6:6D:9A
      Identifier: bus=0x0005, vendor=0x046d, product=0xb30c, version=0x0040
      KeyLayoutFile: /data/system/devices/keylayout/Vendor_046d_Product_b30c.kl
      KeyCharacterMapFile: /data/system/devices/keychars/Vendor_046d_Product_b30c.kcm
      ConfigurationFile:
      HaveKeyboardLayoutOverlay: false

エラーなどもあるため、作業は、KL、KCMファイルのどちらかだけで行い、動作が確実になったら他方のファイルの編集に入るとよいだろう。今回は最初にKLファイルの編集から行い、その後KCMファイルを作成して編集を行った。

KLファイルの作成とテスト

KLファイルは、Linux Key Code(以下LKC)からAndroid Key Code(同AKC)の変換テーブルだ。KLファイルでの対応は、おもに特殊キーにAKCを割り当てて処理することだろう。今回のdiNovo Miniでは、以下のような割り当て変更を行った。

Windowsロゴキー      ホームキー
レコードキー(赤丸のキー)   バックキー
スタートポーズキー       メディア再生、ポーズ
FN+Vol.Down     メニューキー
FN+Vol.Up       アプリ切り替えキー
FN+Mute     電源キー

また、キーボード右下のメディアセンターボタンは、今回対象としたGalaxy NexusがLKCを発生しないので割り当ては行えなかった。FNキーの組み合わせ部分は、「♪」、「IE」、「電源ボタン」のアイコンが割り当てられており、最初からdiNovoのFNキーでコードが出るようになっている。また、diNovoのメディア再生キーのキートップには、スタートとポーズのアイコンが表示されているものの、MEDIA_PLAYキーコードに変換されており、再生中に押しても停まらなかったため、割り当てを行った。また、利用頻度の高い、ホームキーとバックキーは、利用する場面のない「Windowsロゴキー」と「メディアの録音キー」(赤丸のついたボタン)を利用し、すぐに押せるようにした。

まず、変更するキートップとそれぞれが発生するLKCの関係は(表01)のようになる。これに対して、(表02)のようなAKC名を割り当てることにする。

■表1
キートップ LKC
Windowsロゴキー 125
レコードキー(赤丸のキー) 158
スタートポーズキー 164
FN+Vol.Down 171
FN+Vol.Up 172
FN+Mute 142
■表2
アンドロイド機能名 AKC名
ホームキー HOME
バックキー BACK
メディア再生、ポーズ

MEDIA_PLAY_PAUSE

メニューキー MENU
アプリ切り替えキー

APP_SWITCH

電源キー POWER

具体的なKLファイルは、リスト01のようなものだ。変更したところだけを抜粋すると、

key 125 HOME
key 158 BACK
key 164 MEDIA_PLAY_PAUSE
key 171 MENU
key 172 APP_SWITCH
key 142 POWER

となる。

KLファイルができたら、Bluetoothをオンにしてキーボードを接続する。この時点でKLファイルが読み込まれる。正しく読み込まれたかどうかの1つの判断は、前述のdumpsysコマンドでKey layoutファイルを確認することだ。その後、テストを行ってみればいいだろう。

KCMファイルを作る

次に同じファイル名で拡張子をkcmとしたものを「/data/system/devices/keychars」ディレクトリに作成する。これは、Generic.kcm(/system/usr/keychars)をベースにするといいだろう。

diNovoの場合、特にキーと文字の割り当てに問題はなかったため、ALTキーと英数字の組み合わせにfallbackを使って、特殊キーと同じ働き(たとえば、Alt+Hでホームキーなど)を定義してみた。また、電話など数字のみを入力する場合に、数字キーの7~9の下にあるキー3段分がテンキーになるように「number:」を定義した。これを使えば、電話をかける場合などに、「Y」キーで4が入力でき、「M」キーで0が入力できるようになる。

具体的なKCMファイルは、(リスト02)のようなものになるが、簡単に解説しておこう。まずは、Aのキーでは、Altキーの組み合わせで音楽再生アプリが起動するようにした。

key A {
    label:                              'A'
    base:                               'a'
    shift, capslock:                    'A'
    alt:                                fallback MUSIC
}

「fallback MUSIC」は、AKCである「KEYCODE_MUSIC」を発生させる。なお、利用可能な特殊機能キーには、(表03)のようなものがある。これ以外にも第一回で紹介した資料には、AKCが定義されているのだが、入れるとエラーが発生し、作成したKCMファイルが読み込まれない場合があった。たとえば、「CAMERA」、「CONTECT」、「BOOKMARK」、「FOCUS」などだ。これらをfallbackで指定するとエラーになり、KCMファイル自体が読み込めなくなる。ただ、こうした定義は、機種によって違いがあるため、他の機種では、動作する可能性もある。最初からカメラキーを持っている機種などでは「CAMERA」が動作する可能性はある。

■表3
AKC名 機能
MUSIC 音楽再生アプリ
ENVELOPE メール
CALL 電話
CALCULATOR 電卓
CALENDAR カレンダー
EXPLORER Webブラウザ

さて、3回にわたってAndroidのキーボードのカスタマイズとその実際について解説した。このやり方を使えば、USB、Bluetoothキーボードでキートップと入る文字が違う、特殊キーがアンドロイドでもちゃんと動作するようにしたいといった場合のほとんどに対応できるはずだ。

リスト01

key 1     ESCAPE
key 2     1
key 3     2
key 4     3
key 5     4
      :
    (省略)
      :
key 125   HOME
      :
    (省略)
      :
key 142  POWER
key 158   BACK
      :
    (省略)
      :
key 164   MEDIA_PLAY_PAUSE
      :
    (省略)
      :
key 171   MENU
key 172   APP_SWITCH
      :
    (省略)
      :
key 418   ZOOM_IN
key 419   ZOOM_OUT

リスト02

type FULL

key A {
    label:                              'A'
    base:                               'a'
    shift, capslock:                    'A'
    alt:                                fallback MUSIC
}

key B {
    label:                              'B'
    base:                               'b'
    shift, capslock:                    'B'
    alt:                                fallback ENVELOPE
}

key C {
    label:                              'C'
    base:                               'c'
    shift, capslock:                    'C'
    alt:                                fallback CALL
#    alt:                                '\u00e7'
    shift+alt:                          '\u00c7'
}

key D {
    label:                              'D'
    base:                               'd'
    shift, capslock:                    'D'
#    alt:                                fallback CONTACT
}

key E {
    label:                              'E'
    base:                               'e'
    shift, capslock:                    'E'
#    alt:                                '\u0301'
    alt:                                fallback CALCULATOR
}

key F {
    label:                              'F'
    base:                               'f'
    shift, capslock:                    'F'
    alt:                                fallback CALENDAR
}

key G {
    label:                              'G'
    base:                               'g'
    shift, capslock:                    'G'
    alt:                                fallback EXPLORER
}

key H {
    label:                              'H'
    base:                               'h'
    shift, capslock:                    'H'
    number:             '1'
    alt:                                fallback HOME
}

key I {
    label:                              'I'
    base:                               'i'
    shift, capslock:                    'I'
#    alt:                                '\u0302'
#    alt:                                fallback BOOKMARK
    number:             '6'
}

key J {
    label:                              'J'
    base:                               'j'
    shift, capslock:                    'J'
    number:             '2'
#    alt:                                fallback CAMERA
}

key K {
    label:                              'K'
    base:                               'k'
    shift, capslock:                    'K'
    number:             '3'
#    alt:                                fallback FOCUS
}

key L {
    label:                              'L'
    base:                               'l'
    shift, capslock:                    'L'
}

key M {
    label:                              'M'
    base:                               'm'
    shift, capslock:                    'M'
    alt:                                fallback MENU
    number:             '0'
}

key N {
    label:                              'N'
    base:                               'n'
    shift, capslock:                    'N'
    alt:                                '\u0303'
    number:             '*'
}
      :
    (省略)
      :
key U {
    label:                              'U'
    base:                               'u'
    shift, capslock:                    'U'
    alt:                                '\u0308'
    number:             '5'
}
      :
    (省略)
      :
key Y {
    label:                              'Y'
    base:                               'y'
    shift, capslock:                    'Y'
    number:             '4'
}
      :
    (省略)
      :
key COMMA {
    label:                              ','
    base:                               ','
    shift:                              '
編集部注: 本稿は、2013年2月25日にAndorid情報のWeb専門誌「AndroWire」に掲載した記事を再構成したものです。