Not able to track crash in the project, I got this error in play store pre-launch section, it showing on click of EditText
, it got the error. but not getting any crash on a real device.
Issue: java.lang.IndexOutOfBoundsException: setSpan (4 ... 4) ends beyond length 0
Fatal Exception: java.lang.IndexOutOfBoundsException: setSpan (4 ... 4) ends beyond length 0
at android.text.SpannableStringBuilder.checkRange(SpannableStringBuilder.java:1096)
at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:671)
at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:664)
at android.text.Selection.setSelection(Selection.java:76)
at android.text.Selection.setSelection(Selection.java:87)
at android.widget.EditText.setSelection(EditText.java:98)
at android.widget.EditText.performAccessibilityActionInternal(EditText.java:138)
at android.view.View.performAccessibilityAction(View.java:8892)
at android.view.AccessibilityInteractionController.performAccessibilityActionUiThread(AccessibilityInteractionController.java:668)
at android.view.AccessibilityInteractionController.-wrap6(AccessibilityInteractionController.java)
at android.view.AccessibilityInteractionController$PrivateHandler.handleMessage(AccessibilityInteractionController.java:1194)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5459)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
Open Play Console. Select an app. On the left menu, select Quality > Android vitals > Crashes and ANRs. Near the center of your screen, use the filters to help you find and diagnose issues.
A pre-launch report is automatically generated when you publish an app to internal, closed, or open testing. It helps to identify issues proactively before your app reaches users. It includes tests for: Stability issues. Android compatibility issues.
I was seeing his same error, both in the pre-launch report and in FireBase test lab. I spent several hours looking into this and I am sure it is a bug that only affects SDK <= 23 and is triggered by AccessibilityNodeInfo#performAction(ACTION_SET_TEXT). It seems this method completely ignores the maxLength attribute which in turn causes the IndexOutOfBoundsException.
You can duplicate this same exception with the following code, making sure the string "1234" is longer than your maxLength:
Bundle arguments = new Bundle();
arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, "1234");
mEditText.performAccessibilityAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments);
So, what to do about it?
One option is to just ignore it as it is likely to affect a very small subset of users. that is unless you think you might have many users using accessibility functions to enter text and they are also using older SDKs (<= 23).
Another option would be to set your minSDKVersion in your build.gradle to 24. This might hurt if you have a lot of users using SDK <= 23
A third option would be to use this very ugly workaround I came up with:
if(Build.VERSION.SDK_INT <= 23){
ViewGroup rootView = findViewById(R.id.your_layout_that_contains_edittexts);
ArrayList<View> views = rootView.getTouchables();
for(View view : views){
if(view instanceof EditText){
EditText mEditText = (EditText)view;
mEditText.setAccessibilityDelegate(new View.AccessibilityDelegate() {
@Override
public boolean performAccessibilityAction(View host, int action, Bundle arguments) {
if (action == AccessibilityNodeInfo.ACTION_SET_TEXT) {
//do something here to make sure index out of bounds does not occur
int maxLength = 0;
for(InputFilter filter : mEditText.getFilters()){
if(filter instanceof InputFilter.LengthFilter) {
maxLength = ((InputFilter.LengthFilter)filter).getMax();
}
}
Set<String> keys = arguments.keySet();
for(String key : keys){
if(arguments.get(key) instanceof CharSequence){
if(arguments.get(key) != null) {
arguments.putCharSequence(key, ((CharSequence) arguments.get(key)).subSequence(0, maxLength));
mEditText.setText(arguments.getCharSequence(key));
}
}
}
}
return true;
}
});
}
}
}
OK, so I did say it was ugly, but it does work. Replace your_layout_that_contains_edittexts with the id of a layout that contains all your EditTexts.
Basically, if SDK <= 23, it cycles through all the EditTexts in the ViewGroup and for each one, overrides the performAccessibilityAction via AccessibilityDelegate and ensures that the text being entered never exceeds the EditText's maxLength value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With