title: Android OnEditorActionListener() actionId give 0 when I click Done key
body: <p>I have created one keyboard.When user enter numbers , its entering particular EditText.But When User click on <code>Done</code> key, it didn't go to <code>setOnEditorActionListener</code> but its closing the keyboard.</p>
  
  <p>This is my code :</p>
  
  <pre><code> final EditText txtQty = new EditText(this);
          txtQty.setHeight(1);
          txtQty.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, 42));
          txtQty.setInputType(InputType.TYPE_CLASS_PHONE);
          txtQty.setImeOptions(EditorInfo.IME_ACTION_DONE);
          txtQty.setSelectAllOnFocus(true);
          txtQty.setTextSize(9);
          txtQty.setVisibility(View.VISIBLE);
          txtQty.setHint("0.0");
          txtQty.setHighlightColor(R.color.green);
          tr.addView(txtQty);
   txtQty.setOnEditorActionListener( new OnEditorActionListener() {
              public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                  Log.i("KeyBoard" ,"Inside the Edit Text");
                  if (actionId == EditorInfo.IME_ACTION_DONE ||actionId == EditorInfo.IME_ACTION_NEXT ) { ......}
  </code></pre>
  
  <p>Here its give actionId = 0
  and EditorInfo.IME_ACTION_NEXT =5</p>
  
  <p>When I run through the Android Softkeyboard its working fine</p>
  
  <pre><code> txtQty.setOnEditorActionListener( new OnEditorActionListener() {
              public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                  Log.i("KeyBoard" ,"Inside the Edit Text");
                  Log.i("---EditorInfo.IME_ACTION_NEXT---" , EditorInfo.IME_ACTION_NEXT);
                  Log.i("---actionId---" , actionId);
                  Log.i("---event---" , event);
                  Log.i("---EditorInfo.IME_ACTION_DONE---" , EditorInfo.IME_ACTION_DONE);
  </code></pre>
  
  <p>Here giving <code>EditorInfo.IME_ACTION_NEXT =5 , actionId =5 &amp; EditorInfo.IME_ACTION_DONE = 6, actionId=6</code>
  But when I run through my Soft keyboard gave  <code>EditorInfo.IME_ACTION_NEXT =5 , actionId =0 &amp; EditorInfo.IME_ACTION_DONE = 6, actionId=0</code></p>
  
  <p>This is the problem.Where its wrong? Why it didn't take <code>actionId</code> value?</p>
  
  <p>This is kind of scenario i am doing:</p>
  
  <p><img src="https://i.stack.imgur.com/KHYq1.png" alt="enter image description here"></p>
  
  <p><strong>EDITED/UPDATED</strong></p>
  
  <pre><code>    public class SoftKeyboard extends InputMethodService implements KeyboardView.OnKeyboardActionListener {
      static final boolean DEBUG = false;
      static final boolean PROCESS_HARD_KEYS = true;
      private KeyboardView mInputView;
      private CandidateView mCandidateView;
      private CompletionInfo[] mCompletions;
      private StringBuilder mComposing = new StringBuilder();
      private boolean mPredictionOn;
      private boolean mCompletionOn;
      private int mLastDisplayWidth;
      private boolean mCapsLock;
      private long mLastShiftTime;
      private long mMetaState;
      private LatinKeyboard mSymbolsKeyboard;
      private LatinKeyboard mSymbolsShiftedKeyboard;
      private LatinKeyboard mQwertyKeyboard;
      private LatinKeyboard mCurKeyboard; 
      private String mWordSeparators;
  
      @Override public void onCreate() {
          super.onCreate();
          mWordSeparators = getResources().getString(R.string.word_separators);
      }
  
      @Override public void onInitializeInterface() {
          if (mQwertyKeyboard != null) {
              int displayWidth = getMaxWidth();
              if (displayWidth == mLastDisplayWidth) return;
              mLastDisplayWidth = displayWidth;
          }
          mQwertyKeyboard = new LatinKeyboard(this, R.xml.qwerty);
          mSymbolsKeyboard = new LatinKeyboard(this, R.xml.symbols);
          mSymbolsShiftedKeyboard = new LatinKeyboard(this, R.xml.symbols_shift);
      }
  
  
      @Override public View onCreateInputView() {
          mInputView = (KeyboardView) getLayoutInflater().inflate(
                  R.layout.input, null);
          mInputView.setOnKeyboardActionListener(this);
          mInputView.setKeyboard(mQwertyKeyboard);
          return mInputView;
      }
  
      @Override public View onCreateCandidatesView() {
          mCandidateView = new CandidateView(this);
          mCandidateView.setService(this);
          return mCandidateView;
      }
  
      @Override public void onStartInput(EditorInfo attribute, boolean restarting) {
          super.onStartInput(attribute, restarting);
  
          mComposing.setLength(0);
          updateCandidates();
  
          if (!restarting) {
              mMetaState = 0;
          }
  
          mPredictionOn = false;
          mCompletionOn = false;
          mCompletions = null;
  
          switch (attribute.inputType&amp;EditorInfo.TYPE_MASK_CLASS) {
              case EditorInfo.TYPE_CLASS_NUMBER:
              case EditorInfo.TYPE_CLASS_DATETIME:
                  mCurKeyboard = mSymbolsKeyboard;
                  break;
  
              case EditorInfo.TYPE_CLASS_PHONE:
                  mCurKeyboard = mSymbolsKeyboard;
                  break;
  
              case EditorInfo.TYPE_CLASS_TEXT:
                  mCurKeyboard = mQwertyKeyboard;
                  mPredictionOn = true;
                  int variation = attribute.inputType &amp;  EditorInfo.TYPE_MASK_VARIATION;
                  if (variation == EditorInfo.TYPE_TEXT_VARIATION_PASSWORD ||
                          variation == EditorInfo.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) {
                      mPredictionOn = false;
                  }
  
                  if (variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS 
                          || variation == EditorInfo.TYPE_TEXT_VARIATION_URI
                          || variation == EditorInfo.TYPE_TEXT_VARIATION_FILTER) {
                      mPredictionOn = false;
                  }
  
                  if ((attribute.inputType&amp;EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) {
  
                      mPredictionOn = false;
                      mCompletionOn = isFullscreenMode();
                  }
  
                  updateShiftKeyState(attribute);
                  break;
  
              default:
                  mCurKeyboard = mQwertyKeyboard;
                  updateShiftKeyState(attribute);
          }
          mCurKeyboard.setImeOptions(getResources(), attribute.imeOptions);
      }
  
      @Override public void onFinishInput() {
          super.onFinishInput();
  
          // Clear current composing text and candidates.
          mComposing.setLength(0);
          updateCandidates();
          setCandidatesViewShown(false);
  
          mCurKeyboard = mQwertyKeyboard;
          if (mInputView != null) {
              mInputView.closing();
          }
      }
  
      @Override public void onStartInputView(EditorInfo attribute, boolean restarting) {
          super.onStartInputView(attribute, restarting);
          mInputView.setKeyboard(mCurKeyboard);
          mInputView.closing();
      }
  
      @Override 
      public void onUpdateSelection(int oldSelStart, int oldSelEnd,
              int newSelStart, int newSelEnd,
              int candidatesStart, int candidatesEnd) {
          super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd,
                  candidatesStart, candidatesEnd);
          if (mComposing.length() &gt; 0 &amp;&amp; (newSelStart != candidatesEnd
                  || newSelEnd != candidatesEnd)) {
              mComposing.setLength(0);
              updateCandidates();
              InputConnection ic = getCurrentInputConnection();
              if (ic != null) {
                  ic.finishComposingText();
              }
          }
      }
  
      @Override 
      public void onDisplayCompletions(CompletionInfo[] completions) {
          if (mCompletionOn) {
              mCompletions = completions;
              if (completions == null) {
                  setSuggestions(null, false, false);
                  return;
              }
  
              List&lt;String&gt; stringList = new ArrayList&lt;String&gt;();
              for (int i=0; i&lt;(completions != null ? completions.length : 0); i++) {
                  CompletionInfo ci = completions[i];
                  if (ci != null) stringList.add(ci.getText().toString());
              }
              setSuggestions(stringList, true, true);
          }
      }
  
      private boolean translateKeyDown(int keyCode, KeyEvent event) {
          mMetaState = MetaKeyKeyListener.handleKeyDown(mMetaState,
                  keyCode, event);
          int c = event.getUnicodeChar(MetaKeyKeyListener.getMetaState(mMetaState));
          mMetaState = MetaKeyKeyListener.adjustMetaAfterKeypress(mMetaState);
          InputConnection ic = getCurrentInputConnection();
          if (c == 0 || ic == null) {
              return false;
          }
  
          boolean dead = false;
  
          if ((c &amp; KeyCharacterMap.COMBINING_ACCENT) != 0) {
              dead = true;
              c = c &amp; KeyCharacterMap.COMBINING_ACCENT_MASK;
          }
  
          if (mComposing.length() &gt; 0) {
              char accent = mComposing.charAt(mComposing.length() -1 );
              int composed = KeyEvent.getDeadChar(accent, c);
  
              if (composed != 0) {
                  c = composed;
                  mComposing.setLength(mComposing.length()-1);
              }
          }
  
          onKey(c, null);
  
          return true;
      }
  
  
      @Override 
      public boolean onKeyDown(int keyCode, KeyEvent event) {
          switch (keyCode) {
              case KeyEvent.KEYCODE_BACK:
                  if (event.getRepeatCount() == 0 &amp;&amp; mInputView != null) {
                      if (mInputView.handleBack()) {
                          return true;
                      }
                  }
                  break;
  
              case KeyEvent.KEYCODE_DEL:
                  if (mComposing.length() &gt; 0) {
                      onKey(Keyboard.KEYCODE_DELETE, null);
                      return true;
                  }
                  break;
  
              case KeyEvent.KEYCODE_ENTER:
                  return false;
  
  
  
              default:
                  if (PROCESS_HARD_KEYS) {
                      if (keyCode == KeyEvent.KEYCODE_SPACE
                              &amp;&amp; (event.getMetaState()&amp;KeyEvent.META_ALT_ON) != 0) {
                          InputConnection ic = getCurrentInputConnection();
                          if (ic != null) {
                              ic.clearMetaKeyStates(KeyEvent.META_ALT_ON);
                              keyDownUp(KeyEvent.KEYCODE_A);
                              keyDownUp(KeyEvent.KEYCODE_N);
                              keyDownUp(KeyEvent.KEYCODE_D);
                              keyDownUp(KeyEvent.KEYCODE_R);
                              keyDownUp(KeyEvent.KEYCODE_O);
                              keyDownUp(KeyEvent.KEYCODE_I);
                              keyDownUp(KeyEvent.KEYCODE_D);
                              return true;
                          }
                      }
                      if (mPredictionOn &amp;&amp; translateKeyDown(keyCode, event)) {
                          return true;
                      }
                  }
          }
  
          return super.onKeyDown(keyCode, event);
      }
  
      @Override 
      public boolean onKeyUp(int keyCode, KeyEvent event) {
          if (PROCESS_HARD_KEYS) {
              if (mPredictionOn) {
                  mMetaState = MetaKeyKeyListener.handleKeyUp(mMetaState,
                          keyCode, event);
              }
          }
  
          return super.onKeyUp(keyCode, event);
      }
  
      private void commitTyped(InputConnection inputConnection) {
          if (mComposing.length() &gt; 0) {
              inputConnection.commitText(mComposing, mComposing.length());
              mComposing.setLength(0);
              updateCandidates();
          }
      }
  
      private void updateShiftKeyState(EditorInfo attr) {
          if (attr != null 
                  &amp;&amp; mInputView != null &amp;&amp; mQwertyKeyboard == mInputView.getKeyboard()) {
              int caps = 0;
              EditorInfo ei = getCurrentInputEditorInfo();
              if (ei != null &amp;&amp; ei.inputType != EditorInfo.TYPE_NULL) {
                  caps = getCurrentInputConnection().getCursorCapsMode(attr.inputType);
              }
              mInputView.setShifted(mCapsLock || caps != 0);
          }
      }
  
      private boolean isAlphabet(int code) {
          if (Character.isLetter(code)) {
              return true;
          } else {
              return false;
          }
      }
  
      private void keyDownUp(int keyEventCode) {
          getCurrentInputConnection().sendKeyEvent(
                  new KeyEvent(KeyEvent.ACTION_DOWN, keyEventCode));
          getCurrentInputConnection().sendKeyEvent(
                  new KeyEvent(KeyEvent.ACTION_UP, keyEventCode));
      }
  
      private void sendKey(int keyCode) {
          switch (keyCode) {
              case '\n':
                  keyDownUp(KeyEvent.KEYCODE_ENTER);
                  break;
              default:
                  if (keyCode &gt;= '0' &amp;&amp; keyCode &lt;= '9') {
                      keyDownUp(keyCode - '0' + KeyEvent.KEYCODE_0);
                  } else {
                      getCurrentInputConnection().commitText(String.valueOf((char) keyCode), 1);
                  }
                  break;
          }
      }
  
  
      public void onKey(int primaryCode, int[] keyCodes) {
          if (isWordSeparator(primaryCode)) {
              // Handle separator
              if (mComposing.length() &gt; 0) {
                  commitTyped(getCurrentInputConnection());
              }
              sendKey(primaryCode);
              updateShiftKeyState(getCurrentInputEditorInfo());
          } else if (primaryCode == Keyboard.KEYCODE_DELETE) {
              handleBackspace();
          } else if (primaryCode == Keyboard.KEYCODE_SHIFT) {
              handleShift();
          } else if (primaryCode == Keyboard.KEYCODE_CANCEL) {
              handleClose();
              return;
          } else if (primaryCode == LatinKeyboardView.KEYCODE_OPTIONS) {
              // Show a menu or somethin'
          } else if (primaryCode == Keyboard.KEYCODE_MODE_CHANGE
                  &amp;&amp; mInputView != null) {
              Keyboard current = mInputView.getKeyboard();
              if (current == mSymbolsKeyboard || current == mSymbolsShiftedKeyboard) {
                  current = mQwertyKeyboard;
              } else {
                  current = mSymbolsKeyboard;
              }
              mInputView.setKeyboard(current);
              if (current == mSymbolsKeyboard) {
                  current.setShifted(false);
              }
          } else {
              handleCharacter(primaryCode, keyCodes);
          }
      }
  
      public void onText(CharSequence text) {
          InputConnection ic = getCurrentInputConnection();
          if (ic == null) return;
          ic.beginBatchEdit();
          if (mComposing.length() &gt; 0) {
              commitTyped(ic);
          }
          ic.commitText(text, 0);
          ic.endBatchEdit();
          updateShiftKeyState(getCurrentInputEditorInfo());
      }
  
      private void updateCandidates() {
          if (!mCompletionOn) {
              if (mComposing.length() &gt; 0) {
                  ArrayList&lt;String&gt; list = new ArrayList&lt;String&gt;();
                  list.add(mComposing.toString());
                  setSuggestions(list, true, true);
              } else {
                  setSuggestions(null, false, false);
              }
          }
      }
  
      public void setSuggestions(List&lt;String&gt; suggestions, boolean completions,
              boolean typedWordValid) {
          if (suggestions != null &amp;&amp; suggestions.size() &gt; 0) {
              setCandidatesViewShown(true);
          } else if (isExtractViewShown()) {
              setCandidatesViewShown(true);
          }
          if (mCandidateView != null) {
              mCandidateView.setSuggestions(suggestions, completions, typedWordValid);
          }
      }
  
      private void handleBackspace() {
          final int length = mComposing.length();
          if (length &gt; 1) {
              mComposing.delete(length - 1, length);
              getCurrentInputConnection().setComposingText(mComposing, 1);
              updateCandidates();
          } else if (length &gt; 0) {
              mComposing.setLength(0);
              getCurrentInputConnection().commitText("", 0);
              updateCandidates();
          } else {
              keyDownUp(KeyEvent.KEYCODE_DEL);
          }
          updateShiftKeyState(getCurrentInputEditorInfo());
      }
  
      private void handleShift() {
          if (mInputView == null) {
              return;
          }
  
          Keyboard currentKeyboard = mInputView.getKeyboard();
          if (mQwertyKeyboard == currentKeyboard) {
              // Alphabet keyboard
              checkToggleCapsLock();
              mInputView.setShifted(mCapsLock || !mInputView.isShifted());
          } else if (currentKeyboard == mSymbolsKeyboard) {
              mSymbolsKeyboard.setShifted(true);
              mInputView.setKeyboard(mSymbolsShiftedKeyboard);
              mSymbolsShiftedKeyboard.setShifted(true);
          } else if (currentKeyboard == mSymbolsShiftedKeyboard) {
              mSymbolsShiftedKeyboard.setShifted(false);
              mInputView.setKeyboard(mSymbolsKeyboard);
              mSymbolsKeyboard.setShifted(false);
          }
      }
  
      private void handleCharacter(int primaryCode, int[] keyCodes) {
          if (isInputViewShown()) {
              if (mInputView.isShifted()) {
                  primaryCode = Character.toUpperCase(primaryCode);
              }
          }
          if (isAlphabet(primaryCode) &amp;&amp; mPredictionOn) {
              mComposing.append((char) primaryCode);
              getCurrentInputConnection().setComposingText(mComposing, 1);
              updateShiftKeyState(getCurrentInputEditorInfo());
              updateCandidates();
          } else {
              getCurrentInputConnection().commitText(
                      String.valueOf((char) primaryCode), 1);
          }
      }
  
      private void handleClose() {
          commitTyped(getCurrentInputConnection());
          requestHideSelf(0);
          mInputView.closing();
      }
  
      private void checkToggleCapsLock() {
          long now = System.currentTimeMillis();
          if (mLastShiftTime + 800 &gt; now) {
              mCapsLock = !mCapsLock;
              mLastShiftTime = 0;
          } else {
              mLastShiftTime = now;
          }
      }
  
      private String getWordSeparators() {
          return mWordSeparators;
      }
  
      public boolean isWordSeparator(int code) {
          String separators = getWordSeparators();
          return separators.contains(String.valueOf((char)code));
      }
  
      public void pickDefaultCandidate() {
          pickSuggestionManually(0);
      }
  
      public void pickSuggestionManually(int index) {
          if (mCompletionOn &amp;&amp; mCompletions != null &amp;&amp; index &gt;= 0
                  &amp;&amp; index &lt; mCompletions.length) {
              CompletionInfo ci = mCompletions[index];
              getCurrentInputConnection().commitCompletion(ci);
              if (mCandidateView != null) {
                  mCandidateView.clear();
              }
              updateShiftKeyState(getCurrentInputEditorInfo());
          } else if (mComposing.length() &gt; 0) {
  
              commitTyped(getCurrentInputConnection());
          }
      }
  
      public void swipeRight() {
          if (mCompletionOn) {
              pickDefaultCandidate();
          }
      }
  
      public void swipeLeft() {
          handleBackspace();
      }
  
      public void swipeDown() {
          handleClose();
      }
  
      public void swipeUp() {
      }
  
      public void onPress(int primaryCode) {
      }
  
      public void onRelease(int primaryCode) {
      }
  }
  </code></pre>
  
  <p>And symbols.xml file :</p>
  
  <pre><code>   &lt;Key android:codes="-3" android:keyIcon="@drawable/sym_keyboard_done" android:keyWidth="20%p" android:keyEdgeFlags="left" /&gt;
  </code></pre>
  
  <p>When I click <code>Done</code> key also I didn't go to <code>OnEditorActionListener</code> method. Please help me</p>
  
  <p>Please help me this: </p>
  
  <hr>
  
  <p>I have tried like this : But not proper solution. Anyhow I want to take actionId , according to actionId i want put switch statement &amp; want to know why it didn't take actionId when we use other than the android keyboard</p>
  
  <pre><code>  txtQty.setOnEditorActionListener( new OnEditorActionListener() {
          public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
  
           if(event.getKeyCode() == KeyEvent.KEYCODE_ENTER){ } .....
  </code></pre>