5

我已经构建了一个 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 but didn't find a solution to work。

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

4

1 回答 1

11

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

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

需要注意的主要代码有:

在Activity中,消费关键事件并向下传递:

/**
 * 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 所在的 Fragment 中(尽管这可能在您的活动中):

/**
 * 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;
    }
};

这个例子可能比它需要的复杂得多,但是如果你完成了上面的每一部分并尝试了它,你应该不会有太多的麻烦

于 2013-11-01T11:48:28.333 回答