my app uses the following code to get the local currency:
Locale locale = Locale.getDefault()
java.util.Currency localCurrency = java.util.Currency.getInstance(locale);
This workes fine in all my tests and was never a problem before. Today I saw a CrashLog in the Google Play Developer Console: The app crashes with:
java.lang.IllegalArgumentException: Unsupported ISO 3166 country: es
I can easy reproduce this error when using new Locale("es")
instead of Locale.getDefault()
:
Locale locale = new Locale("es");
java.util.Currency localCurrency = java.util.Currency.getInstance(locale);
Actually the same exception is thrown no matter was language code I use, e.g. "en", "de", "fr", etc. Only when also the country code is specified everthing workes fine, e.g. new Locale("es", "ES")
I have two problems with Exception:
1. Why is "es" not a valid locale? As fas as I understand Locale names are formed by a language code (lowercase), and an optional country code. Thus es-ES
would be a valid locale but "es" should be as well, shouldn't it?
2. What can I do to avoid this problem? I use Locale.getDefault()
all over the app to give the user locale currency, locale numberformat, etc. I would assume that the system always returns a valid Locale but this is obviously not the case. How can I make sure, that a valid locale is used?
I have also had this issue and I feel the current answer is incomplete. This issue pops up when you run on Firebase virtual machines (you can do it as well on your emulator by selecting the respective language locales i.e. en, de,es, etc.).
I resolved this by creating a custom class which does the retrieval of the currency accounting for failure using a try:
public static Locale getLocalCurrency() {
try {
return Currency.getInstance(Locale.getDefault());
} catch (NullPointerException | IllegalArgumentException ex) {
return Currency.getInstance(new Locale("en", "US"));
}
}
This basically assumes that if it fails it will return the locale for the US. This could easily be extended to detect the language, i.e. es, and return the relevant default.
I have extended this to all points where I use Locale for safety.
Hope that helps anyone else who looks here.
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