9

I am getting some JSON data with a formatted string of currency like this

₽35

However, i noticed that on a Nexus 5 (Lollipop) it displays it correctly but other phones such as the HTC one mini and Samsung GT-I9505, it displays a blank character.

I attempted to research the issue, i could not find a solution other than, in the XML layout file, ensure that this line is present

<?xml version="1.0" encoding="utf-8"?>

But i still have the same issue

Please help

Edit 15 May 2015

Loading custom font NotoSans (Please note I know this would leak memory but its just a quick test)

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView ruble = (TextView)findViewById(R.id.ruble);
        Typeface myFont = Typeface.createFromAsset(getAssets(),"fonts/NotoSans-Regular.ttf");
        ruble.setTypeface(myFont);
    }

The Russian Ruble symbol defined in strings.xml (note I tried all)

     <string name="rubleSymbolJava">\u20BD</string>
  <string name="rubleSymbolHTML">&#8381;</string>
    <string name="rubleSymbolHTMLHex">&#x20bd;</string>

Same problem, on older phones shown as a square but works on Android 5.0 BUT nothing older.

SOLVED Please see my answer

Ersen Osman
  • 7,067
  • 8
  • 47
  • 80
  • 2
    The copy/paste you did into the question would seem to have messed up your currency symbol. Leastways, it it is not showing up as [the Russian ruble sign](http://unicode-table.com/en/20BD/). It is possible that the font being used on those devices lacks this Unicode glyph. – CommonsWare May 14 '15 at 14:35
  • @DerGolem I am using the default font. No custom. It is just a standard button. – Ersen Osman May 14 '15 at 14:44
  • @DerGolem I just did a test. I used a custom font Roboto-Light.ttf which does not have that glyph but yet it displays fine on Nexus 5 only – Ersen Osman May 14 '15 at 14:51
  • @DerGolem, I will try a font which has it – Ersen Osman May 14 '15 at 14:53
  • @CommonsWare. I just tried Helvetica which according to the link given by CommonsWare supports it. It now displays a blank square – Ersen Osman May 14 '15 at 15:20
  • @DerGolem I just tried Helvetica which according to the link given by CommonsWare supports it. It now displays a blank square – Ersen Osman May 14 '15 at 15:20
  • Then perhaps there is an issue in your JSON parsing. Confirm that the character is actually in the value you are passing to the button on the devices that are not displaying it. – CommonsWare May 14 '15 at 15:32
  • @CommonsWare, it comes up on log cat on all devices. I am parsing it as a string – Ersen Osman May 14 '15 at 15:35

5 Answers5

12

I fixed this. I just used the new Google Roboto Font which was last updated Jan 2015 and has the Ruble symbol.

https://www.google.com/fonts/specimen/Roboto#pairings

Research showed that in 2014 Russia changed their currency symbol so old fonts did not have the new Glyph so for others who have a similar issue, see if your font has been updated

Ersen Osman
  • 7,067
  • 8
  • 47
  • 80
6

The problem-phone's default font might be missing the Russian ruble glyph. Try to hard-code it into a TextView somewhere in your app to make sure that that is indeed the issue rather than some other JSON parsing mistake or so (seems less likely as it works on some phones).

In case the missing glyph is your problem, it's fairly simple to include your own font in your project. That way you can be sure that you can support all glyphs that you need.

Here are the steps to do so programmatically:

I haven't used the graphical designer much, but I'm sure it's not any more difficult there either. Also, these instructions are for the Android Eclipse plugin. While the code will likely be identical in Android Studio, I'm not sure that the folder structure is the same. The docs say something about placing the assets in main/assets instead of just assets, for example...

A couple of things to consider:

  • Make sure that your distribution of the font you choose doesn't violate any licenses of that font.
  • Your app will now no longer use the device's default font, which will mean that your app will look more similar and predictable across devices, but it might stand out from other apps on specific devices that might use very different default fonts.
  • The size of the .ttf file will add to the size of your app. Most fonts are fairly small (~100KB), but some do get large (several MB), especially if they support many different languages, which might then become an issue.
  • Make sure your font supports all glyphs in all languages that your project needs.

An added bonus: You can add some of your own custom glyphs into the font to easily include simple single-colored vector graphics into your app just by putting the corresponding "letter" into a TextView (remember Wingdings?).

Community
  • 1
  • 1
Markus A.
  • 12,349
  • 8
  • 52
  • 116
  • Thanks for the reply. Do you recommend any particular fonts? So far I tried Helvetica and Ariel. This time, a square is displayed rather than nothing. – Ersen Osman May 14 '15 at 19:37
  • Helvetica and Ariel (if you are talking about the ones being shipped with Windows) might not be a good choice for licensing reasons. I haven't looked into the issue directly, but I doubt that Microsoft would be too happy if you started shipping their fonts with your app. [Google Fonts](http://www.google.com/fonts) has a couple of alternatives, some of which have good support for different languages. Again, you need to check the licenses. I don't know if all of them are OK to just use. To check the included glyphs, you can install the TTF on your system and use the Windows character map. – Markus A. May 14 '15 at 20:31
  • Thanks for the warning but I would like to ignore the licensing issues for now to prove if its the font or a backend issue – Ersen Osman May 14 '15 at 21:09
  • @johncarter Google has a project called ["Noto Fonts"](https://www.google.com/get/noto/) that aim to support as many languages as possible. [Noto Sans](https://www.google.com/get/noto/#/family/noto-sans), for example, supports Russian and probably has the Ruble glyph also. But I would just go and place a TextView into your app that has a Ruble sign in it. If that displays correctly, your problem is elsewhere. And if not, your font is definitely also a problem (albeit maybe not the only one). But given that your code works on the Nexus 5, my first guess would be the font issue. – Markus A. May 15 '15 at 03:16
  • Can you check my edit? I still have the same problem, except that its shown as a square. Works on Android 5.0 but not older. Also this time I am hardcoding the string (no longer from backend) still same issue. Please help – Ersen Osman May 15 '15 at 05:53
  • @johncarter If you double-click the ttf-file in Windows, it will open a preview and at the top you will find a button called "Install". Click that and wait until it's done. Then, open the Windows "Character Map". Select your font up top and click and hold the mouse-button on one of the characters. You can now drag the mouse around and quickly scan through the characters. Bottom left, it shows the unicode value of the character you are hovering over (e.g. U+0321). Check if the font you chose has U+20BD (the Ruble sign). For some reason, Noto does NOT. You need to keep looking for one that does. – Markus A. May 15 '15 at 06:39
  • Thanks. Yeah it does not have it. But this is so weird, if the font does not have it then it should not display on the Android 5.0 device but it does so anyway – Ersen Osman May 15 '15 at 06:44
  • @johncarter On my machine (Win-7 64bit) Microsoft's Arial has the Ruble glyph and so does Times New Roman (you can find their ttf-files under C:\Windows\Fonts). Courier New does not, though. BTW: Maybe it's easier and more reliable to just use [ISO 4217 currency codes](http://en.wikipedia.org/wiki/ISO_4217), i.e. RUB and USD, instead of their symbols... – Markus A. May 15 '15 at 06:44
  • 1
    @johncarter The Nexus 5 might be using a different font or a more complete version of the same font. Also, different devices (and software) handle missing glyphs differently. Some draw nothing (Chrome, for example), others an empty rectangle, others a rectangle with the hex-code of the missing glyph (Firefox). Maybe the Nexus just uses a Glyph from its default font instead... – Markus A. May 15 '15 at 06:48
  • I just tried Arial, it works and displays so it was a font issue. I guess I will use the ISO 4217 currency codes like you said to avoid licencing issues with the fonts – Ersen Osman May 15 '15 at 06:57
2

I found solution in that answer https://stackoverflow.com/a/36338231/1078641 , added &amp;subset=all parameter to Roboto font link.

The original link to Roboto font was like that

<link href='https://fonts.googleapis.com/css?family=Roboto:400,300italic,300,400italic,500,500italic,700,700italic' rel='stylesheet' type='text/css'>

After I added &amp;subset=all parameter to the link I can successfully see ruble symbol on my Android device

<link href='https://fonts.googleapis.com/css?family=Roboto:400,300italic,300,400italic,500,500italic,700,700italic&amp;subset=all' rel='stylesheet' type='text/css'>
Community
  • 1
  • 1
electroid
  • 603
  • 8
  • 20
1

You can also check Android version. I think, some phones on API 19 support russian rubles, but on API 21 they all support it. It would be easier to add string resources instead of check and replace programmatically.

After reading Trying to use <!ENTITY in ANDROID resources with error: "The entity was referenced, but not declared." I made a new file strings.xml in res/values-v21.

So, in values/strings.xml:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE resources [
    <!ENTITY rouble "р.">
    ]>
<resources>
    <string name="saaki">Галстук Сааки - %1$s &rouble;</string>
</resources>

In values-v21/strings.xml:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE resources [
    <!ENTITY rouble "₽">
    ]>
<resources>
    <string name="saaki">Галстук Сааки - %1$s &rouble;</string>
</resources>
CoolMind
  • 26,736
  • 15
  • 188
  • 224
0

You can check if the glyph is present using the code from https://stackoverflow.com/a/29938454/755804

If it's not present, you will need to either provide an image and use TextViewWithImages or replace it with a character sequence.

Community
  • 1
  • 1
18446744073709551615
  • 16,368
  • 4
  • 94
  • 127