I need to get the current language selected in the Android device. When I use below code:
Log.v("Language: ", Locale.getDefault().getDisplayLanguage());
Log.v("Language: ", getResources().getConfiguration().locale.getDisplayLanguage());
The output is always same:
V/Language:: English
Below picture from android emulator selected language:
When I change the language of emulator, I can get the logs in the picture on the Android console.(But getDisplayLanguage() function returning English)
String locale = context.getResources().getConfiguration().locale.getDisplayName();
String locale = java.util.Locale.getDefault().getDisplayName();
They are different. The first can change if the user switches the Locale.
The second is the one that is pre-installed on the phone. It never changes no matter what the user does.
Happy Coding :)
Related
I have a function to rewrite and pick app language based on system language while you install an app. This function is working as expected if you build your app from Android Studio (even release build). Also, I can confirm it is working from Play Store on all Androids except Android 10, 11 and 12.
It looks like I will correctly pick locale according to my logs and I will rewrite resource config, but after activity restart, it will jump to English as default no matter what system language is currently set (even if default locale in code is correct - in my case Czech (lang code "cs").
As I said, it is caused by the Google Play version of APK, not from Android Studio one.
Is there any undocumented change by Google Play Terms of Service, that they are blocking resource config to be read-only if uploaded on Play Store since Android 10?
Here is function:
fun applyLanguage() {
val defaultLocale = startupLocale
val langs = App.languages
val langCode = app.languageIndex.let {
if (it == 0) {
if(langs.any{ l -> l.first==defaultLocale.language }) {
defaultLocale.language
}else {
langs[App.LANGUAGE_INIT_DEFAULT].first
}
} else {
langs[it - 1].first
}
}
App.log("LangChange: MainActivity -> applyLanguage (langCodeSet) $langCode")
app.sysLog("LangChange: MainActivity -> applyLanguage (langCodeSet) $langCode")
if (resources.configuration.locale.language != langCode) {
val l = if (langCode == defaultLocale.language) {
defaultLocale
} else
Locale(langCode, "", "")
arrayOf(resources, app.resources).forEach { res ->
val cfg = res.configuration
cfg.locale = l
res.updateConfiguration(cfg, res.displayMetrics)
}
Locale.setDefault(l)
}
app.langCode = if (langs.any { it.first == langCode }) langCode else "cs"
App.log("LangChange: MainActivity -> applyLanguage (langCode) ${app.langCode}")
app.sysLog("LangChange: MainActivity -> applyLanguage (langCode) ${app.langCode}")
}
Its simple function, I have an array of available languages (in my case it's 3 of them based on available resources - translates) and if the default system language is one of them I will set the app in that language, if it's not I will set Czech as default. So if I pick English, I should have the app in English, if I pick German, I should have the app in German, if I pick Czech, I should have the app in Czech and if I pick any other language (for example French) it should be set to Czech as a fallback is there.
Also, the same function is used for language picker in App settings and it's the same issue. Default locale has langCode "cs" but if I pick any of those languages from the picker, it will always set resources to default state (string.xml file) which is of course English.
Another example, I setup default language as French in device settings. I downloaded an app from store and it correctly rewrites resources locale to Czech (language code "cs"). But app was still in English.
So, resources.configuration.locale.language was "cs" after activity restart, but this resource config was completely ignored by the system and system picked default resource xml - string.xml which is English.
So it looks like you cant rewrite the resources config anymore, or technically you can, but this altered resource config is completely ignored by the system.
UPDATE
Additional debugging.
Android 10: Default language (French): App was installed and default language was set to English(suppose to be Czech).
If you change language in settings, no matter what language you pick, it will always be set to English.
Android 11: Default language (French): App was installed and default language was set to Czech(correct).
If you change your language in settings it gets interesting:
If you change to English, app switches to English. If you change back to Czech, app switches to Czech. If you change to German, app switches to English (I dont know whats going on).
Android 12: Default language (French): App was installed and default language was set to English(suppose to be Czech).
If you change to English, app switches to English. If you change back to Czech, app switches to English. If you change to German, app switches to German.
Android 9, 8, 7, 6 (and probably lower) - working as intended.
I'm not sure whats going on but its kinda funny.
According to your description above, I got that your issue only happened in the Google Play app version.
I had faced a similar issue, all I did is adding this setting:
bundle {
language {
enableSplit = false
}
}
build.gradle(.app) within android tag
To expand Eng. OsamaYousef answer.
In Short you have to disallow bundle to remove "not needed" languages when user downloads your application.
bundle {
language {
enableSplit = false
}
}
Explanation:
The reason your language picker is working with android studio and not with play store version is because through android studio you install .apk and play store installs .aab (bundle). To test what user gets by downloading your app through play store simply go to android studio -> Run -> Edit configurations... -> Under installation Options search for Deploy and select APK from app bundle.
In addition, I would also recommend following Android guide to implement latest recommendations.
I develop an Android app. If I call
float.Parse("51.552058")
in Editor or App on my Mac Book (Language Setting English), it works fine. After publishing to Android (Language Setting German) the result of the Parse operation is not "51.552058" anymore but "5,155211E+09". I understand that this might be related to the device's language but I still don't really understand what is happening and why.
I also tried following with no success:
float.Parse("51.552058", System.Globalization.NumberStyles.Any)
float.Parse("51.552058", System.Globalization.NumberStyles.AllowDecimalPoint)
Did anyone stumble over this before?
float.Parse is culture dependent.
See e.g. from NumberFormatInfo
// '1,034,562.91' --> 1034562.91 (en-US)
// '1,034,562.91': FormatException (fr-FR)
// '1,034,562.91' --> 1034562.91 (Invariant)
Reason here is that in EU cultures the , is usually the decimal separator while the . is used as the group separator. So from the example above the correct format for fr-FR would be 1.034.562,91
You probably rather want to use CultureInfo.InvariantCulture like
float.Parse("51.552058", CultureInfo.InvariantCulture);
or directly NumberFormatInfo.InvariantInfo
float.Parse("51.552058", NumberFormatInfo.InvariantInfo);
which simply has defined
NumberDecimalSeparator .
NumberGroupSeparator ,
I want to try speech Gujarati language for my application. I've tried this locale code for the Gujarati language:
result = tts.setLanguage(Locale("gu-IN"))
result = tts.setLanguage(Locale("gu"))
result = tts?.setLanguage(Locale("gu-IND"))!!
I've tried these locale codes for the Gujarati Language .. but none of them work.
The code gu-IN is correct you can confirm by here.
If it's not working in your program then you can try this code to confirm if the language is in the list or not.
If it's available then you need to re-check your code. You can also share your code for help.
I want to display flag of US and UK. On some devices flag shows up perfectly but on some text is shown as "US" and "UK" instead of flags. I have used unicode value as 🇺🇸 and have also used below code but neither worked on device Samsung S4. Please help.
int flagOffset = 0x1F1E6;
int asciiOffset = 0x41;
String country = language;
int firstChar = Character.codePointAt(country, 0) - asciiOffset + flagOffset;
int secondChar = Character.codePointAt(country, 1) - asciiOffset + flagOffset;
String flag = new String(Character.toChars(firstChar))
+ new String(Character.toChars(secondChar));
pFlagText.setText(flag);
Maybe the unicode version supported on Samsung S4 is older than the one that the flags were added.
The flag for the United States of America (USA), which may show as the letters US on some platforms.
Source: emojipedia
Possible solution
I'd recommend to just use drawables for the flags.
UK flag svg image (from wikipedia)
US flag svg image (from wikipedia)
Then you can use a converter from SVG to android drawable, like this one [inloop.github.io]
Use a Toast or the log console to see what you get on S4 as the variable's value which is responsible for the flag and the names. Maybe there is a mismatch between this value and the flags' icon names. In this case you have to use conditional load of the image name based on the device.
I am aware of this question asked before about the WebView being broken in Android N especially with localization. I have another problem which I cannot figure out how to fix.
As shown in pic, I have two languages set on my Pixel device running 7.1.1. Now, I'm trying to load the following url in a WebView in my app.
"https://accounts.google.com/ServiceLogin?<my-params>"
What I notice is that the page loads in Chinese instead of English which is my current Locale language. I tried opening the above link on my Chrome desktop (where I am signed in with the same account as my phone) and it loads in Chinese too! I went to Chrome's settings to find that they language preferences are saved to my account because they show up in too.
I did try setting locale before setContentView() in my app like this:
public static void setLocale(Locale locale){
Locale.setDefault(locale);
Configuration config = new Configuration();
config.setLocale(locale);
Context context = MyApplication.getInstance();
context.getResources().updateConfiguration(config,
context.getResources().getDisplayMetrics());
}
but in vain. If I put a log statement, it prints the correct Locale which is en-US. The WebView still loads the page in Chinese though. Any thoughts on how can I fix it?
The issue is affected by the webview in the Android N.
On the first launching of the webview, it resets the locale to default.
If you then rotate the phone - the locale gets correctly set back to the custom locale.
If you then launch the webview again - the locale stays correct.
To fix this, you have to switch back to your chosen language after the page was loaded.
You may also check on the Activity/Fragment life cycle when to switch language.
Sources:
https://issuetracker.google.com/issues/37113860
https://gist.github.com/amake/0ac7724681ac1c178c6f95a5b09f03ce#new-locales-vs-old-locales-chinese
Activity is blinking after locale change in Android 4.1+