onKeyListener not working on virtual keyboard
Asked Answered
M

6

24

I don't understand why this piece of code is not working. Only backspace and return key are detected. Listener doesn't fire for any other key. My device is Nexus One.

I tried to override activity's OnKeyDown method and that's even worse. The only detected button was hardware back button.

I am seeing around a suggestion to use TextWatcher and onTextChanged, while that might work in some cases, it's not a real work around. For example, if textbox is empty, you won't detect if user press BackSpace(Delete) button. So any ideas?

        TextView txtInput = (TextView)findViewById(R.id.txtInput);
    txtInput.setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            makeToast(keyCode + " key pressed");
            return true;
        }
    });
Minoan answered 26/11, 2010 at 2:47 Comment(4)
Well, I spent good 4 hours on this problem. It seems that nobody has solution for this. Few people are also suggesting to use OnKeyboardActionListener, but can't find any example on how to use it.Minoan
Found example here: developer.android.com/resources/samples/SoftKeyboard/src/com/…Minoan
I am not sure that softkeyboard example will work for me. I don't won't to write another input method. I simply want to show default input method on the screen (android keyboard usually) and capture any key press. Why this seems so daunting task? I am getting frustrated.Minoan
According to the docs at developer.android.com/reference/android/view/View.OnKeyListener - "This is only useful for hardware keyboards; a software input method has no obligation to trigger this listener."Freeway
M
19

Ok. I finally figured how to do what I want, and I am not proud on Android for this.

I am writing server/client application where on client I have to open SoftKeyboard and send pressed keys (characters and DEL key)... Each time key is pressed, that character is sent to server. If DEL is pressed I am sending sequence {BS} to server.

In order to do that I had to implement TextWatcher and onTextChange which works well except for situation when EditText is empty and user press DEL key. Since there is no change in EditText there is no way to detect that DEL key is pressed.

In addition to TextWatcher, I had to implement onKeyListener which I attached to my EditText control. This onKeyListener ignores all keys on SoftKeyboard except DEL and RETURN. Not sure why? A bug maybe?

Here is my code:

    TextView txtInput = (TextView)findViewById(R.id.txtInput);
    txtInput.addTextChangedListener(inputTextWatcher);

    txtInput.setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            Log.d(TAG, keyCode + " character(code) to send");
            return false;
        }
    });

and TextWatcher....

private TextWatcher inputTextWatcher = new TextWatcher() {
    public void afterTextChanged(Editable s) { }
    public void beforeTextChanged(CharSequence s, int start, int count, int after)
        { }
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        Log.d(TAG, s.charAt(count-1) + " character to send");;          
    }
};
Minoan answered 26/11, 2010 at 20:32 Comment(2)
It's indeed irritating that some keyboards don't seem to send the onkeyup key codes (e.g., the samsung default keyboard on an S3/S4). You have to work around it by watching for text changed instead...Lehmann
what about when there is no character and user press back-key?Miki
D
4

You have done one mistake here.
it should return true,If you handled the event. If you want to allow the event to be handled by the next receiver, return false
You are always returning true

Dirham answered 26/11, 2010 at 4:35 Comment(1)
Thanks for clarifying that. I actually tried to return false too. Reading around I figured I have to use onKeyboardActionListener. Will spend some time on it tomorrow. Thx.Minoan
T
4

Note : inputtype mention in your edittext.

<EditText android:id="@+id/select_category" 
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textCapSentences|textAutoCorrect" >



edittext.setOnEditorActionListener(new OnEditorActionListener() {

            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {

                if ((actionId & EditorInfo.IME_MASK_ACTION) == EditorInfo.IME_ACTION_DONE) {
                    //do something here.
                    return true;
                }
                return false;
            }
        });
Tombstone answered 19/3, 2015 at 7:21 Comment(1)
this one solved my problem with Mimuum keyboard. Does it work without imeOptions as in your code ?Manrope
S
3

Have you tried using the specific listener sub-class for that view?

I had a similar problem with an EditText. The code below worked:

private OnKeyListener keyListener = new EditText.OnKeyListener(){

    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        EditText et = (EditText) v;
        Log.i("APPEVENT", "Key hit: "+ event);
        //...
        return false;
    }

};

But if I used the View.OnKeyListener, I only record backspace and enter. It could be a similar problem with TextView. Perhaps the subclass key listeners are sensitive to more events for the given View subclass.

Sieve answered 7/2, 2013 at 13:32 Comment(0)
F
3

Referencing from:

http://developer.android.com/reference/android/view/View.OnKeyListener.html

View.OnKeyListener

Class Overview Interface definition for a callback to be invoked when a hardware key event is dispatched to this view. The callback will be invoked before the key event is given to the view. This is only useful for hardware keyboards; a software input method has no obligation to trigger this listener.

It seems OnKeyListener was designed for HARDWARE keys only!

Frescobaldi answered 10/9, 2019 at 10:31 Comment(0)
T
-1

We had the TextWatcher problem on iPhone as well -- if buffer is empty, keyboard does not send del event. We worked around it by preloading the keyboard buffer with 1000 characters. Luckily, our app hid the edit field behind the keyboard so the 1000 characters are not seen. It's ugly, but it works (unless the user hits 1000 deletes in a a row prior to entering any data!)

Trouper answered 5/1, 2011 at 5:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.