android.view.inputmethod.ExtractedText Java Examples

The following examples show how to use android.view.inputmethod.ExtractedText. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: CtrlInputAction.java    From remotekeyboard with Apache License 2.0 6 votes vote down vote up
/**
 * Try to replace the current word with its substitution.
 */
private void replaceText(InputConnection con) {
	ExtractedText txt = con.getExtractedText(new ExtractedTextRequest(), 0);
	if (txt != null) {
		int end = txt.text.toString().indexOf(" ", txt.selectionEnd);
		if (end == -1) {
			end = txt.text.length();
		}
		int start = txt.text.toString().lastIndexOf(" ", txt.selectionEnd - 1);
		start++;
		String sel = txt.text.subSequence(start, end).toString();
		String rep = myService.replacements.get(sel);
		if (rep != null) {
			con.setComposingRegion(start, end);
			con.setComposingText(rep, 1);
			con.finishComposingText();
		}
		else {
			String err = myService.getResources().getString(
					R.string.err_no_replacement, sel);
			Toast.makeText(myService, err, Toast.LENGTH_SHORT).show();
		}
	}
}
 
Example #2
Source File: InputConnectionCommandEditor.java    From speechutils with Apache License 2.0 6 votes vote down vote up
@Override
public Op moveAbs(final int pos) {
    return new Op("moveAbs " + pos) {
        @Override
        public Op run() {
            Op undo = null;
            mInputConnection.beginBatchEdit();
            ExtractedText et = getExtractedText();
            if (et != null) {
                int charPos = pos;
                if (pos < 0) {
                    //-1 == end of text
                    charPos = et.text.length() + pos + 1;
                }
                undo = getOpSetSelection(charPos, charPos, et.selectionStart, et.selectionEnd).run();
            }
            mInputConnection.endBatchEdit();
            return undo;
        }
    };
}
 
Example #3
Source File: InputConnectionCommandEditor.java    From speechutils with Apache License 2.0 6 votes vote down vote up
/**
 * mInputConnection.performContextMenuAction(android.R.id.selectAll) does not create a selection
 */
@Override
public Op selectAll() {
    return new Op("selectAll") {
        @Override
        public Op run() {
            Op undo = null;
            mInputConnection.beginBatchEdit();
            final ExtractedText et = getExtractedText();
            if (et != null) {
                undo = getOpSetSelection(0, et.text.length(), et.selectionStart, et.selectionEnd).run();
            }
            mInputConnection.endBatchEdit();
            return undo;
        }
    };
}
 
Example #4
Source File: InputConnectionCommandEditor.java    From speechutils with Apache License 2.0 6 votes vote down vote up
@Override
public Op select(final String query) {
    return new Op("select " + query) {
        @Override
        public Op run() {
            Op undo = null;
            mInputConnection.beginBatchEdit();
            ExtractedText et = getExtractedText();
            if (et != null) {
                Pair<Integer, CharSequence> queryResult = lastIndexOf(query.replace(F_SELECTION, getSelectedText()), et);
                if (queryResult.first >= 0) {
                    undo = getOpSetSelection(queryResult.first, queryResult.first + queryResult.second.length(), et.selectionStart, et.selectionEnd).run();
                }
            }
            mInputConnection.endBatchEdit();
            return undo;
        }
    };
}
 
Example #5
Source File: InputConnectionCommandEditor.java    From speechutils with Apache License 2.0 6 votes vote down vote up
@Override
public Op selectReBefore(final String regex) {
    return new Op("selectReBefore") {
        @Override
        public Op run() {
            Op undo = null;
            mInputConnection.beginBatchEdit();
            final ExtractedText et = getExtractedText();
            if (et != null) {
                CharSequence input = et.text.subSequence(0, et.selectionStart);
                CharSequence selectedText = et.text.subSequence(et.selectionStart, et.selectionEnd);
                // 0 == last match
                Pair<Integer, Integer> pos = matchNth(Pattern.compile(regex.replace(F_SELECTION, selectedText)), input, 0);
                if (pos != null) {
                    undo = getOpSetSelection(pos.first, pos.second, et.selectionStart, et.selectionEnd).run();
                }
            }
            mInputConnection.endBatchEdit();
            return undo;
        }
    };
}
 
