Androidのアプリ開発関連のブログ

キー入力の取得処理でハマってる

今日はキー入力の取得処理でハマって、全く進んでない。

まず、EditTextなしでキーボードを表示してキーイベントを取得する方法で考えた。
AndroidManifest.xml で<activity>の属性にandroid:windowSoftInputMode="stateAlwaysVisible" を追加すればキーボードは常時表示される。
ActivityのonKeyDown(int keyCode, KeyEvent event)
をオーバーライドすれば押されたキーのボタン番号とKeyEventが取得できる。
のだが、ここで戻りがStringとかCharのメソッドを調べて、
「ボタンに対応する文字を取得する機能が存在しない。」と判断してしまった。


次にEditTextなしは諦めてEditTextの変更をTextWatcherで監視する方法を試みた。
普通にEditTextを使うと確定前に表示されちゃうので、TextWatcherで確定判別。
確定時にイベントが発生すれば良いのだが、そういうイベントはない模様。

この場合はソフトキーボードの強制表示は、
InputMethodManager imm=(InputMethodManager)getSystemService(this.INPUT_METHOD_SERVICE);
imm.showSoftInput(view,imm.SHOW_IMPLICIT);
てな感じでできる。
showSoftInput()の第1引数がViewだが、Viewなしでキーボード表示は動的にできないのかな?

で、TextWatcherでの確定判別だが、
public void afterTextChanged(Editable s){
   for(Object obj:s.getSpans(0,s.length(),Object.class)){
     if((s.getSpanFlags(obj)&s.SPAN_COMPOSING)==s.SPAN_COMPOSING){
       Log.d("TES","未確定"+s.toString());
       return;
     }
   }
   Log.d("TES","確定"+s.toString());
}
こんな感じで、Spanned(Editableがimplementsしてる)のフラッグを確認すると、未確定状態だとSPAN_COMPOSINGが付いているようなので、それを判別。
なのだが、キーボードをゆっくり押すと問題ないが、速く押すと未確定のはずが一瞬確定してる。
他に、未確定状態だとアンダーラインがついているはず!ということでSpannedでアンダーラインを判別しても似たようなことが出来るようなのだが、
キーボードを押すと一瞬アンダーラインが消えてるのが目視できる。結局同じぽい。



どうしたもんかと思ったが、
実は最初に試したActivityのonKeyDown()の方で、
戻り値がint型なので気づかなかったが、event.getUnicodeChar()でボタンに対応するchar値(intで返ってくるが)が取得できた。
isPrintingKey()で表示可能文字かどうかの判別もできるんで、
表示可能ならそのまま送信して、表示できない文字は個別に処理作れば良さそう。

というわけで、ActivityのonKeyDown()でキー入力を取得する方法で行こうと思うが、1byteずつ送ることになるんで、
マルチバイト文字の入力が必要な場合とかは入力エリア使ってやるしか無いかな。

SSHクライアントの制作をちょっとやった

SSHクライアントの制作をちょっとやったが、
SFTPの時と同じようにJSCHでセッションをconnectして、
ssh=(ChannelShell)sess.openChannel("shell");
InputStream s2c=ssh.getInputStream();
ssh.connect();
てな感じで、openChannel("shell")でChannelShellを取得。
チャンネルをconnectする前にgetInputStream()で取れるInputStreamを読むことでサーバーからの出力を読み取ることができる感じ。
まだ試していないが、getOutputStream()で取れるOutputStreamから入力ができるはず。
JavaのInputStreamとOutputStreamは、どっちが入力でどっちが出力だかわかりにくい・・・

サーバーからの出力(InputStream)は繋いでる間は切断されないのでread()は-1にならない。
最後に制御コードが来るとかもないようなので、1byteずつ処理するしか無いと思うのでUTF以外の文字コードに対応させようと思ったらめんどそう。
まずUTF-8で作って、他の文字コードは対応できそうだったら考えることにする。

nanoとかtopみたいな画面が切り替わるコマンドだとかは何か制御コードが飛んでくるものだと思うのだが、
今の所ログイン処理までしか作って無くて、そこまででは改行と復帰以外の制御コードは確認できなかった。
次は入力をできるようにしてnanoとかコマンド送ってレスポンスを確認してみようと思う。
nanoなんかはターミナルの画面全体に表示されるが、サイズはどうやって決定してるんだろ?
と思ったが、setPtySize(int col, int row, int wp, int hp)でサイズを指定できるみたいだ。wpとhpはpxぽいが、colとrowは文字数なのかな?

入力はEditTextとかなしでキーボード常時表示にして入力を取得できないか?
という方向で考えている。