BreakIterator behaving differently in Android API 29 and API 30

159 Views Asked by At

I have made the below function to break String into Hindi Chars. But It behaves differently android API 29 and API 30. In Android 29 Hindi word चक्की is broken into च क् की But in Android 30 it is correctly broken into च क्की.

public List<String> breakIntoHindiChar(String textAnswer) {
    List<String> ansCharList = new ArrayList<String>();
    Locale hindi = new Locale("hi", "IN");
    BreakIterator breaker = BreakIterator.getCharacterInstance(hindi);
    breaker.setText(textAnswer);
    int start = breaker.first();
    for (int end = breaker.next();
         end != BreakIterator.DONE;
         start = end, end = breaker.next()) {

        ansCharList.add(textAnswer.substring(start, end));

    }
    return ansCharList;

}

How can I solve this problem?

2

There are 2 best solutions below

2
On

How can I solve this problem?

As you noted in your question, the behavior in Android 29 is incorrect, and the behavior in Android 30 is correct.

So it depends on what you think the problem is:

  • If you think that it is that they fixed the behavior in Android 30 at that has "broken" your app on later versions, then a solution would be for you to copy the Android 29 BreakIterator into your app (with a different name) and use it.

  • If you think that it is that they didn't fix the behavior in Android 29 (and earlier) and you want your app to behave correctly on older Android, then a solution would be for you to copy the Android 30 BreakIterator into your app (with a different name) and use it.

Note that what you would be doing is to implement either forwards or backwards compatible behavior for BreakIterator, albeit not in the standard class.

(There may be a more elegant solution, but I don't have my own local copy of the Android master repo to dig through the history.)

Note: If you can't replace all of your app's use of BreakIterator with an alternative version of the class, then (AFAIK) there won't be a way to make the behavior consistent. You cannot patch the Android platform. And note that while you could use android.icu.text.BreakIterator instead of android.text.BreakIterator in your own code, that wouldn't fix the problem for other code that your app depends on.


But if you think the problem is that BreakIterator behaves differently in Android 29 vs 30 ... there is no solution to that. It is a fact. Yes ... it does behave differently ... and even Google can't make it not behave differently in Android 30 ... now.

3
On

Android implementation of BreakIterator was not able to interpret Bharatiya scripts (abiguda type) accurately. See this bug - https://code.google.com/p/android/issues/detail?id=230832

Looks like it has been fixed for API 30 and has not been backported for previous versions.