How can i get locale info in Unity C#? - c#

I am developing a project with Unity 2019.2b, it is expected to work at all platforms (android, ios, windows, macos) , i am trying to get device locale info(e.g. en-us, en-au, en-bz) but all i can find is Application.systemLanguage definition. Even i decide to use this information i will still need region info. Are there any sample or way to get locale info in Unity or to get device region info? (If the solution for only region info; I dont want to use device location or dont want to use user ip address, i want to get it from settings)
I tried to get locale or at least device region info with RegionInfo,CultureInfo,System.Threading.Thread.CurrentThread.CurrentUICulture and System.Threading.Thread.CurrentThread.CurrentCulture definitions, but it didn't work.
string regionName = System.Globalization.RegionInfo.CurrentRegion.Name;
string cultureName = System.Globalization.CultureInfo.CurrentCulture.Name;
string cname = System.Threading.Thread.CurrentThread.CurrentCulture.Name;
string uiname = System.Threading.Thread.CurrentThread.CurrentUICulture.Name;
Depending on the platform (ios, android, windows,macos) sometimes the result comes as InvariantCulture, sometimes always en-US even device locale is not en-US.

The issue is coming from Mono, used by Unity.
I found a few solutions in this forum thread.
If you are working with Windows a workaround might be using PInvoke:
[System.Runtime.InteropServices.DllImport("KERNEL32.DLL")]
private static extern int GetSystemDefaultLCID();
And then check the global culture like so:
var currentCulture = new CultureInfo(GetSystemDefaultLCID());
This might be used to set the culture:
Thread.CurrentThread.CurrentCulture = new CultureInfo(GetSystemDefaultLCID());
Thread.CurrentThread.CurrentUICulture = new CultureInfo(GetSystemDefaultLCID());

Related

Windows Forms Localize resx without changing Culture

I know it's easy to localize Windows Forms App: set Localizable=True, change Language and set text in Controls for every Language. This information saves in resx-files and application will automatically select the required file. Great!
I know about disadvantages of this solution (you need to rebuild the app if there a typo, it's impossible to change language in runtime, etc), but it's not a problem for me and "resources" is the simpliest, built-in solution.
But this mechanism uses the property Culture of app's thread.
My app is the part ("plugin") of the bigger application and works in the same Thread.
The main application is multilingual too, but it doesn't use Culture to change interface's language. I can change the thread's culture globally, but it crushes the main app's interface.
So my question:
is it possible to manually set the resx-localizable resurce file that will be used? Not based on Culture, but, for example, on some variable in my app:
if (this.Language == "fr")
this.Resources.Add("Form1.fr.resx");
else
this.Resources.Add("Form1.en.resx");
Or something else.
Thank you!
My sandbox:
https://github.com/Tereami/WindowsFormsTestLanguage
The built resources file has a property ResourceManager that's used to return the desired content. This has an overload with a CultureInfo parameter. You can use it to request resources in individual languages:
var desiredCulture = new CultureInfo("en-us");
var text = MyStrings.ResourceManager.GetString(nameof(Resources.ExitMessage), desiredCulture);
If you want to set the culture globally for your resource file, you could also set it through the corresponding property:
var desiredCulture = new CultureInfo("en-us");
MyStrings.Culture = desiredCulture;
var text = MyStrings.ExitMessage;

Why C# CultureInfo.CurrentCulture give en_US in Window-7 Japanese culture?

I have window-7 Ultimate OS.I written below code for get current culture info.
void TestMessage()
{
CultureInfo culture = CultureInfo.CurrentCulture;
CultureInfo culture1 = Thread.CurrentThread.CurrentCulture;
}
it is working fine with window-8,server 2012 Japanese OS. But it is not working in window-7 only. Please look below image of my computer region setting
Can any anyone guide me to get correct culture name?
Thanks,
There's CurrentCulture and CurrentUICulture.
CurrentCulture: formatting of data (numbers, dates), it is configured in Windows using the tab visible in your screenshot
CurrentUICulture: the language to speak/write to your user, it is configured in Windows using one of the other tabs showing in your screenshot. ("Keyboard & Languages" I think)
Your screenshot:
... is showing american numeric notation because CurrentCulture is set to en-US
... is talking Japanese because CurrentUICulture is very likely set to Japanese
So, if you need to know what language to use for localization, as is probably your case, you should be using CurrentUICulture.

Why does my localization only work on my Development-Machine?

I've localized my App in two languages (English and German) with the MulitlingualAppToolkit 4.0. English is the base language, while german is a translation based on the english one.
The translations are stored as resw-file inside folder "strings.en" and "strings.de".
In App.xaml.cs App() I set the culture like this:
Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = GetCurrentCulture();
CultureInfo.CurrentUICulture = GetCurrentCulture();
private CultureInfo GetCurrentCulture()
{
var cultureName = new DateTimeFormatter("longdate", new[] {"US"}).ResolvedLanguage;
return new CultureInfo(cultureName);
}
(I got this quiet weird way to the regional-culture in Windows 10 from this article https://www.pedrolamas.com/2015/11/02/cultureinfo-changes-in-uwp/ since I recognized that CultureInfo.CurrentCulture and CultureInfo.CurrentUICulture are always "en-EN" no matter what i configurate in my machines regional- and language-settings)
To check if PrimaryLanguageOverride works as expected, I added a TextBox by the name of tbTest on my first Page and a button linkt to this event:
private void Button_Click(object sender, RoutedEventArgs e)
{
Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = tbTest.Text;
Frame.Navigate(this.GetType(), 0);
System.IO.File.AppendAllText(System.IO.Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "PrimaryLanguageOverride.txt"),
DateTime.Now + " - Actual PrimaryLanguageOverride:\n " + WIndows.Globalization.ApplicationLanguages.PrimaryLanguageOverride);
}
catch(Exception ex) { Helper.Log.LogUnhandledError(ex); }
}
Now comes the weird stuff:
When Debugging, or executing the App from my Development-Machine, everything works as expected, but when I make an appx-bundle and install it on another (Windows10-Desktop) device, the App does not recognize the its Language.
In my situation, the device is set to german, regional as well as its language. Also when using the test-procedure, it defenetively gets the string I set , as long as it's a valid culture-name, e.g.: "en-EN", "en-US", "de-DE", "de", "en" (all of these are working fine on my development machine) if it's an invalid string, I get an exception, with a log-entry in my unhandled-error-log. It refresh the Page, and even writes the new-set language in my PrimaryLanguageOverride-Log, but it doesn't change any text I did translate.
So my question is, is this a common Issue (since I recognized in UWP/Win10 the culture-system is a little messed up) or do I use the wrong procedure to override the App-Culture?
This is an issue with AppXBundling. When Installing bundles, it checks with the current OS for the installed Language packs and copies the relevant language resources from the bundle and omits the other language files. The objective of a single bundle is to copy necessary resources and build the application and therefore the languages which are not in the system are considered irrelevant. As a fix you could stop generating single bundles and create package for each CPU architecture. Check this for more info