Example #6
Source File: InputConnectionCommandEditor.java    From speechutils with Apache License 2.0 6 votes vote down vote up
@Override
public Op selectReAfter(final String regex, final int n) {
    return new Op("selectReAfter") {
        @Override
        public Op run() {
            Op undo = null;
            mInputConnection.beginBatchEdit();
            final ExtractedText et = getExtractedText();
            if (et != null) {
                CharSequence input = et.text.subSequence(et.selectionEnd, et.text.length());
                // TODO: sometimes crashes with:
                // StringIndexOutOfBoundsException: String index out of range: -4
                CharSequence selectedText = et.text.subSequence(et.selectionStart, et.selectionEnd);
                Pair<Integer, Integer> pos = matchNth(Pattern.compile(regex.replace(F_SELECTION, selectedText)), input, n);
                if (pos != null) {
                    undo = getOpSetSelection(et.selectionEnd + pos.first, et.selectionEnd + pos.second, et.selectionStart, et.selectionEnd).run();
                }
            }
            mInputConnection.endBatchEdit();
            return undo;
        }
    };
}
 
Example #7
Source File: InputConnectionCommandEditor.java    From AlexaAndroid with GNU General Public License v2.0 6 votes vote down vote up
@Override
public boolean replace(String str1, String str2) {
    boolean success = false;
    mInputConnection.beginBatchEdit();
    ExtractedText extractedText = mInputConnection.getExtractedText(new ExtractedTextRequest(), 0);
    if (extractedText != null) {
        CharSequence beforeCursor = extractedText.text;
        //CharSequence beforeCursor = mInputConnection.getTextBeforeCursor(MAX_SELECTABLE_CONTEXT, 0);
        Log.i("replace: " + beforeCursor);
        int index = beforeCursor.toString().lastIndexOf(str1);
        Log.i("replace: " + index);
        if (index > 0) {
            mInputConnection.setSelection(index, index);
            mInputConnection.deleteSurroundingText(0, str1.length());
            if (!str2.isEmpty()) {
                mInputConnection.commitText(str2, 0);
            }
            success = true;
        }
        mInputConnection.endBatchEdit();
    }
    return success;
}
 
Example #8
Source File: InputConnectionCommandEditor.java    From speechutils with Apache License 2.0 6 votes vote down vote up
@Override
public Op selectRe(final String regex, final boolean applyToSelection) {
    return new Op("selectRe") {
        @Override
        public Op run() {
            Op undo = null;
            mInputConnection.beginBatchEdit();
            final ExtractedText et = getExtractedText();
            if (et != null) {
                if (applyToSelection || et.selectionStart == et.selectionEnd) {
                    Pair<Integer, Integer> pos = matchAtPos(Pattern.compile(regex), et.text, et.selectionStart, et.selectionEnd);
                    if (pos != null) {
                        undo = getOpSetSelection(pos.first, pos.second, et.selectionStart, et.selectionEnd).run();
                    }
                }
            }
            mInputConnection.endBatchEdit();
            return undo;
        }
    };
}
 
Example #9
Source File: MongolEditText.java    From mongol-library with MIT License 6 votes vote down vote up
private void reportExtractedText() {

        // custom keyboards don't have an extracted view.
        if (mMongolImeManager != null) return;

        // TODO cancel this if not in extracted text mode

        ExtractedText et = new ExtractedText();
        final CharSequence content = getText();
        final int length = content.length();
        et.partialStartOffset = -1;
        et.partialEndOffset = -1;
        et.startOffset = 0;
        et.selectionStart = getSelectionStart();
        et.selectionEnd = getSelectionEnd();
        et.flags = 0;
        et.text = content.subSequence(0, length);

        InputMethodManager imm = (InputMethodManager) getContext()
                .getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm == null) return;
        imm.updateExtractedText(this, mExtractedTextRequestToken, et);
    }
 
