Fix #13130: Android respects device locale (#19419)

Co-authored-by: Tulio Leao <tupaschoal@gmail.com>
This commit is contained in:
undermark5 2023-04-13 04:30:18 -05:00 committed by GitHub
parent 0a28f6b0b9
commit 78aa02fe8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 126 additions and 3 deletions

View File

@ -9,6 +9,7 @@
- Improved: [#19764] Miscellaneous scenery tab now grouped next to the all-scenery tab.
- Improved: [#19830] “Highlight path issues” will now hide wall elements.
- Fix: [#12598] Number of holes is not set correctly when saving track designs.
- Fix: [#13130] Android always defaulting to UK locale for language, currency and temperature.
- Fix: [#18895] Responding mechanic blocked at level crossing.
- Fix: [#19231] Crash due to null pointer to previously deleted banner in tile copy/paste functionality
- Fix: [#19296] Crash due to a race condition for parallel object loading.

View File

@ -1,15 +1,80 @@
package io.openrct2;
import android.icu.util.Currency;
import android.icu.util.LocaleData;
import android.icu.util.ULocale;
import android.os.Build;
import android.view.View;
import org.libsdl.app.SDLActivity;
import java.util.Locale;
public class GameActivity extends SDLActivity {
public float getDefaultScale() {
return getResources().getDisplayMetrics().density;
}
public String getDefaultLocale(String[] supportedTags) {
Locale deviceLocale;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
deviceLocale = getResources().getConfiguration().getLocales().get(0);
} else {
deviceLocale = getResources().getConfiguration().locale;
}
for (String supportedTag : supportedTags) {
if (supportedTag.isEmpty()) continue;
String[] splits = supportedTag.split("-");
String language = splits[0];
String country = splits[1];
if (deviceLocale.getLanguage().equals(language) && deviceLocale.getCountry().equals(country)) {
return supportedTag;
}
}
Locale canadaEn = Locale.CANADA;
if (canadaEn.getLanguage().equals(deviceLocale.getLanguage()) && canadaEn.getCountry().equals(deviceLocale.getCountry())) {
return "en-US";
}
for (String supportedTag : supportedTags) {
if (supportedTag.isEmpty()) continue;
String[] splits = supportedTag.split("-");
String language = splits[0];
if (deviceLocale.getLanguage().equals(language)) {
return supportedTag;
}
}
return "en-UK";
}
public String getLocaleCurrency() {
Locale deviceLocale;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
deviceLocale = getResources().getConfiguration().getLocales().get(0);
return Currency.getInstance(deviceLocale).getCurrencyCode();
} else {
deviceLocale = getResources().getConfiguration().locale;
return java.util.Currency.getInstance(deviceLocale).getCurrencyCode();
}
}
public boolean isImperialLocaleMeasurementFormat() {
Locale deviceLocale;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
return LocaleData.getMeasurementSystem(ULocale.forLocale(getResources().getConfiguration().getLocales().get(0))) == LocaleData.MeasurementSystem.US;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
deviceLocale = getResources().getConfiguration().getLocales().get(0);
} else {
deviceLocale = getResources().getConfiguration().locale;
}
String localeCountry = deviceLocale.getCountry();
return localeCountry.equals(Locale.US.getCountry()) || localeCountry.equals(new Locale("xx", "LR").getCountry()) || localeCountry.equals(new Locale("xx", "MM").getCountry());
}
@Override
protected String[] getLibraries() {
return new String[]{

View File

@ -74,17 +74,74 @@ namespace Platform
uint16_t GetLocaleLanguage()
{
return LANGUAGE_ENGLISH_UK;
JNIEnv* env = static_cast<JNIEnv*>(SDL_AndroidGetJNIEnv());
jobject activity = static_cast<jobject>(SDL_AndroidGetActivity());
jclass activityClass = env->GetObjectClass(activity);
jmethodID getDefaultLocale = env->GetMethodID(
activityClass, "getDefaultLocale", "([Ljava/lang/String;)Ljava/lang/String;");
jobjectArray jLanguageTags = env->NewObjectArray(
LANGUAGE_COUNT, env->FindClass("java/lang/String"), env->NewStringUTF(""));
for (int32_t i = 1; i < LANGUAGE_COUNT; ++i)
{
jstring jTag = env->NewStringUTF(LanguagesDescriptors[i].locale);
env->SetObjectArrayElement(jLanguageTags, i, jTag);
}
jstring jniString = static_cast<jstring>(env->CallObjectMethod(activity, getDefaultLocale, jLanguageTags));
const char* jniChars = env->GetStringUTFChars(jniString, nullptr);
std::string defaultLocale = jniChars;
env->ReleaseStringUTFChars(jniString, jniChars);
for (int32_t i = 0; i < LANGUAGE_COUNT; ++i)
{
jobject strToFree = env->GetObjectArrayElement(jLanguageTags, i);
env->DeleteLocalRef(strToFree);
}
env->DeleteLocalRef(jLanguageTags);
env->DeleteLocalRef(activity);
env->DeleteLocalRef(activityClass);
return LanguageGetIDFromLocale(defaultLocale.c_str());
}
CurrencyType GetLocaleCurrency()
{
return Platform::GetCurrencyValue(NULL);
JNIEnv* env = static_cast<JNIEnv*>(SDL_AndroidGetJNIEnv());
jobject activity = static_cast<jobject>(SDL_AndroidGetActivity());
jclass activityClass = env->GetObjectClass(activity);
jmethodID getDefaultLocale = env->GetMethodID(activityClass, "getLocaleCurrency", "()Ljava/lang/String;");
jstring jniString = static_cast<jstring>(env->CallObjectMethod(activity, getDefaultLocale));
const char* jniChars = env->GetStringUTFChars(jniString, nullptr);
std::string localeCurrencyCode = jniChars;
env->ReleaseStringUTFChars(jniString, jniChars);
env->DeleteLocalRef(activity);
env->DeleteLocalRef(activityClass);
return Platform::GetCurrencyValue(localeCurrencyCode.c_str());
}
MeasurementFormat GetLocaleMeasurementFormat()
{
return MeasurementFormat::Metric;
JNIEnv* env = static_cast<JNIEnv*>(SDL_AndroidGetJNIEnv());
jobject activity = static_cast<jobject>(SDL_AndroidGetActivity());
jclass activityClass = env->GetObjectClass(activity);
jmethodID getIsImperialLocaleMeasurementFormat = env->GetMethodID(
activityClass, "isImperialLocaleMeasurementFormat", "()Z");
jboolean isImperial = env->CallBooleanMethod(activity, getIsImperialLocaleMeasurementFormat);
env->DeleteLocalRef(activity);
env->DeleteLocalRef(activityClass);
return isImperial == JNI_TRUE ? MeasurementFormat::Imperial : MeasurementFormat::Metric;
}
std::string GetSteamPath()