在WebView Google电视应用上处理来自D-pad的箭头键

时间:2013-10-31 21:22:26

标签: android webview arrow-keys

我已经构建了一个Android应用程序,可以在WebView中加载一个html页面,并且它正常工作,除了在D-pad箭头键上发生操作的事实不起作用。如果我用其他键改变箭头的动作,它就可以了。在Web浏览器中加载html页面工作正常,PC键盘箭头键返回正确的操作,但在Android WebView中,D-pad箭头键不起作用。

这就是我在js中按下虎键的方式:

window.addEventListener('keydown', keyDownHandler, true);
function keyDownHandler(evt){
var keyCode=evt.keyCode;
alert(keyCode);
}

除了箭头键,按任何其他键都会返回键码,但箭头不会。

这可能与此处重复:android WebView: Handle arrow keys in JavaScript但找不到合适的解决方案。

我有什么方法可以在Android WebView中获取D-pad箭头键代码?

1 个答案:

答案 0 :(得分:8)

Google TV样本上有一个名为WebAppNativePlayback的示例应用:https://code.google.com/p/googletv-android-samples/source/browse/#git%2FWebAppNativePlayback

本质上,d-pad由本机应用程序使用,因此您需要处理它,如果您使用全屏WebView,则可以通过将相关键传入JS中来将其传递给WebView。

要注意的主要代码是:

在“活动”中,使用关键事件并传递下来:

/**
 * This method will check if the key press should be handled by the system
 * or if we have chosen to override it to pass to the WebView. In
 * development builds of the application, the R key is used refresh the page
 * (required to ensure cached versions of the page are not used)
 */
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
    if (mIsDevelopmentBuild && event.getKeyCode() == KeyEvent.KEYCODE_R) {
        mWebViewFragment.refresh();
    }

    int eventKeyCode = event.getKeyCode();
    for (int i = 0; i < mOverrideKeyCodes.length; i++) {
        if (eventKeyCode == mOverrideKeyCodes[i]) {
            if (event.getAction() == KeyEvent.ACTION_UP) {
                mWebViewFragment.handleKeyInjection(eventKeyCode);
            }
            return true;
        }
    }

    return super.dispatchKeyEvent(event);
}

覆盖键位于:

mOverrideKeyCodes = new int[] {
                KeyEvent.KEYCODE_DPAD_CENTER,
                KeyEvent.KEYCODE_DPAD_UP,
                KeyEvent.KEYCODE_DPAD_LEFT,
                KeyEvent.KEYCODE_DPAD_DOWN,
                KeyEvent.KEYCODE_DPAD_RIGHT
        };

在webview所在的片段中(尽管这可能在您的活动中):

/**
 * Given a key code, this method will pass it into the web view to handle
 * accordingly
 * 
 * @param keycode Native Android KeyCode
 */
public void handleKeyInjection(int keycode) {
    String jsSend = "javascript:androidKeyHandler.handleUri('nativewebsample://KEY_EVENT;"
            + keycode + ";');";
    loadJavascriptAction(jsSend);
}

loadJavascriptAction只是

mWebView.loadUrl(jsSend);

然后在您的网页中,您需要设置一个可访问的方法或对象 - 在这种情况下,应用程序设置一个对象window.androidKeyHandler

/**
* This method will set up any additional key handling (i.e. Android key handling)
* @function
*/
IndexPage.prototype.setUpKeyHandling = function () {
    if(this.isEmbedded()) {
        // We want the native app to access this
        window.androidKeyHandler = new AndroidKeyHandler(this.getFocusController());
    }
};

比处理键更能:

/**
* Handle a keypress directly from the native app
* @function
* @param {int} keyCode The native Android key code
*/
AndroidKeyHandler.prototype.handleNativeKeyPress = function (keyCode) {
    var focusController = this.getFocusController();
    switch(parseInt(keyCode, 10)) {
        case 23:
            // DPAD Center
            console.log("Native Enter");
            if(focusController.getCurrentlyFocusedItem()) {
                focusController.getCurrentlyFocusedItem().onItemClick();
            }
            break;
        case 20:
            // DPAD Down
            console.log("Native Down Pressed");
            focusController.moveFocus({x: 0, y: -1});
            break;
        case 21:
            // DPAD Left
            console.log("Native Left Pressed");
            focusController.moveFocus({x: -1, y: 0});
            break;
        case 22:
            // DPAD Right
            console.log("Native RIGHT Pressed");
            focusController.moveFocus({x: 1, y: 0});
            break;
        case 19:
            // DPAD Up
            console.log("Native UP Pressed");
            focusController.moveFocus({x: 0, y: 1});
            break;
        default:
            console.log("Keycode not registered");
            break;
    }
};

这个例子可能比它需要的要复杂得多,但是如果你通过上面的每一件作品并尝试一下,你应该没有太多的麻烦去那里