Example #10
Source File: ThreadedInputConnection.java    From 365browser with Apache License 2.0 6 votes vote down vote up
private void updateSelection(TextInputState textInputState) {
    if (textInputState == null) return;
    assertOnImeThread();
    if (mNumNestedBatchEdits != 0) return;
    Range selection = textInputState.selection();
    Range composition = textInputState.composition();
    // As per Guidelines in
    // https://developer.android.com/reference/android/view/inputmethod/InputConnection.html
    // #getExtractedText(android.view.inputmethod.ExtractedTextRequest,%20int)
    // States that if the GET_EXTRACTED_TEXT_MONITOR flag is set,
    // you should be calling updateExtractedText(View, int, ExtractedText)
    // whenever you call updateSelection(View, int, int, int, int).
    if (mShouldUpdateExtractedText) {
        final ExtractedText extractedText = convertToExtractedText(textInputState);
        mImeAdapter.updateExtractedText(mCurrentExtractedTextRequestToken, extractedText);
    }
    mImeAdapter.updateSelection(
            selection.start(), selection.end(), composition.start(), composition.end());
}
 
Example #11
Source File: ThreadedInputConnection.java    From 365browser with Apache License 2.0 5 votes vote down vote up
private ExtractedText convertToExtractedText(TextInputState textInputState) {
    if (textInputState == null) return null;
    ExtractedText extractedText = new ExtractedText();
    extractedText.text = textInputState.text();
    extractedText.partialEndOffset = textInputState.text().length();
    // Set the partial start offset to -1 because the content is the full text.
    // See: Android documentation for ExtractedText#partialStartOffset
    extractedText.partialStartOffset = -1;
    extractedText.selectionStart = textInputState.selection().start();
    extractedText.selectionEnd = textInputState.selection().end();
    extractedText.flags = textInputState.singleLine() ? ExtractedText.FLAG_SINGLE_LINE : 0;
    return extractedText;
}
 
Example #12
Source File: Session.java    From FirefoxReality with Mozilla Public License 2.0 5 votes vote down vote up
@Override
public void updateExtractedText(@NonNull GeckoSession aSession, @NonNull ExtractedTextRequest request, @NonNull ExtractedText text) {
    if (mState.mSession == aSession) {
        for (GeckoSession.TextInputDelegate listener : mTextInputListeners) {
            listener.updateExtractedText(aSession, request, text);
        }
    }
}
 
Example #13
Source File: InputConnectionCommandEditor.java    From speechutils with Apache License 2.0 5 votes vote down vote up
/**
 * TODO: review
 * we should be able to review the last N ops and undo them if they can be interpreted as
 * a combined op.
 */
private Op getCommitWithOverwriteOp(final String text, final boolean isCommand) {
    return new Op("add " + text) {
        @Override
        public Op run() {
            mInputConnection.beginBatchEdit();
            final ExtractedText et = getExtractedText();
            final String selectedText = getSelectedText();
            if (text.isEmpty() && !selectedText.isEmpty() && isCommand) {
                mInputConnection.endBatchEdit();
                return null;
            }
            final int addedLength = commitWithOverwrite(text, true);
            mInputConnection.endBatchEdit();
            return new Op("delete " + addedLength) {
                @Override
                public Op run() {
                    mInputConnection.beginBatchEdit();
                    boolean success = deleteSurrounding(addedLength, 0);
                    if (et != null && selectedText.length() > 0) {
                        success = mInputConnection.commitText(selectedText, 1) &&
                                mInputConnection.setSelection(et.selectionStart, et.selectionEnd);
                    }
                    mInputConnection.endBatchEdit();
                    if (success) {
                        return NO_OP;
                    }
                    return null;
                }
            };
        }
    };
}
 
Example #14
Source File: InputConnectionCommandEditor.java    From speechutils with Apache License 2.0 5 votes vote down vote up
/**
 * Op that commits a text at the cursor. If successful then an undo is returned which deletes
 * the text and restores the old selection.
 */
private Op getCommitTextOp(final CharSequence oldText, final CharSequence newText) {
    return new Op("commitText") {
        @Override
        public Op run() {
            Op undo = null;
            // TODO: use getSelection
            final ExtractedText et = getExtractedText();
            if (mInputConnection.commitText(newText, 1)) {
                undo = new Op("deleteSurroundingText+commitText") {
                    @Override
                    public Op run() {
                        mInputConnection.beginBatchEdit();
                        boolean success = deleteSurrounding(newText.length(), 0);
                        if (success && oldText != null) {
                            success = mInputConnection.commitText(oldText, 1);
                        }
                        if (et != null && success) {
                            success = mInputConnection.setSelection(et.selectionStart, et.selectionEnd);
                        }
                        mInputConnection.endBatchEdit();
                        if (success) {
                            return NO_OP;
                        }
                        return null;
                    }
                };
            }
            return undo;
        }
    };
}
 
