Thursday, December 22, 2022

How to ensure that Android displays non-ascii unicode characters properly

I was trying to show a button that has an leftwards arrow character as it's text. The leftwards arrow is unicode character u2190. The relevant code snippet is the following:

<Button
    app:layout_row="0"
    app:layout_column="2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="\u2190"
    android:textSize="@dimen/font_size"
    app:layout_columnWeight="1"
    style="?android:attr/buttonBarButtonStyle"
    android:onClick="onKeyPressed"
/>

On most devices I was getting the expected result (left image), while on Nokia 1 API Level 27 (available on Firebase Test Lab) I got something that might be some han glyph (right image).

I have resolved the problem by finding a TTF font with permissive license that had leftwards arrow correctly mapped. I have added it in res/font directory and referenced it from the layout file in the following way:

<Button
    android:fontFamily="@font/custom"
    app:fontFamily="@font/custom"
    app:layout_row="0"
    app:layout_column="2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="\u2190"
    android:textSize="@dimen/font_size"
    app:layout_columnWeight="1"
    style="?android:attr/buttonBarButtonStyle"
    android:onClick="onKeyPressed"
/>

Now the leftwards arrow is displayed properly on testing devices, including the one that previously was showing a different symbol.

Additionally, I used FontForge to subset the font so that it contains only the necessary character.

Also answered on StackOverflow.