mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-19 20:21:36 +00:00
fix(android): prefer live AppCompat locales
This commit is contained in:
@@ -5,6 +5,7 @@ import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import android.os.Build
|
||||
import android.util.Xml
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.core.app.LocaleManagerCompat
|
||||
@@ -135,7 +136,13 @@ internal object NativeStringResources {
|
||||
fun install(context: Context) {
|
||||
val appContext = context.applicationContext
|
||||
applicationContext = appContext
|
||||
val requestedLocales = appContext.requestedApplicationLocales()
|
||||
val liveLocales =
|
||||
if (Build.VERSION.SDK_INT >= 33) {
|
||||
LocaleManagerCompat.getApplicationLocales(appContext)
|
||||
} else {
|
||||
AppCompatDelegate.getApplicationLocales()
|
||||
}
|
||||
val requestedLocales = liveLocales.takeUnless { it.isEmpty } ?: appContext.readStoredAppLocales()
|
||||
applicationLocaleMode =
|
||||
if (requestedLocales.isEmpty) {
|
||||
ApplicationLocaleMode.System(ConfigurationCompat.getLocales(appContext.resources.configuration))
|
||||
@@ -162,14 +169,19 @@ internal object NativeStringResources {
|
||||
|
||||
@Synchronized
|
||||
fun setConfigurationLocales(configuration: Configuration) {
|
||||
val requestedLocales =
|
||||
applicationContext?.requestedApplicationLocales()
|
||||
?: LocaleListCompat.getEmptyLocaleList()
|
||||
val previousMode = applicationLocaleMode
|
||||
val context = applicationContext
|
||||
val liveLocales =
|
||||
when {
|
||||
context == null -> LocaleListCompat.getEmptyLocaleList()
|
||||
Build.VERSION.SDK_INT >= 33 -> LocaleManagerCompat.getApplicationLocales(context)
|
||||
else -> AppCompatDelegate.getApplicationLocales()
|
||||
}
|
||||
applicationLocaleMode =
|
||||
if (requestedLocales.isEmpty) {
|
||||
ApplicationLocaleMode.System(ConfigurationCompat.getLocales(configuration))
|
||||
} else {
|
||||
ApplicationLocaleMode.Pinned(requestedLocales)
|
||||
when {
|
||||
!liveLocales.isEmpty -> ApplicationLocaleMode.Pinned(liveLocales)
|
||||
Build.VERSION.SDK_INT < 33 && previousMode is ApplicationLocaleMode.Pinned -> previousMode
|
||||
else -> ApplicationLocaleMode.System(ConfigurationCompat.getLocales(configuration))
|
||||
}
|
||||
localizedContext = null
|
||||
}
|
||||
@@ -211,12 +223,6 @@ private fun Context.localizedContext(locales: LocaleListCompat): Context =
|
||||
createConfigurationContext(configuration)
|
||||
}
|
||||
|
||||
private fun Context.requestedApplicationLocales(): LocaleListCompat =
|
||||
LocaleManagerCompat
|
||||
.getApplicationLocales(this)
|
||||
.takeUnless { it.isEmpty }
|
||||
?: readStoredAppLocales()
|
||||
|
||||
private fun Context.readStoredAppLocales(): LocaleListCompat {
|
||||
if (Build.VERSION.SDK_INT >= 33) return LocaleListCompat.getEmptyLocaleList()
|
||||
// AppCompat only hydrates auto-stored locales when a delegate attaches. A cold service
|
||||
|
||||
@@ -2,6 +2,7 @@ package ai.openclaw.app.i18n
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.core.os.ConfigurationCompat
|
||||
import androidx.core.os.LocaleListCompat
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
@@ -70,20 +71,21 @@ class NativeStringsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun configurationLocaleRefreshesPersistedAppLocale() {
|
||||
fun configurationLocaleUsesLiveAppCompatLocaleBeforeStorage() {
|
||||
val app = RuntimeEnvironment.getApplication()
|
||||
persistAppLocales(app, "fr")
|
||||
persistAppLocales(app, "en")
|
||||
try {
|
||||
NativeStringResources.install(app)
|
||||
assertEquals("Micro désactivé", nativeString("Mic off"))
|
||||
assertEquals("Mic off", nativeString("Mic off"))
|
||||
|
||||
persistAppLocales(app, "de")
|
||||
AppCompatDelegate.setApplicationLocales(LocaleListCompat.forLanguageTags("fr"))
|
||||
val configuration = Configuration(app.resources.configuration)
|
||||
ConfigurationCompat.setLocales(configuration, LocaleListCompat.forLanguageTags("en"))
|
||||
NativeStringResources.setConfigurationLocales(configuration)
|
||||
|
||||
assertEquals("Mikrofon aus", nativeString("Mic off"))
|
||||
assertEquals("Micro désactivé", nativeString("Mic off"))
|
||||
} finally {
|
||||
AppCompatDelegate.setApplicationLocales(LocaleListCompat.getEmptyLocaleList())
|
||||
app.deleteFile(APP_LOCALES_FILE)
|
||||
NativeStringResources.setApplicationLocales(LocaleListCompat.getEmptyLocaleList())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user