Onkeylistener Not Working with Soft Keyboard (Android)

onKeyListener not working on virtual keyboard

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");;
}
};

OnKeyListener stops working after soft keyboard is hidden

You could override onBackPressed() in the activity which is using the fragment and them send a message to the fragment to know that key back was pressed. Something like this:

Activity:

/**
* Triggered when the user press back button
*/
@Override
public void onBackPressed(){

mYourFragment.onBackPressed();

}

Fragment:

public void onBackPressed(){

if (isSomeViewShowing) {
hideSomeView();
}

}

KeyBoard : setonkeylistener not working for EditText

Try using this: Filter your action first using KeyEvent.ACTION_DOWN

@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if ((event.getAction() == KeyEvent.ACTION_DOWN)
&& (keyCode == KeyEvent.KEYCODE_ENTER)) {
Toast.makeText(this,editText.getText().toString()+"Enter Pressed",Toast.LENGTH_LONG).show();
return true;
}
return false;
}

EDIT

use an setOnEditorActionListener on your Edittext

editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if ( (actionId == EditorInfo.IME_ACTION_DONE) || ((event.getKeyCode() == KeyEvent.KEYCODE_ENTER) && (event.getAction() == KeyEvent.ACTION_DOWN ))){
Toast.makeText(this,editText.getText().toString()+"Enter Pressed",Toast.LENGTH_LONG).show();
return true;
}
else{
return false;
}
}
});

Make sure in XMl you had:

<EditText
android:imeOptions="actionDone"
android:inputType="text"/>

EditText OnKeyListener not working

Finally solved myself by implementing this feature through TextWatcher. The major hurdle was that, I needed to detect backspace press even when there is no character in EditText or at least the end user perceives that there is no character there. The fist thing couldn't be achieved however I did the later one. Following is the detailed solution.

First of all, I always retained a space ' ' character in my editText.

editText.addTextChangedListener(new TextWatcher() {

@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
if(cs.toString().length() == 0)
editText.setText(" ");
}

@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { }

@Override
public void afterTextChanged(Editable arg0) { }

});

Then I customized EditText to notify me for every cursor position change. This purpose is achieved by overriding onSelectionChanged method of EditText. My customized EditText looks like this.

public class SelectionEnabledEditText extends EditText {
public SelectionEnabledEditText(Context context) {
super(context);
}

public SelectionEnabledEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}

public SelectionEnabledEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}

@Override
protected void onSelectionChanged(int selStart, int selEnd) {
super.onSelectionChanged(selStart, selEnd);

if(onSelectionChangeListener != null)
onSelectionChangeListener.onSelectionChanged(selStart, selEnd);
}

public static interface OnSelectionChangeListener{
public void onSelectionChanged(int selStart, int selEnd);
}

private OnSelectionChangeListener onSelectionChangeListener;

public void setOnSelectionChangeListener(OnSelectionChangeListener onSelectionChangeListener) {
this.onSelectionChangeListener = onSelectionChangeListener;
}
}

Finally, in my activity, I'm listening for cursor position changed event and resetting my cursor position in editText if it's there at the necessary space charatcer start i.e. at 0th index, like this;

editText.setOnSelectionChangeListener(new SelectionEnabledEditText.OnSelectionChangeListener() {
@Override
public void onSelectionChanged(int selStart, int selEnd) {
if (selEnd == 0) {
if (editText.getText().toString().length() == 0)
editText.setText(" ");

editText.setSelection(1);
}
}
});

Hope this would be helpful in similar situations. Suggestions are welcomed for improvements/optimizations.

onKeyListener not working as i want it to... in android

Option 1:

Use getAction() to determine when any key(excluding the back key) is pressed like this:

  etSearch.setOnKeyListener(new OnKeyListener() {

@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if(event.getAction() == KeyEvent.ACTION_DOWN && keyCode != KeyEvent.KEYCODE_BACK){
MyDbHelper mydbhelper2 = new MyDbHelper(MainActivity.this);
Course[] abc = mydbhelper2.query_searchByCourseName(etSearch.getText().toString());
CourseAdapter cadptrSearch = new CourseAdapter(MainActivity.this, R.layout.list_course_row,abc);
ListView lvSearch = (ListView) findViewById(R.id.list);
lvSearch.setAdapter(cadptrSearch);
}
return false;
}
});

If that fails, then you're dealing with a soft keyboard issue so try Option 2:

Option 2: Use a text watcher to handle text changed events:

    etSearch.addTextChangedListener(new TextWatcher () {
public void afterTextChanged(Editable s) {
if(s.length() > 0){
MyDbHelper mydbhelper2 = new MyDbHelper(MainActivity.this);
Course[] abc = mydbhelper2.query_searchByCourseName(etSearch.getText().toString());
CourseAdapter cadptrSearch = new CourseAdapter(MainActivity.this, R.layout.list_course_row,abc);
ListView lvSearch = (ListView) findViewById(R.id.list);
lvSearch.setAdapter(cadptrSearch);
}

}

public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// TODO Auto-generated method stub
}

public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
}

});

keyListener does not recognise input

setOnKeyListener

Register a callback to be invoked when a hardware key is pressed in
this view. Key presses in software input methods will generally not
trigger the methods of this listener.

setOnEditorActionListener

Set a special listener to be called when an action is performed on the
text view. This will be called when the enter key is pressed, or when
an action supplied to the IME is selected by the user.

To solve your problem using setOnEditorActionListener, please check below:

  • Add imeOptions and inputType to your EditText
<EditText
android:id="@+id/tip"
android:imeOptions="actionDone"
android:inputType="text"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
  • Then add setOnEditorActionListener to EditText
tip.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {

if ( (actionId == EditorInfo.IME_ACTION_DONE) || (event.getKeyCode() == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN) ) {
checkInput();
return true;
} else {
return false;
}
}
});

Here,

  • actionId == EditorInfo.IME_ACTION_DONE handle action from Soft Keyboard (IME)
  • event.getKeyCode() == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN handle enter key from Hardware Keyboard

Android: why is my OnKeyListener() not called?

Are you using the soft keyboard (ime) to type in the edit text? I believe that the onKeyListener only gets invoked with events from the hardware keyboard. You are better off using the TextWatcher if you can. onKeyListener not working with soft keyboard (Android)



Related Topics



Leave a reply



Submit