Home » Android » java – getExtractedText on inactive InputConnection warning on android

java – getExtractedText on inactive InputConnection warning on android

Posted by: admin March 11, 2020 Leave a comment

Questions:

I get the following warning in my logcat.

getExtractedText on inactive InputConnection

I’m unable to find the reason behind it. Please help

How to&Answers:

I ran into a similar issue. My logcat:

W/IInputConnectionWrapper(21214): getTextBeforeCursor on inactive InputConnection
W/IInputConnectionWrapper(21214): getSelectedText on inactive InputConnection
W/IInputConnectionWrapper(21214): getTextBeforeCursor on inactive InputConnection
W/IInputConnectionWrapper(21214): getTextAfterCursor on inactive InputConnection
...
I/Choreographer(20010): Skipped 30 frames!  The application may be doing too much work on its main thread.

My situation:
I have an EditText view the user types into. The EditText gets cleared when user presses a button. Lots of inactive InputConnection entries stream out when I rapidly press the button.

Ex:

editText.setText(null);

The last line in my logcat above provides a great indication of what is happening. Sure enough, the InputConnection is overwhelmed by requests to clear the text. I tried modifying the code to check for text length before trying to clear it:

if (editText.length() > 0) {
    editText.setText(null);
}

This helps mitigate the problem in that pressing the button rapidly no longer causes the stream of IInputConnectionWrapper warnings. However this is still prone to problems when the user rapidly alternates between typing something and pressing the button or presses the button when the app is under sufficient load, etc.

Fortunately, I found another way to clear text: Editable.clear(). With this I don’t get warnings at all:

if (editText.length() > 0) {
    editText.getText().clear();
}

Note that should you wish to clear all input state and not just the text (autotext, autocap, multitap, undo), you can use TextKeyListener.clear(Editable e).

if (editText.length() > 0) {
    TextKeyListener.clear(editText.getText());
}

Answer:

Update:

The reason I was getting InputConnection warnings was not because of where I was setting the text (i.e, in the onTextChanged callback, or the afterTextChanged) — it was because I was using setText.

I got around the issue by calling:

hiddenKeyboardText.getText().clear();
hiddenKeyboardText.append("some string");

Note: I still make the call in the afterTextChanged callback, though it works without warnings from ontextChanged as well.

Previous answer:

I was getting identical messages in logcat as well, though my scenario was slightly different. I wanted to read every character that came into EditText (or composed characters/pasted text), and then reset the EditText in question to a default initialisation string.

The clear text part works as per Johnson’s solution above. However, resetting the text was problematic, and I’d get inputconnection warnings.

Initially, my onTextChanged(CharSequence s, ...) was defined as follows:

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
    if (isResettingKeyboard)
        return;

    // ... do what needs to be done

    resetKeyboardString();

}

public void resetKeyboardString()
{
    isResettingKeyboard = true;

    hiddenKeyboardText.getText().clear();
    hiddenKeyboardText.setText(keyboardInitString);
    hiddenKeyboardText.setSelection(defaultKeyboardCursorLocation);

    isResettingKeyboard = false;
}

When onTextChanged(...) is called, the EditText is in readonly mode. I am not sure if this means we can’t do more than call getText.clear() on it (setText(...) calls produce inputConnection warnings as well).

However, the callback afterTextChanged(Editable s) is the right place to set the text.

@Override
public void afterTextChanged(Editable s) {

    if (isResettingKeyboard)
        return;

    resetKeyboardString();

    // ... 
}

This is, thus far, working without any warnings.

Answer:

From the help documents

http://developer.android.com/reference/android/view/inputmethod/InputConnection.html

The InputConnection interface is the communication channel from an
InputMethod back to the application that is receiving its input. It is
used to perform such things as reading text around the cursor,
committing text to the text box, and sending raw key events to the
application.

In addition, further reading shows

getExtractedText():
This method may fail either if the input connection has become invalid
(such as its process crashing) or the client is taking too long to
respond with the text (it is given a couple seconds to return)
. In
either case, a null is returned.

It appears to also monitor changes to such text, and alert changes.

To hunt the issue down you’ll have to explore any database queries you are making, perhaps around listViews or lists in a layout.

