Reputation: 4345
Within the scope of an Android application (language used is Java), I want to display a list of countries and their respective currencies. However there are a few oddities:
Here is the piece of code that creates the list I later display:
List<String> countries = new ArrayList<String>();
List<Locale> locales = new ArrayList<Locale>();
// Explicitly check for Locales needed to create currencies
Locale[] locales = NumberFormat.getAvailableLocales();
for (Locale locale : locales) {
if (!locale.getDisplayCountry().isEmpty()) {
String country = locale.getDisplayCountry();
String currencySymbol = CurrencyAmount.getCurrencySymbol(locale);
String formatted = String.format("%s, %s", country, currencySymbol);
Log.i(TAG, formatted);
countries.add(formatted);
locales.add(locale);
}
}
The above code produces the following log statements (excerpt):
01-27 15:50:25.742: I/de.zainodis.SelectCurrency(13281): Deutschland, €
01-27 15:50:25.882: I/de.zainodis.SelectCurrency(13281): Portugal, ¤
01-27 15:50:25.742: I/de.zainodis.SelectCurrency(13281): Schweiz, CHF
01-27 15:50:25.742: I/de.zainodis.SelectCurrency(13281): Luxemburg, ¤
01-27 15:50:25.820: I/de.zainodis.SelectCurrency(13281): Luxemburg, ¤
01-27 15:50:25.906: I/de.zainodis.SelectCurrency(13281): Taiwan, ¤
01-27 15:50:25.914: I/de.zainodis.SelectCurrency(13281): Taiwan, NT$
I slightly modified the above code, to only display entries, where getInstance(locale) does not throws an IllegalArgumentException. That is the case if the locale's country is not a supported ISO 3166 country. The modified code...
List<String> countries = new ArrayList<String>();
List<Locale> locales = new ArrayList<Locale>();
Locale[] locales = NumberFormat.getAvailableLocales();
for (Locale locale : locales) {
if (!locale.getDisplayCountry().isEmpty()) {
String country = locale.getDisplayCountry();
String currencySymbol = CurrencyAmount.getCurrencySymbol(locale);
try {
Currency currency = Currency.getInstance(locale);
String formatted = String.format("%s, %s, %s", country, currencySymbol,
currency.getCurrencyCode());
Log.i(TAG, String.format("%s, %s", country, currencySymbol));
SelectCurrency.countries.add(formatted);
SelectCurrency.locales.add(locale);
} catch (IllegalArgumentException e) {
// Skip these countries
}
}
}
...and the output (excerpt):
01-27 15:55:01.453: I/de.zainodis.SelectCurrency(13725): Deutschland, €, EUR
01-27 15:55:01.632: I/de.zainodis.SelectCurrency(13725): Portugal, ¤, EUR
01-27 15:55:01.453: I/de.zainodis.SelectCurrency(13725): Schweiz, CHF, CHF
01-27 15:55:01.468: I/de.zainodis.SelectCurrency(13725): Luxemburg, ¤, EUR
01-27 15:55:01.578: I/de.zainodis.SelectCurrency(13725): Luxemburg, ¤, EUR
01-27 15:55:01.664: I/de.zainodis.SelectCurrency(13725): Taiwan, NT$, TWD
Since I want to display a list of countries, each with their respective currencies (as a Symbol) what would I do in case of countries such as Portugal or Luxembourg, that have no currency symbol attached? I know I could alternatively show the currency code, however since I'll render amounts with their respective currencies into the UI, I'd rather go for those symbols... I guess I could filter countries out where the currency symbol is "¤" but I wonder: is it guaranteed to be that symbol on each Android device across the world? And what if someone happens to live in Portugal or Luxembourg... ?
This is how it, what it looks like right now:
In this example screenshot, Belgium's entry has no currency symbol (should be the € symbol), however later in the list, there is another Belgium entry (several actually...) which looks like this:
So in case of Belgium, I could simply kick out the one that has "¤" as it's currency symbol, but what about countries such as Portugal, which have no entry with a proper currency symbol?
Upvotes: 2
Views: 2105
Reputation: 6185
Yes, it is a Google issue that has been fixed in Android v.4.3 only. I am using workaround below to fix this issue for devices with pt_PT locale.
if (Locale.getDefault().toString().equals("pt_PT")) {
mCurrencyNumberFormat = NumberFormat.getCurrencyInstance(Locale.getDefault());
DecimalFormatSymbols dfs = ((DecimalFormat)mCurrencyNumberFormat).getDecimalFormatSymbols();
dfs.setCurrencySymbol("\u20AC");
((DecimalFormat)mCurrencyNumberFormat).setDecimalFormatSymbols(dfs);
}
So € symbol now shown instead of buggy ¤ symbol. Enjoy )))
Upvotes: 1
Reputation: 6711
Ther's an issue in google code issue
// http://code.google.com/p/android/issues/detail?id=38622
public void test_getSymbol_38622() throws Exception {
// The CLDR data had the Portuguese symbol for "EUR" in pt, not in pt_PT.
// We weren't falling back from pt_PT to pt, so we didn't find it and would
// default to U+00A4 CURRENCY SIGN (¤) rather than €.
Locale pt_BR = new Locale("pt", "BR");
Locale pt_PT = new Locale("pt", "PT");
assertEquals("R$", Currency.getInstance(pt_BR).getSymbol(pt_BR));
assertEquals("BR$", Currency.getInstance(pt_BR).getSymbol(pt_PT));
assertEquals("€", Currency.getInstance(pt_PT).getSymbol(pt_BR));
assertEquals("€", Currency.getInstance(pt_PT).getSymbol(pt_PT));
}
Upvotes: 1