get preferred locales on android

This commit is contained in:
kyle-sylvestre 2025-05-20 18:09:28 -04:00 committed by Sam Lantinga
parent c08b1049d3
commit 8e22194217
3 changed files with 62 additions and 57 deletions

View File

@ -50,6 +50,8 @@
boolean supportsRelativeMouse(); boolean supportsRelativeMouse();
int openFileDescriptor(java.lang.String, java.lang.String); int openFileDescriptor(java.lang.String, java.lang.String);
boolean showFileDialog(java.lang.String[], boolean, boolean, int); boolean showFileDialog(java.lang.String[], boolean, boolean, int);
java.lang.String getPreferredLocales();
java.lang.String formatLocale(java.util.Locale);
} }
-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.HIDDeviceManager { -keep,includedescriptorclasses,allowoptimization class org.libsdl.app.HIDDeviceManager {

View File

@ -23,6 +23,7 @@ import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.LocaleList;
import android.os.Message; import android.os.Message;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
@ -2116,6 +2117,48 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
int requestCode; int requestCode;
boolean multipleChoice; boolean multipleChoice;
} }
/**
* This method is called by SDL using JNI.
*/
public static String getPreferredLocales() {
String result = "";
if (Build.VERSION.SDK_INT >= 24 /* Android 7 (N) */) {
LocaleList locales = LocaleList.getAdjustedDefault();
for (int i = 0; i < locales.size(); i++) {
if (i != 0) result += ",";
result += formatLocale(locales.get(i));
}
}
else if (mCurrentLocale != null) {
result = formatLocale(mCurrentLocale);
}
return result;
}
public static String formatLocale(Locale locale) {
String result = "";
String lang = "";
if (locale.getLanguage() == "in") {
// Indonesian is "id" according to ISO 639.2, but on Android is "in" because of Java backwards compatibility
lang = "id";
}
else if (locale.getLanguage() == "") {
// Make sure language is never empty
lang = "und";
}
else {
lang = locale.getLanguage();
}
if (locale.getCountry() == "") {
result = lang;
}
else {
result = lang + "_" + locale.getCountry();
}
return result;
}
} }
/** /**

View File

@ -371,6 +371,7 @@ static jmethodID midShowTextInput;
static jmethodID midSupportsRelativeMouse; static jmethodID midSupportsRelativeMouse;
static jmethodID midOpenFileDescriptor; static jmethodID midOpenFileDescriptor;
static jmethodID midShowFileDialog; static jmethodID midShowFileDialog;
static jmethodID midGetPreferredLocales;
// audio manager // audio manager
static jclass mAudioManagerClass; static jclass mAudioManagerClass;
@ -660,6 +661,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl
midSupportsRelativeMouse = (*env)->GetStaticMethodID(env, mActivityClass, "supportsRelativeMouse", "()Z"); midSupportsRelativeMouse = (*env)->GetStaticMethodID(env, mActivityClass, "supportsRelativeMouse", "()Z");
midOpenFileDescriptor = (*env)->GetStaticMethodID(env, mActivityClass, "openFileDescriptor", "(Ljava/lang/String;Ljava/lang/String;)I"); midOpenFileDescriptor = (*env)->GetStaticMethodID(env, mActivityClass, "openFileDescriptor", "(Ljava/lang/String;Ljava/lang/String;)I");
midShowFileDialog = (*env)->GetStaticMethodID(env, mActivityClass, "showFileDialog", "([Ljava/lang/String;ZZI)Z"); midShowFileDialog = (*env)->GetStaticMethodID(env, mActivityClass, "showFileDialog", "([Ljava/lang/String;ZZI)Z");
midGetPreferredLocales = (*env)->GetStaticMethodID(env, mActivityClass, "getPreferredLocales", "()Ljava/lang/String;");
if (!midClipboardGetText || if (!midClipboardGetText ||
!midClipboardHasText || !midClipboardHasText ||
@ -691,7 +693,8 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl
!midShowTextInput || !midShowTextInput ||
!midSupportsRelativeMouse || !midSupportsRelativeMouse ||
!midOpenFileDescriptor || !midOpenFileDescriptor ||
!midShowFileDialog) { !midShowFileDialog ||
!midGetPreferredLocales) {
__android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLActivity.java?"); __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLActivity.java?");
} }
@ -2585,65 +2588,22 @@ bool Android_JNI_ShowToast(const char *message, int duration, int gravity, int x
bool Android_JNI_GetLocale(char *buf, size_t buflen) bool Android_JNI_GetLocale(char *buf, size_t buflen)
{ {
AConfiguration *cfg; bool result = false;
if (buf && buflen > 0) {
SDL_assert(buflen > 6); *buf = '\0';
JNIEnv *env = Android_JNI_GetEnv();
// Need to re-create the asset manager if locale has changed (SDL_EVENT_LOCALE_CHANGED) jstring string = (jstring)(*env)->CallStaticObjectMethod(env, mActivityClass, midGetPreferredLocales);
Internal_Android_Destroy_AssetManager(); if (string) {
const char *utf8string = (*env)->GetStringUTFChars(env, string, NULL);
if (!asset_manager) { if (utf8string) {
Internal_Android_Create_AssetManager(); result = true;
} SDL_strlcpy(buf, utf8string, buflen);
(*env)->ReleaseStringUTFChars(env, string, utf8string);
if (!asset_manager) {
return false;
}
cfg = AConfiguration_new();
if (!cfg) {
return false;
}
{
char language[2] = {};
char country[2] = {};
size_t id = 0;
AConfiguration_fromAssetManager(cfg, asset_manager);
AConfiguration_getLanguage(cfg, language);
AConfiguration_getCountry(cfg, country);
// Indonesian is "id" according to ISO 639.2, but on Android is "in" because of Java backwards compatibility
if (language[0] == 'i' && language[1] == 'n') {
language[1] = 'd';
}
// copy language (not null terminated)
if (language[0]) {
buf[id++] = language[0];
if (language[1]) {
buf[id++] = language[1];
} }
(*env)->DeleteLocalRef(env, string);
} }
buf[id++] = '_';
// copy country (not null terminated)
if (country[0]) {
buf[id++] = country[0];
if (country[1]) {
buf[id++] = country[1];
}
}
buf[id++] = '\0';
SDL_assert(id <= buflen);
} }
return result;
AConfiguration_delete(cfg);
return true;
} }
bool Android_JNI_OpenURL(const char *url) bool Android_JNI_OpenURL(const char *url)