Commit 2491f16f85e7e34f9cd0b55c2f39c255e35ba265

Sylvain Becker 2020-05-08T21:40:28

Android: send SDL_LOCALECHANGED when locale changes

diff --git a/android-project/app/src/main/AndroidManifest.xml b/android-project/app/src/main/AndroidManifest.xml
index 9bcd6e8..36c5378 100644
--- a/android-project/app/src/main/AndroidManifest.xml
+++ b/android-project/app/src/main/AndroidManifest.xml
@@ -70,7 +70,7 @@
             android:label="@string/app_name"
             android:alwaysRetainTaskState="true"
             android:launchMode="singleInstance"
-            android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation"
+            android:configChanges="layoutDirection|locale|orientation|uiMode|screenLayout|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation"
             >
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
index cad6b1a..f051d96 100644
--- a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
+++ b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
@@ -4,6 +4,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.util.Arrays;
 import java.util.Hashtable;
+import java.util.Locale;
 import java.lang.reflect.Method;
 import java.lang.Math;
 
@@ -62,6 +63,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
     protected static final int SDL_ORIENTATION_PORTRAIT_FLIPPED = 4;
 
     protected static int mCurrentOrientation;
+    protected static Locale mCurrentLocale;
 
     // Handle the state of the native layer
     public enum NativeState {
@@ -258,6 +260,15 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
         // Only record current orientation
         SDLActivity.onNativeOrientationChanged(mCurrentOrientation);
 
+        try {
+            if (Build.VERSION.SDK_INT < 24) {
+                mCurrentLocale = getContext().getResources().getConfiguration().locale;
+            } else {
+                mCurrentLocale = getContext().getResources().getConfiguration().getLocales().get(0);
+            }
+        } catch(Exception ignored) {
+        }
+
         setContentView(mLayout);
 
         setWindowStyle(false);
@@ -408,6 +419,17 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
     }
 
     @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        Log.v(TAG, "onConfigurationChanged()");
+        super.onConfigurationChanged(newConfig);
+
+        if (!mCurrentLocale.equals(newConfig.locale)) {
+            mCurrentLocale = newConfig.locale;
+            SDLActivity.onNativeLocaleChanged();
+        }
+    }
+
+    @Override
     protected void onDestroy() {
         Log.v(TAG, "onDestroy()");
 
@@ -784,6 +806,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
     public static native void onNativeOrientationChanged(int orientation);
     public static native void nativeAddTouch(int touchId, String name);
     public static native void nativePermissionResult(int requestCode, boolean result);
+    public static native void onNativeLocaleChanged();
 
     /**
      * This method is called by SDL using JNI.
diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c
index 81bf846..41011c1 100644
--- a/src/core/android/SDL_android.c
+++ b/src/core/android/SDL_android.c
@@ -127,6 +127,9 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeClipboardChanged)(
 JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeLowMemory)(
         JNIEnv *env, jclass cls);
 
+JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeLocaleChanged)(
+        JNIEnv *env, jclass cls);
+
 JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSendQuit)(
         JNIEnv *env, jclass cls);
 
@@ -180,6 +183,7 @@ static JNINativeMethod SDLActivity_tab[] = {
     { "onNativeAccel",              "(FFF)V", SDL_JAVA_INTERFACE(onNativeAccel) },
     { "onNativeClipboardChanged",   "()V", SDL_JAVA_INTERFACE(onNativeClipboardChanged) },
     { "nativeLowMemory",            "()V", SDL_JAVA_INTERFACE(nativeLowMemory) },
+    { "onNativeLocaleChanged",      "()V", SDL_JAVA_INTERFACE(onNativeLocaleChanged) },
     { "nativeSendQuit",             "()V", SDL_JAVA_INTERFACE(nativeSendQuit) },
     { "nativeQuit",                 "()V", SDL_JAVA_INTERFACE(nativeQuit) },
     { "nativePause",                "()V", SDL_JAVA_INTERFACE(nativePause) },
@@ -1142,6 +1146,15 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeLowMemory)(
     SDL_SendAppEvent(SDL_APP_LOWMEMORY);
 }
 
+/* Locale
+ * requires android:configChanges="layoutDirection|locale" in AndroidManifest.xml */
+JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeLocaleChanged)(
+                                    JNIEnv *env, jclass cls)
+{
+    SDL_SendAppEvent(SDL_LOCALECHANGED);
+}
+
+
 /* Send Quit event to "SDLThread" thread */
 JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSendQuit)(
                                     JNIEnv *env, jclass cls)
@@ -2859,6 +2872,9 @@ int Android_JNI_GetLocale(char *buf, size_t buflen)
 
     SDL_assert(buflen > 6);
 
+    /* Need to re-create the asset manager if locale has changed (SDL_LOCALECHANGED) */
+    Internal_Android_Destroy_AssetManager();
+
     if (asset_manager == NULL) {
         Internal_Android_Create_AssetManager();
     }