Example #15
Source File: InputConnectionCommandEditor.java    From speechutils with Apache License 2.0 5 votes vote down vote up
/**
 * Tries to match a substring before the cursor, using case-insensitive matching.
 * TODO: this might not work with some Unicode characters
 *
 * @param query search string
 * @param et    text to search from
 * @return pair index of the last occurrence of the match, and the matched string
 */
private Pair<Integer, CharSequence> lastIndexOf(String query, ExtractedText et) {
    int start = et.selectionStart;
    query = query.toLowerCase();
    CharSequence input = et.text.subSequence(0, start);
    CharSequence match = null;
    int index = input.toString().toLowerCase().lastIndexOf(query);
    if (index >= 0) {
        match = input.subSequence(index, index + query.length());
    }
    return new Pair<>(index, match);
}
 
Example #16
Source File: InputConnectionCommandEditor.java    From speechutils with Apache License 2.0 5 votes vote down vote up
private Op move(final int numberOfChars, final int type) {
    return new Op("moveRel") {
        @Override
        public Op run() {
            Op undo = null;
            mInputConnection.beginBatchEdit();
            ExtractedText extractedText = getExtractedText();
            if (extractedText != null) {
                int newStart = extractedText.selectionStart;
                int newEnd = extractedText.selectionEnd;
                if (type == 0) {
                    newStart += numberOfChars;
                } else if (type == 1) {
                    newEnd += numberOfChars;
                } else {
                    if (numberOfChars < 0) {
                        newStart += numberOfChars;
                        newEnd = newStart;
                    } else {
                        newEnd += numberOfChars;
                        newStart = newEnd;
                    }
                }
                undo = getOpSetSelection(newStart, newEnd, extractedText.selectionStart, extractedText.selectionEnd).run();
            }
            mInputConnection.endBatchEdit();
            return undo;
        }
    };
}
 
Example #17
Source File: ThreadedInputConnection.java    From 365browser with Apache License 2.0 5 votes vote down vote up
/**
 * @see InputConnection#getExtractedText(android.view.inputmethod.ExtractedTextRequest, int)
 */
@Override
public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) {
    if (DEBUG_LOGS) Log.i(TAG, "getExtractedText");
    assertOnImeThread();
    mShouldUpdateExtractedText = (flags & GET_EXTRACTED_TEXT_MONITOR) > 0;
    if (mShouldUpdateExtractedText) {
        mCurrentExtractedTextRequestToken = request != null ? request.token : 0;
    }
    TextInputState textInputState = requestAndWaitForTextInputState();
    return convertToExtractedText(textInputState);
}
 
Example #18
Source File: CtrlInputAction.java    From remotekeyboard with Apache License 2.0 5 votes vote down vote up
/**
 * use ROT13 to scramble the contents of the editor
 */
private void scramble(InputConnection con) {
	char[] buffer = null;
	CharSequence selected = con.getSelectedText(0);
	if (selected != null) {
		buffer = selected.toString().toCharArray();
	}
	else {
		ExtractedText txt = con.getExtractedText(new ExtractedTextRequest(), 0);
		if (txt == null) {
			return;
		}
		buffer = txt.text.toString().toCharArray();
		if (buffer.length == 0)
			return;
	}
	// char[] buffer = con.getSelectedText(0).toString().toCharArray();
	// //con.getExtractedText(new
	// ExtractedTextRequest(),0).text.toString().toCharArray();
	for (int i = 0; i < buffer.length; i++) {
		if (buffer[i] >= 'a' && buffer[i] <= 'm')
			buffer[i] += 13;
		else if (buffer[i] >= 'A' && buffer[i] <= 'M')
			buffer[i] += 13;
		else if (buffer[i] >= 'n' && buffer[i] <= 'z')
			buffer[i] -= 13;
		else if (buffer[i] >= 'N' && buffer[i] <= 'Z')
			buffer[i] -= 13;
	}
	if (selected == null) {
		con.setComposingRegion(0, buffer.length);
	}
	con.setComposingText(new String(buffer), 1);
	con.finishComposingText();
}
 