If you don’t have any views, for example it’s happening randomly in the background, then i would suggest that its not a UI element issue, so ignore textfields and such. It could be a background service that’s storing information in a cursor or requesting a cursor.

Also, does the issue arise from your app? or perhaps someone else’s that you’ve installed recently. List the full logCat trace. Someone might recognise the issue.

I would hazard a guess that if you haven’t written something specific around this that its someone elses log message, or perhaps that of a library your using?

Answer:

I was having the same problem. The warning appeared when the soft keyboard was activated in one of my EditTexts and the activity lose focus.

What I did was to hide the keyboard in onPause();

@Override
protected void onPause() {

    // hide the keyboard in order to avoid getTextBeforeCursor on inactive InputConnection
    InputMethodManager inputMethodManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);

    inputMethodManager.hideSoftInputFromWindow(myEditText.getWindowToken(), 0);

    super.onPause();
}

Answer:

Solved this issue for myself maybe you have the same problem.

This was caused by an Object in the HeaderView of the List Adapter.

I inflated a View and declared the Object and put a TextWatcher on it.

View v = LayoutInflater.from(CONTEXT).inflate(R.layout.in_overscrollview, null);
Object= (Object) v.findViewById(R.id.OBJECT_ID);

Object.addTextChangedListener(new TextWatcher() {
        @Override
        public void afterTextChanged(Editable s) {
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after){
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
        //Do my work
        //Update my view
        }
});

Added it to the List Adapter and built the adapter.

JobListView = (ListView) getListView().findViewWithTag("JOBLISTVIEWTAG");
JobListView.addHeaderView(v, null, false);
JobsAdapter = new IN_JOBS_ADAPTER(CONTEXT, ITEMS_FOR_ADATER);
ListView.setAdapter(JOBSadapter);

Everything is fine the Text Watcher works.

BUT if I ever rebuilt the adapter after the initial build.

JobsAdapter = new IN_JOBS_ADAPTER(CONTEXT, DIFFERENT_ITEMS_FOR_ADAPTER);
ListView.setAdapter(JOBSadapter);

That HeaderView is rebuilt too.

That warning would show because the Object was removed and the Text Watcher was still set watching for it.

The List Adapter and Object were replaced, and I’m guessing the Text Watcher was looking the other way when it happened.

So the warning goes off and miraculously the Text Watcher finds the HeaderView and the Object. But it loses focus and logs that warning.

Using

JOBSadapter.notifyDataSetChanged();

fixed the issue.

BUT if you have an Object inside the Adapter, and the Text Watcher is attached to the Object inside the Adapter. Then you may need to do a little more work.

Try removing the Listener and attach it again after doing whatever work you may be doing.

Object.removeTextChangedListener();

or

Object.addTextChangedListener(null);

Answer:

Aside from antoniom’s answer, make sure that any further actions needed to be done, are really done after hiding the keyboard, so if you have hidden the keyboard like the one below:

public void hideKeyboard() {
InputMethodManager inputMethodManager =(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), 0);
}

, you need to have succeeding actions performed post the keyboard hiding, like so:

getWindow().getDecorView().post(new Runnable() {            
        @Override
        public void run() {
            finish(); //Sample succeeding code
     }
});

Answer:

I had this problem when I had to modify or get text from EditText and it was focused.

So before modify or get from it, I closed keyboard and I fix it.

InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);

Maybe, your problem is different.

Answer:

I had solved my problem inserting a input type on xml like this:
android:inputType=”none|text|textCapWords|textUri”

before that was android:inputType=”text”
This solved my problem.

Answer:

Error in Logcat: getTextBeforeCursor on inactive InputConnection

Solution: Hide Your Input Keyboard and run the application.

Answer:

Hide software keyboard before clearing EditText – warnings will not be shown.

Also, It seems to be device specific. I’ve seen it only on Nexus 4 (Android 7.1). No warnings on emulators (8.0, 7.1) or Nexus 5.

Answer:

My problem was caused by setting the visibility of the EditText to GONE and then immediately setting it to VISIBLE each time the user typed a character, as I was running validation on the input each time the text changed and in some cases the view needed to be hidden.

The solution is therefore to avoid setting the View or Layout’s visibility to GONE between UI or state updates, as the EditText may lose focus