Android: Backspace в WebView/BaseInputConnection

У меня проблема с программным возвратом клавиатуры в Android (4.2).

У меня есть собственный редактор в WebView (CodeMirror), который внутри использует пустой <textarea>. Похоже, что система Android не отправляет backspace, если только она не считает, что в <textarea> есть какой-то текст.

Я переопределил WebView onCreateInputConnection в попытке упростить программный ввод:

@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;
}

Однако это не работает, и даже onKeyUp не вызывается для возврата.

Как заставить программную клавиатуру всегда отправлять назад?


person Andrey Shchekin    schedule 28.01.2013    source источник


Ответы (2)


Хорошо, наконец-то понял это.

В Android 4.2 (возможно, и в более ранних версиях) возврат на стандартную программную клавиатуру не отправляется как sendKeyEvent(..., KeyEvent.KEYCODE_DEL). Вместо этого он отправляется как deleteSurroundingText(1, 0).

Таким образом, решение в моем случае состоит в том, чтобы создать собственный InputConnection со следующим:

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

Примечание. Пожалуйста, дайте мне знать, если я делаю что-то глупое, так как я уже третий день пишу для Android.

person Andrey Shchekin    schedule 28.01.2013
comment
Эй, я также сталкиваюсь с этой проблемой... за исключением того, что я использую Phonegap, поэтому у меня действительно нет большого низкоуровневого доступа к исходному коду Java, так как он весь скомпилирован. У меня есть доступ только к методу onCreate, все остальное запутано/скомпилировано. Какие-либо предложения? - person Nisk; 11.05.2013
comment
Извините, я никогда не был пользователем PhoneGap, поэтому не могу ответить на ваш вопрос — но попробуйте задать его как отдельный вопрос, и должны быть люди, знакомые с ним. - person Andrey Shchekin; 11.05.2013
comment
В любом случае спасибо, я разместил вопрос, если вы хотите следить за ним: stackoverflow.com/questions/16499178/ - person Nisk; 11.05.2013
comment
Хорошая находка. Это сводило меня с ума. - person André Restivo; 10.06.2013
comment
Очень хорошая находка. Спасибо друг. - person Sean Glover; 13.09.2013
comment
К вашему сведению, вот отчет об этой ошибке, которая до сих пор не назначена: code.google.com/p/android/issues/detail?id=42904 - person Carl; 14.11.2013
comment
Похоже, этот метод перестал работать в Android 4.4 KitKat (по крайней мере, на моем Nexus 5). Кто-нибудь еще заметил это? Я пока не смог найти обходной путь... - person pqvst; 04.12.2013
comment
Да, у меня на 4.3 вообще не работает (на Nexus7 2012). Не в WebView, но это, вероятно, не имеет значения. К вашему сведению, эта проблема исчезает, когда я использую стороннюю программную клавиатуру SwiftKey. Поэтому я почти уверен, что это проблема с программной клавиатурой по умолчанию. И его также нет, когда я устанавливаю targetSdkLevel обратно на уровень API 15, я полагаю. Так что, возможно, программная клавиатура по умолчанию является частью SDK, а не частью установки Android? Или же клавиатура, которая выбирается при установке, зависит от уровня API. В любом случае, я собираюсь попробовать нацелиться на более высокий уровень - мне сейчас 17. - person Carl; 08.12.2013
comment
Я переопределил веб-просмотр, и пользовательский веб-просмотр возвращает customInputConnection из onCreateInputConnection. Это правильный подход? потому что после изменения я не могу активировать клавиатуру в своем веб-просмотре. - person eugene; 10.12.2014
comment
@pbergqvis: тоже не могу заставить это работать .. на 4.4.2 - person eugene; 12.12.2014
comment
Удивительно хороший обходной путь для довольно сложной задачи - отличная работа для кого-то на 3-й день разработки Android. - person Melllvar; 01.01.2015
comment
Это отлично работало, пока я не переключился на другую клавиатуру и не попытался добавить смайлик. Я переключился на Fleksy и попытался добавить смайлик. Он работает в обычном веб-просмотре, но не здесь. Кто-нибудь еще сталкивался с проблемой переключения клавиатуры на что-то, кроме клавиатуры Google? - person pratZ; 20.07.2015
comment
После нескольких часов попыток найти решение это сработало безупречно, спасибо, приятель! - person Sleeper9; 22.03.2016

этот код будет лучше, он работает с большим количеством клавиатур: 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) ;
      }
  }
person Vui Dang    schedule 27.10.2016