Read Keyboard events in Android WebView

PC. picture PC. · Jul 11, 2012 · Viewed 14.1k times · Source

I'm trying to listen to key events in android web view. Example when user is filling a form, I should receive the key events. This is my WebView code

public class MyWebView extends WebView implements OnKeyListener
{
    .....

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event)
    {
        Log.i("PcWebView", "onKeyDown keyCode=" + keyCode);
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event)
    {
        Log.i("PcWebView", "onKeyUp keyCode=" + keyCode);
        return super.onKeyUp(keyCode, event);
    }

    @Override // Listener is initialized in the constructor
    public boolean onKey(View v, int keyCode, KeyEvent event)
    {
        Log.i("PcWebView", "onKey keyCode=" + keyCode);
        return false;
    }

    .....

}

neither of the methods onKeyDown, onKeyUp and onKey are being called when user types into the textboxes or textareas. Is it possible to achieve this or has Android restricted this b'cos of a possible privacy breach?

Answer

riwnodennyk picture riwnodennyk · Apr 15, 2015

Caution! This solution supports only English letters.

Accomplished without any access to the HTML source code or JS events. Works for me on Android 5.0.2 for both soft and hardware keyboards.

public class MyWebView extends WebView {


    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        return new BaseInputConnection(this, false); //this is needed for #dispatchKeyEvent() to be notified.
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        boolean dispatchFirst = super.dispatchKeyEvent(event);
        // Listening here for whatever key events you need
        if (event.getAction() == KeyEvent.ACTION_UP)
            switch (event.getKeyCode()) {
                case KeyEvent.KEYCODE_SPACE:
                case KeyEvent.KEYCODE_ENTER:
                    // e.g. get space and enter events here
                    break;
            }
        return dispatchFirst;
    }
}

The trick here is overriding the system-provided input implementation of InputConnection with a simplified one. Preventing developers from accessing the events by default was made by Googlers on purpose. Because the key event input isn't the only one anymore. There're gestures, voice and more is coming. Official recommendation is to "stop relying on legacy key events for text entry at all". Check out more details here: https://code.google.com/p/android/issues/detail?id=42904#c15