いろいろやっていると、ハードキーを使わずに
任意のタイミングでキーイベントを発行したくなることがあると思います。
手段はいくつかありますが、状況によって可否が変わります。
セキュリティ的な観点も含めて、
できること、できないことをメモしていこうと思います。
##目次
1.adbコマンドから発行する
1-1.inputコマンド
1-2.sendeventコマンド
2.プログラムコードから発行する
2-1.大前提(セキュリティ的な話)
2-2.dispatchKeyEvent
2-3.inputコマンドを使って発生させる
3.おわりに
##参考
キーコード:ソース(KeyEvent.java)・AndroidDeveloper
スキャンコード:ソース(input.h)
##1.adbコマンドから発行する
USB経由でイベントを発生させる場合がこれにあたります。
ある程度スクリプトを組めば、放置テストする際に便利ですね。
###1-1.inputコマンド
$ adb shell input keyevent [key code]
キーコードは10進数でもいいですし、KEYCODE_VOLUME_UPなどの定数名でもOKです。
定義名やキーコードは参考からどうぞ。
なお、蛇足ですがinputコマンドはタッチイベントやマウスなど、
様々なイベントを発生させることが可能です。
###1-2.sendeventコマンド
これはデバイスに入力される情報を擬似的に発生させるので、ちょっと面倒です。
まず、実際にデバイスに入力されるイベントを見てみましょう。
$ adb shell getevent
add device 1: /dev/input/event5
name: "msm8974-taiko-mtp-snd-card Headset Jack"
add device 2: /dev/input/event4
name: "msm8974-taiko-mtp-snd-card Button Jack"
add device 3: /dev/input/event3
name: "hs_detect"
add device 4: /dev/input/event1
name: "touch_dev"
add device 5: /dev/input/event0
name: "qpnp_pon"
add device 6: /dev/input/event2
name: "gpio-keys"
/dev/input/event2: 0001 0073 00000001
/dev/input/event2: 0000 0000 00000000
/dev/input/event2: 0001 0073 00000000
/dev/input/event2: 0000 0000 00000000
これはgetevent後に音量下キーを押して離したときのログです。
/dev/input/event2 というデバイス(gpio-keys)に対して、
音量下キーを押した、離した、というイベントが送られているログです。
音量下が「押された」
/dev/input/event2: 0001 0073 00000001
/dev/input/event2: 0000 0000 00000000
音量下が「離された」
/dev/input/event2: 0001 0073 00000000
/dev/input/event2: 0000 0000 00000000
詳しくは、ここでは解説しません。
この「押された」「離された」のイベントを偽装するのがsendeventになります。
$ adb shell sendevent [device] [cmd] [scancode] [value]
[device] : ここでいうと /dev/input/event2 になります
[cmd]、[scancode]、[value]はログに表示されている3つの数字を 16進数 にしたものです。
キーコードは10進数でもいいですし、KEYCODE_VOLUME_UPなどの定数名でもOKです。
scancodeはキーコードとはまた違ったもので、
参考のスキャンコードを参照して何を入れればよいか選んでください。
あとはログにあるように、4回sendeventを実行すればOKです。
inputコマンドで十分ですね。w
##2.プログラムコードから発行する
これはアプリ側からキーコードを発行する場合がこれにあたります。
###2-1.大前提(セキュリティ的な話)
私はこれでやろうとしたことを諦めたのですが…
基本的に、自分のアプリが全面に出てる場合しか使えません。
例えば、サービス上で使ってみたり、
ステータスバーを下に引っ張った状態だったり、
パネルセーブした状態だと利用できません。
おそらく、勝手にバックグラウンドで動かれると
セキュリティ的に問題があるからでしょう。(そりゃそうだ)
###2-2.dispatchKeyEvent
例えば、音量下イベントを発生させる場合はこうなります。
dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_VOLUME_UP));
dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_VOLUME_UP));
###2-3.コマンドを発行して発生させる
例えば、inputコマンドを発行する場合はこうなります。
Runtime.getRuntime().exec("input keyevent " + keyCode);
##3.おわりに
イヤホンジャックを挿したら音楽が再生される。。。
ようなアプリを作ろうと思って調べていたんですが、
セキュリティ的な話でダメでした。
rootをとってinjectKeyEventなどを使えば使えるのかもしれませんが、
市場への公開を目標にする人にとっては意味がありません。