title: What does KeyListener do exactly?
body: <p>If I'm right, there is a bug that when the locale says the decimal point is comma (as in Germany or Italy), Android's numeric keyboad does not accept entering commas. It still only accetps dots. I must fix this bug in my app. Requirements are:</p>
  
  <ol>
  <li>When focus is set to an EditText, the program brings up the soft keyboard in symbol/numeric mode.</li>
  <li>When under European locales, the keyboard accepts a comma (and a sign).</li>
  <li>And, #2 must be done programmatically.</li>
  </ol>
  
  <p>I find that I can use XML to achieve #1 and #2 (althgout it'd allow mutiple signs and decimal points in the intput), but it doesn't satisfy #3:</p>
  
  <pre><code>android:inputType="numberDecimal|numberSigned"
  android:digits="1234567890,-"
  </code></pre>
  
  <p>Documentation says <code>android:digits</code> can be acheieved by using <code>KeyListener</code>. So I did a KeyListener to allow/disallow characters. But from what I saw, no matter what I return from <code>onKeyDown()</code>, the input character is always allowed. I expect KeyListener() allows me to filter the input, but I must have missed something. Could you please point it out? Thank you!</p>
  
  <pre><code>et.setKeyListener(new KeyListener() {
      @Override public void clearMetaKeyState(View view, Editable content, int states) {} 
      @Override public int getInputType() {  return InputType.TYPE_CLASS_NUMBER; }
      @Override public boolean onKeyDown(View view, Editable text, int keyCode, KeyEvent event) {
          if ((keyCode &gt;= KeyEvent.KEYCODE_0 &amp;&amp; keyCode &lt;= KeyEvent.KEYCODE_9) ||
              keyCode == KeyEvent.KEYCODE_MINUS || 
              keyCode == KeyEvent.KEYCODE_COMMA) {
              // I want to allow these
              return false;
          }
          // I want to disallow the rest
          return true;
      }
      @Override public boolean onKeyOther(View view, Editable text, KeyEvent event) { return false; }
      @Override public boolean onKeyUp(View view, Editable text, int keyCode, KeyEvent event) { return false; }
  });
  </code></pre>
  
  <p>P.S: I've also tried to use <code>et.setFilters()</code> and give it a custom <code>InputFilter</code>. But it seems that as long as <code>android:inputType="numberDecimal"</code> exists, which I need to set keyboard to number/symbol mode, it ignores my filter.</p>
  
  <pre><code>final int decimalPoint = ',';
  InputFilter[] filterArray = new InputFilter[1];  
  filterArray[0] = new InputFilter() {
      @Override
      public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) 
      {
          int dots = 0, i;
          String s = source.toString();
          String d = dest.toString();
          boolean hasSign = false;
  
          if (source.length() == 0)
              return null;
  
          for (i = 0; i &lt; d.length(); i++)
              if (d.charAt(i) == '-')
                  hasSign = true;
              else if (d.charAt(i) == decimalPoint)
                  dots++;
          for (i = start; i &lt; end &amp;&amp; i &lt; s.length(); i++) {
              if ((s.charAt(i) &gt;= '0' &amp;&amp; s.charAt(i) &lt;= '9') ||
                  (s.charAt(i) == '-' &amp;&amp; !hasSign &amp;&amp; i == start &amp;&amp; d.length() == 0))
                  continue;
              if (s.charAt(i) == decimalPoint &amp;&amp; dots == 0) {
                  dots++;
                  continue;
              }
              s = s.substring(0, start) + s.substring(start + 1, end);
              end--;
          }
          return s.length() == source.length() ? null : s;
      }};
  et.setFilters(filterArray);
  </code></pre>