Regional format and language in Windows Phone 10 UWP app

I'm working on a localized Windows (Phone) 10 UWP app.
I have implemented support for 2 language: en-US and nl-NL (Dutch-Netherlands). This works fine: When the user has selected English in the phone settings the app starts in English and when the user has selected Dutch in the phone settings the app starts in Dutch.
To get this working I had to make some changes in the package.appxmanifest because my language resources are in a different DLL:
<Resources>
<Resource Language="nl-NL"/>
<Resource Language="en-US"/>
</Resources>
But I cannot find any way to get the regional format from the user for date, time and number formatting.
When the user has selected English as language but Dutch (Netherlands) for regional format, my app starts with both
System.Globalization.CultureInfo.CurrentUICulture and System.Globalization.CultureInfo.CurrentCulture set to "en-US", where System.Globalization.CultureInfo.CurrentCulture should be "nl-NL".
I have been searching all of the documentation but I cannot find a way to retrieve the phone regional format (except Windows.System.UserProfile.GlobalizationPreferences.HomeGeographicRegion which is something different).
Is there a way to retrieve the phone regional format?
I only know the following hack mentioned here
var systemLanguage = GlobalizationPreferences.Languages.First();
var regionInfo = new RegionInfo(systemLanguage);
var dtf = new DateTimeFormatter("longdate", new[] { regionInfo.TwoLetterISORegionName });
var regionInfoName = dtf.ResolvedLanguage;
var regionFormatCultureInfo = new CultureInfo(regionInfoName);
Peter Meinl's answer works, but is a little confusing because you do not need the RegionInfo.
Pedro Lamas describes the hack using the ResolvedLanguage of DateTimeFormatter just using "US".
DateTimeFormatter dtf = new DateTimeFormatter("longdate", new[] { "US" });
string regionInfoName = dtf.ResolvedLanguage;
CultureInfo regionFormatCultureInfo = new CultureInfo(regionInfoName);
The ResolvedLanguage property of the DateTimeFormatter will contain the regional format id of the phone, in this case "nl-NL".
Mind that you DO need a language in the constructor of the DateTimeFormatter, just new DateTimeFormatter("longdate") or DateTimeFormatter.LongDate won't work.

Internationalize Windows Phone 7 App

I am currently working on a windows phone application that takes some information from the user and returns some other information based on the user input.
The application works great if the specific device has its region settings set to US. If the region settings of the device are set to Greek or German, some problems occur. For example, the US decimal point character "." is considered as "," and vice versa. As a result, all the calculations are false.
What I want to do is internationalize the application so that it works exactly the same no matter what the regional settings are. Is this possible?
If you want your app allways to show number and dates in one specify format you can force the app to allways run in one specify culture like this.
You just have to set the current thread of your app to one specify culture (add to the App.cs file)!
public App()
{
// Standard Silverlight initialization
InitializeComponent();
// Phone-specific initialization
InitializePhoneApplication();
// Set the current thread to US!
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");

Categories

Resources