Android で端末アプリを作ろうとしてえらいはまった。

キーボード入力を普通に OnKeyListener.onKey() で拾うプログラムを書いてエミュレータで動作確認後に 実機で動かしてみたら全然動かない。
キーを押しても何も反応しないのだが何故かリターンキーは拾える。

理由がさっぱり分からず数時間を費して OnKeyListener クラスの説明文に気が付いた。

View.OnKeyListener
Class Overview

Interface definition for a callback to be invoked when a hardware key event is dispatched to this view. The callback will be invoked before the key event is given to the view. This is only useful for hardware keyboards; a software input method has no obligation to trigger this listener.

orz...
英語読めないってだめね、完全にスルーしてたよ。
なんでこんな仕様なのかは後で分かったが...

しかし、個別のキー入力が拾えないと端末アプリにならないので対策を調べてみた。
結論から言うとソフトキーボードを自前で実装すればOKよ、と言うことらしい。

ソフトキーボードなんてどうやって実装するかと言うとSDKにちゃんとサンプルが用意されてた。

  • android-sdk/samples/android-17/SofKeyboard

具体的にはXMLでキーボードの配列を書いて Keybord クラスにリスースIDを渡してわれば終り。
以外に簡単だった。

KeyboardView keyboardView = new KeyboardView(context, null);
keyboard = new Keyboard(context, R.xml.keymap); // -> res/xml/keymap.xml
keyboardView.setKeyboard(keyboard);
// keyboardViewを適当に配置。

せっかくなので自分好みのキーマップを作ってみた。(US配列風)

あ、ESC忘れた...

これ作って気が付いたのだが Ctrl キーとかは標準のソフトキーボードではサポートされないので 端末アプリで使う場合には結局自前で実装せざる得なかった訳だ。 理屈は分かったけどもう少し分かり易いようにしておいて欲しいよ。