AndroidのWebViewはタブレットやスマートフォン用にカスタマイズされているため、キーイベントがほとんどきません。
このため、キーボードやゲームパッドで操作するWebViewベースのAndroidアプリを作ることができません。
せっかくいろいろなUSBデバイスやBluetoothデバイスがつながるのに、これらをWebViewで利用できないなんてとても不便です。
ネットで調べても答えが見つからなかったのでいろいろ考えてキーイベントをきっちっと受け取れるWebViewを作ってみました。
ActivityのdispatchKeyEvent()にはイベントがくるので、webview.loadUrl()でJavaScriptを実行させます。
javaScript側ではcreateEvent()でイベントを作って、initEvent()でキーボードイベントを作成、最後にdispatchEvent()でイベントを送信します。
とりあえず方向キーのキーイベントを送るサンプルを作ってみました。
これでどんなキーイベントもWebViewに送れます。
------------------------------------------------------------------------
public class SomeMain extends Activity{
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
webview.getSettings().setJavaScriptEnabled(true);
webview.loadUrl("file:///android_asset/index.html");
setContentView(webview);
}
public boolean dispatchKeyEvent(KeyEvent e) {
int keyCode=e.getKeyCode();
if (e.getAction() == KeyEvent.ACTION_UP) {
switch(keyCode){
case 19:
webview.loadUrl("javascript: "
+"try{"
+"var evt = document.createEvent('Events');"
+"evt.initEvent('keydown', true, true);"
+"evt.keyCode = 38;"
+"window.dispatchEvent(evt);"
+"}catch(e){}"
);
return true;
case 20:
webview.loadUrl("javascript: "
+"try{"
+"var evt = document.createEvent('Events');"
+"evt.initEvent('keydown', true, true);"
+"evt.keyCode = 40;"
+"window.dispatchEvent(evt);"
+"}catch(e){}"
);
return true;
case 21:
webview.loadUrl("javascript: "
+"try{"
+"var evt = document.createEvent('Events');"
+"evt.initEvent('keydown', true, true);"
+"evt.keyCode = 37;"
+"window.dispatchEvent(evt);"
+"}catch(e){}"
);
return true;
case 22:
webview.loadUrl("javascript: "
+"try{"
+"var evt = document.createEvent('Events');"
+"evt.initEvent('keydown', true, true);"
+"evt.keyCode = 39;"
+"window.dispatchEvent(evt);"
+"}catch(e){}"
);
return true;
}
}
if (e.getAction() == KeyEvent.ACTION_DOWN) {
switch(keyCode){
case 19:
webview.loadUrl("javascript: "
+"try{"
+"var evt = document.createEvent('Events');"
+"evt.initEvent('keyup', true, true);"
+"evt.keyCode = 38;"
+"window.dispatchEvent(evt);"
+"}catch(e){}"
);
return true;
case 20:
webview.loadUrl("javascript: "
+"try{"
+"var evt = document.createEvent('Events');"
+"evt.initEvent('keyup', true, true);"
+"evt.keyCode = 40;"
+"window.dispatchEvent(evt);"
+"}catch(e){}"
);
return true;
case 21:
webview.loadUrl("javascript: "
+"try{"
+"var evt = document.createEvent('Events');"
+"evt.initEvent('keyup', true, true);"
+"evt.keyCode = 37;"
+"window.dispatchEvent(evt);"
+"}catch(e){}"
);
return true;
case 22:
webview.loadUrl("javascript: "
+"try{"
+"var evt = document.createEvent('Events');"
+"evt.initEvent('keyup', true, true);"
+"evt.keyCode = 39;"
+"window.dispatchEvent(evt);"
+"}catch(e){}"
);
return true;
}
}
return super.dispatchKeyEvent(e);
}
}
0 件のコメント:
コメントを投稿