Example #19
Source File: KCommands.java    From kboard with GNU General Public License v3.0 5 votes vote down vote up
private int getCursorPosition() {
    ExtractedText extracted = inputConnection.getExtractedText(
            new ExtractedTextRequest(), 0);
    if (extracted == null) {
        return -1;
    }
    return extracted.startOffset + extracted.selectionStart;
}
 
Example #20
Source File: EditableInputConnection.java    From JotaTextEditor with Apache License 2.0 5 votes vote down vote up
public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) {
    if (mTextView != null) {
        ExtractedText et = new ExtractedText();
        if (mTextView.extractText(request, et)) {
            if ((flags&GET_EXTRACTED_TEXT_MONITOR) != 0) {
                mTextView.setExtracting(request);
            }
            return et;
        }
    }
    return null;
}
 
Example #21
Source File: CodenameOneInputConnection.java    From CodenameOne with GNU General Public License v2.0 5 votes vote down vote up
private void updateExtractedText() {

        if (request != null) {
            InputMethodManager manager = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
            ExtractedText et = new ExtractedText();
            extractText(request, et);
            manager.updateExtractedText(view, request.token, et);
        }

    }
 
Example #22
Source File: CodenameOneInputConnection.java    From CodenameOne with GNU General Public License v2.0 5 votes vote down vote up
@Override
public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) {
    if (Display.isInitialized() && Display.getInstance().getCurrent() != null) {
        this.request = request;
        ExtractedText et = new ExtractedText();
        if (extractText(request, et)) {
            return et;
        }
    }
    return null;
}
 
Example #23
Source File: CodenameOneInputConnection.java    From CodenameOne with GNU General Public License v2.0 5 votes vote down vote up
boolean extractTextInternal(ExtractedTextRequest request, ExtractedText outText) {

        Component txtCmp = Display.getInstance().getCurrent().getFocused();
        if (txtCmp != null && txtCmp instanceof TextField) {
            String txt = ((TextField) txtCmp).getText();
            int partialStartOffset = -1;
            int partialEndOffset = -1;
            final CharSequence content = txt;
            if (content != null) {
                final int N = content.length();
                outText.partialStartOffset = outText.partialEndOffset = -1;
                partialStartOffset = 0;
                partialEndOffset = N;

                if ((request.flags & InputConnection.GET_TEXT_WITH_STYLES) != 0) {
                    outText.text = content.subSequence(partialStartOffset,
                            partialEndOffset);
                } else {
                    outText.text = TextUtils.substring(content, partialStartOffset,
                            partialEndOffset);
                }

                outText.flags = 0;
                outText.flags |= ExtractedText.FLAG_SINGLE_LINE;
                outText.startOffset = 0;
                outText.selectionStart = Selection.getSelectionStart(content);
                outText.selectionEnd = Selection.getSelectionEnd(content);
                return true;
            }

        }
        return false;
    }
 
Example #24
Source File: RichInputConnection.java    From Indic-Keyboard with Apache License 2.0 5 votes vote down vote up
private void checkConsistencyForDebug() {
    final ExtractedTextRequest r = new ExtractedTextRequest();
    r.hintMaxChars = 0;
    r.hintMaxLines = 0;
    r.token = 1;
    r.flags = 0;
    final ExtractedText et = mIC.getExtractedText(r, 0);
    final CharSequence beforeCursor = getTextBeforeCursor(Constants.EDITOR_CONTENTS_CACHE_SIZE,
            0);
    final StringBuilder internal = new StringBuilder(mCommittedTextBeforeComposingText)
            .append(mComposingText);
    if (null == et || null == beforeCursor) return;
    final int actualLength = Math.min(beforeCursor.length(), internal.length());
    if (internal.length() > actualLength) {
        internal.delete(0, internal.length() - actualLength);
    }
    final String reference = (beforeCursor.length() <= actualLength) ? beforeCursor.toString()
            : beforeCursor.subSequence(beforeCursor.length() - actualLength,
                    beforeCursor.length()).toString();
    if (et.selectionStart != mExpectedSelStart
            || !(reference.equals(internal.toString()))) {
        final String context = "Expected selection start = " + mExpectedSelStart
                + "\nActual selection start = " + et.selectionStart
                + "\nExpected text = " + internal.length() + " " + internal
                + "\nActual text = " + reference.length() + " " + reference;
        ((LatinIME)mParent).debugDumpStateAndCrashWithException(context);
    } else {
        Log.e(TAG, DebugLogUtils.getStackTrace(2));
        Log.e(TAG, "Exp <> Actual : " + mExpectedSelStart + " <> " + et.selectionStart);
    }
}
 
