Read Keyboard events in Android WebView
Asked Answered
S

5

14

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?

Shortfall answered 11/7, 2012 at 9:45 Comment(2)
Were you able to get it working? I have exactly same problem at the moment...Endocranium
No, this type of action is considered to be insecure as passwords etc can be recorded. So it is not allowed in android.Shortfall
V
14

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

Valetudinary answered 15/4, 2015 at 11:38 Comment(2)
@Shortfall yes, sure. E.g. if the page loaded into the WebView is something like google.com.ua , you get notified on every letter input into the text box.Valetudinary
This can cause problems. Because you ignore the EditorInfo (which carries InputType information) this can lead to the wrong keyboard being shown. eg. last used keyboard is numeric but user clicks into text field, the numeric keyboard appears (interestingly this was only happening on certain devices eg. HTC One M8). I was trying to hide keyboard on Enter, I had to achieve this a different way - I hid keyboard when URL is about to load (webViewClient.shouldOverrideUrlLoading()).Villus
P
7

You can use onUnhandledKeyEvent() function overrid on WebViewClient class. Works perfectly for me.

onUnhandledKeyEvent

@Override
public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
      return;
}

whenever a user presses any key on the keyboard, this event will get fire.
Please let me know if that's works for you?
Prud answered 6/4, 2017 at 15:52 Comment(2)
I needed to know if any virtual keyboard event arrived in a text field in my WebView for an inactivity timer, and this works perfectly. Thanks.Lyly
Note: call requires API level 28.Voroshilovsk
D
1

I found a simple way to do this in Kotlin with a JavaScript callback.

    webview.apply {
        settings.javaScriptEnabled = true

        addJavascriptInterface(object {
            @JavascriptInterface
            fun keyInteraction(): Boolean {
                //<handle key interaction here>
                return true
            }
        },"Android")

        webViewClient = object : WebViewClient() {
            override fun onPageFinished(view: WebView?, url: String?) {
                loadingFinished()
                view?.loadUrl(
                    "javascript:(function() {" +
                    "    window.parent.addEventListener (" +
                    "        'keyup'," +
                    "        function(event) {" +
                    "            Android.keyInteraction();" +
                    "        });" +
                    "})()"
                )
                super.onPageFinished(view, url)
            }
        }
    }
Declinate answered 2/4, 2021 at 17:4 Comment(2)
Can you explain the keyInteraction function further? Does the event or key need to be passed into the function?Due
In this specific example, the keyInteraction java code will be called each time there is a keyup event in the webview. In my usage i did not need to pass any values, I just needed to know when the keyup event was occuring. You should be able to pass some primitive values, but you will just have to experiment for your usage.Declinate
S
0

you can use javascript like this

<body>
    
    <div contenteditable="true" id='box'></div>
</body>
    <script>
        box.addEventListener('keydown',e=>{
            if(e.keyCode ===13){
                alert('pressed enter key')
            }
        })
    </script>
Septuplet answered 15/3, 2020 at 9:33 Comment(0)
T
-2

I don't know if you tried this already but...alternatively, you can enable javascript for your "MyWebViewClass" and use javascript events to call java code using webView.addJavascriptInterface(....etc)

Full Story :- http://developer.android.com/guide/webapps/webview.html#BindingJavaScript

Tania answered 19/6, 2013 at 3:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.