Android: Backspace in WebView/BaseInputConnection
Asked Answered
C

2

15

I have a problem with soft keyboard backspace in Android (4.2).

I have a custom editor in a WebView (CodeMirror), which uses an empty <textarea> internally. It seems that backspace is not sent by an Android system unless it believes there is some text in the <textarea>.

I have overridden WebView onCreateInputConnection in an attempt to dumb down soft input:

@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
    Log.d("CustomWebView", "onCreateInputConnection(...)");
    BaseInputConnection connection = new BaseInputConnection(this, false);
    outAttrs.inputType = InputType.TYPE_NULL;
    outAttrs.imeOptions = EditorInfo.IME_ACTION_NONE;
    outAttrs.initialSelStart = -1;
    outAttrs.initialSelEnd = -1;

    return connection;
}

However, this does not work, and even onKeyUp is not called for backspace.

How do I force soft keyboard to always send backspace?

Cocoon answered 28/1, 2013 at 10:48 Comment(0)
C
34

Ok, finally figured this out.

In Android 4.2 (maybe in earlier versions as well) the backspace is not sent as a sendKeyEvent(..., KeyEvent.KEYCODE_DEL) by the standard soft keyboard. Instead, it is sent as deleteSurroundingText(1, 0).

So the solution in my case is to make a custom InputConnection with the following:

@Override
public boolean deleteSurroundingText(int beforeLength, int afterLength) {       
    // magic: in latest Android, deleteSurroundingText(1, 0) will be called for backspace
    if (beforeLength == 1 && afterLength == 0) {
        // backspace
        return super.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL))
            && super.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL));
    }

    return super.deleteSurroundingText(beforeLength, afterLength);
}

Note: Please let me know if I am doing something stupid here, as it is my 3rd day writing for Android.

Cocoon answered 28/1, 2013 at 11:47 Comment(12)
Hey, I'm also running into this issue...except I'm using Phonegap, so I don't really have much low-level access to the java source code, as it's all compiled. I only have access to the onCreate method, everything else is obfuscated/compiled. Any suggestions?Demobilize
Sorry, I have never user PhoneGap, so I can't answer your question — but try asking it as a separate question instead and there should be people familiar with it.Cocoon
Thanks anyhow, I have posted the question, in case you want to keep an eye on it: #16499678Demobilize
Nice find. This was driving me nuts.Prowess
FYI, here is the Issue report for this bug, which has still not been assigned: code.google.com/p/android/issues/detail?id=42904Mohsen
It seems like this method has stopped working in Android 4.4 KitKat (at least on my Nexus 5). Has anyone else noticed this? I have been unable to find a workaround so far...Seamark
Yes, it fails to work for me on 4.3, actually (on Nexus7 2012). Not in a WebView, but that's probably irrelevant. FYI, this problem disappears when I use the third-party SwiftKey soft keyboard. So I'm pretty sure it is a default soft keyboard problem. And it also is not present when I set targetSdkLevel back to API level 15 I believe. So perhaps the default soft keyboard is part of the SDK and not part of the Android installation? Or else, the keyboard that gets selected from the installation depends on the API level. Anyway, I'm going to try targeting a higher level - I'm at 17 now.Mohsen
I have overriden a webview and the custom webview returns customInputConnection from onCreateInputConnection. Is this the right approach? because afther the change, i can't activate the keyboard in my webview.Cardialgia
@pbergqvis: not able to make it work either.. on 4.4.2Cardialgia
Surprisingly good workaround for quite a sophisticated challenge - excellent work for someone on 3rd day of Android development.Nephelometer
This worked great until I switched to a different keyboard and tried to add an emoticon. I switched to Fleksy and tried to add an emoticon. It works on the normal webview but not here. Did anyone else faced the issue on switching keyboard to something other than google keyboard?Cutis
After hours of trying to find the solution, this worked flawlessly, thanks mate!Araucania
B
2

this code will be better, it work with more keyboard :D

@Override
  public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
      outAttrs.actionLabel = null;
      outAttrs.inputType = InputType.TYPE_NULL;
      final InputConnection con = new BaseInputConnection(this,false);
      InputConnectionWrapper public_con = new InputConnectionWrapper(
              super.onCreateInputConnection(outAttrs), true) {
          @Override
          public boolean deleteSurroundingText(int beforeLength, int afterLength) {
              if (beforeLength == 1 && afterLength == 0) {
                  return this.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL))
                          && this.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL));
              }
              return super.deleteSurroundingText(beforeLength, afterLength);
          }

          @Override
          public boolean sendKeyEvent(KeyEvent event) {
              if(event.getKeyCode() == KeyEvent.KEYCODE_DEL){
                  return con.sendKeyEvent(event);
              }else {
                  return super.sendKeyEvent(event);
              }
          }
      };
      try {
          return public_con ;
      }catch (Exception e){
          return super.onCreateInputConnection(outAttrs) ;
      }
  }
Breunig answered 27/10, 2016 at 6:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.