Example #25
Source File: TokenCompleteTextView.java    From TokenAutoComplete with Apache License 2.0 5 votes vote down vote up
@Override
public boolean extractText(@NonNull ExtractedTextRequest request, @NonNull ExtractedText outText) {
    try {
        return super.extractText(request, outText);
    } catch (IndexOutOfBoundsException ex) {
        Log.d(TAG, "extractText hit IndexOutOfBoundsException. This may be normal.", ex);
        return false;
    }
}
 
Example #26
Source File: AdapterInputConnection.java    From android-chromium with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/**
 * @see BaseInputConnection#getExtractedText(android.view.inputmethod.ExtractedTextRequest,
 *                                           int)
 */
@Override
public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) {
    if (DEBUG) Log.w(TAG, "getExtractedText");
    ExtractedText et = new ExtractedText();
    Editable editable = getEditable();
    et.text = editable.toString();
    et.partialEndOffset = editable.length();
    et.selectionStart = Selection.getSelectionStart(editable);
    et.selectionEnd = Selection.getSelectionEnd(editable);
    et.flags = mSingleLine ? ExtractedText.FLAG_SINGLE_LINE : 0;
    return et;
}
 
Example #27
Source File: AdapterInputConnection.java    From android-chromium with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/**
 * @see BaseInputConnection#getExtractedText(android.view.inputmethod.ExtractedTextRequest,
 *                                           int)
 */
@Override
public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) {
    if (DEBUG) Log.w(TAG, "getExtractedText");
    ExtractedText et = new ExtractedText();
    Editable editable = getEditable();
    et.text = editable.toString();
    et.partialEndOffset = editable.length();
    et.selectionStart = Selection.getSelectionStart(editable);
    et.selectionEnd = Selection.getSelectionEnd(editable);
    et.flags = mSingleLine ? ExtractedText.FLAG_SINGLE_LINE : 0;
    return et;
}
 
Example #28
Source File: CtrlInputAction.java    From remotekeyboard with Apache License 2.0 5 votes vote down vote up
/**
 * Place the cursor on the next occurance of a symbol
 * 
 * @param con
 *          driver
 * @param symbol
 *          the symbol to jump to
 */
private void jumpForward(InputConnection con, int symbol) {
	ExtractedText txt = con.getExtractedText(new ExtractedTextRequest(), 0);
	if (txt != null) {
		int pos = txt.text.toString().indexOf(symbol, txt.selectionEnd + 1);
		if (pos == -1) {
			pos = txt.text.length();
		}
		con.setSelection(pos, pos);
	}
}
 
Example #29
Source File: CtrlInputAction.java    From remotekeyboard with Apache License 2.0 5 votes vote down vote up
/**
 * Place the cursor on the last occusrance of a symbol
 * 
 * @param con
 *          driver
 * @param symbol
 *          the symbol to jump to
 */
private void jumpBackward(InputConnection con, int symbol) {
	ExtractedText txt = con.getExtractedText(new ExtractedTextRequest(), 0);
	if (txt != null) {
		int pos = txt.text.toString().lastIndexOf(symbol, txt.selectionEnd - 2);
		pos++;

		con.setSelection(pos, pos);
	}

}
 
Example #30
Source File: ExtractEditText.java    From android_9.0.0_r45 with Apache License 2.0 5 votes vote down vote up
/**
 * Implement just to keep track of when we are setting text from the
 * client (vs. seeing changes in ourself from the user).
 */
@Override public void setExtractedText(ExtractedText text) {
    try {
        mSettingExtractedText++;
        super.setExtractedText(text);
    } finally {
        mSettingExtractedText--;
    }
}