Odd behavior: Class type of the object retuned by the getText() method of TextView changes after creating AccessibilityNodeInfo of TextView
android, android-layout, textview
Solution
It is due to new features like `select`, `cut`, `copy`, `paste` features added to the `AccessibilityNodeInfo`. It was introduced in Android 4.3 and is documented here.
Select text and copy/paste
The AccessibilityNodeInfo now provides APIs that allow an AccessibilityService to select, cut, copy, and paste text in a node.
To specify the selection of text to cut or copy, your accessibility service can use the new action, ACTION_SET_SELECTION, passing with it the selection start and end position with ACTION_ARGUMENT_SELECTION_START_INT and ACTION_ARGUMENT_SELECTION_END_INT. Alternatively you can select text by manipulating the cursor position using the existing action, ACTION_NEXT_AT_MOVEMENT_GRANULARITY (previously only for moving the cursor position), and adding the argument ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN.
You can then cut or copy with ACTION_CUT, ACTION_COPY, then later paste with ACTION_PASTE.
Note: These new APIs are also available for previous versions of Android through the Android Support Library, with the AccessibilityNodeInfoCompat class.
To implement the `select` feature, the `styleable` / `markup` objects need to be attached to the underlying text. Hence the text type is changed from `String` to `SpannableString`.
Here is the code of View.java which introduced this feature. Following code changes the type to `SpannableString`.
@Override
public CharSequence getIterableTextForAccessibility() {
if (!(mText instanceof Spannable)) {
setText(mText, BufferType.SPANNABLE);
}
return mText;
}
Problem
I have a TextView with text "Hello World!" defined in layout xml ``` TextView textView = (TextView)findViewById(R.id.textView); ``` TextView's getText() method returns object of Class java.lang.String ``` //Returns object of String class Toast.makeText(getApplicationContext(), textView.getText().getClass().getName(), Toast.LENGTH_LONG).show(); ``` If the same is called after creating AccessibilityNodeInfo, it returns object of android.text.SpannableString ``` //Creating AccessibilityNodeInfo AccessibilityNodeInfo info = textView.createAccessibilityNodeInfo(); //Returns object of SpannableString Toast.makeText(getApplicationContext(), "After creating AccessibilityNodeInfo: " + textView.getText().getClass().getName(), Toast.LENGTH_LONG).show(); ``` How is creating AccessibilityNodeInfo relevant to the object returned by the getText() method? Note: This only happens in Android 4.3 and above