Re-apply the locale override to the configuration if necessary

This commit is contained in:
cketti 2021-06-05 14:11:35 +02:00
parent 295b9d8d28
commit db0bd06f21
2 changed files with 40 additions and 7 deletions

View file

@ -2,6 +2,7 @@ package com.fsck.k9
import android.app.Application
import android.content.res.Configuration
import android.content.res.Resources
import com.fsck.k9.activity.MessageCompose
import com.fsck.k9.controller.MessagingController
import com.fsck.k9.external.MessageProvider
@ -25,6 +26,7 @@ class App : Application() {
private val themeManager: ThemeManager by inject()
private val appLanguageManager: AppLanguageManager by inject()
private val appCoroutineScope: CoroutineScope = GlobalScope + Dispatchers.Main
private var appLanguageManagerInitialized = false
override fun onCreate() {
Core.earlyInit(this)
@ -46,13 +48,14 @@ class App : Application() {
private fun initializeAppLanguage() {
appLanguageManager.init()
applyOverrideLocale()
applyOverrideLocaleToConfiguration()
appLanguageManagerInitialized = true
listenForAppLanguageChanges()
}
private fun applyOverrideLocale() {
private fun applyOverrideLocaleToConfiguration() {
appLanguageManager.getOverrideLocale()?.let { overrideLocale ->
updateConfigurationWithLocale(resources.configuration, overrideLocale)
updateConfigurationWithLocale(superResources.configuration, overrideLocale)
}
}
@ -61,14 +64,14 @@ class App : Application() {
.drop(1) // We already applied the initial value
.onEach { overrideLocale ->
val locale = overrideLocale ?: Locale.getDefault()
updateConfigurationWithLocale(resources.configuration, locale)
updateConfigurationWithLocale(superResources.configuration, locale)
}
.launchIn(appCoroutineScope)
}
override fun onConfigurationChanged(newConfiguration: Configuration) {
applyOverrideLocale()
super.onConfigurationChanged(resources.configuration)
applyOverrideLocaleToConfiguration()
super.onConfigurationChanged(superResources.configuration)
}
private fun updateConfigurationWithLocale(configuration: Configuration, locale: Locale) {
@ -79,7 +82,31 @@ class App : Application() {
}
@Suppress("DEPRECATION")
resources.updateConfiguration(newConfiguration, resources.displayMetrics)
superResources.updateConfiguration(newConfiguration, superResources.displayMetrics)
}
private val superResources: Resources
get() = super.getResources()
// Creating a WebView instance triggers something that will cause the configuration of the Application's Resources
// instance to be reset to the default, i.e. not containing our locale override. Unfortunately, we're not notified
// about this event. So we're checking each time someone asks for the Resources instance whether we need to change
// the configuration again. Luckily, right now (Android 11), the platform is calling this method right after
// resetting the configuration.
override fun getResources(): Resources {
val resources = super.getResources()
if (appLanguageManagerInitialized) {
appLanguageManager.getOverrideLocale()?.let { overrideLocale ->
if (resources.configuration.currentLocale != overrideLocale) {
Timber.w("Resources configuration was reset. Re-applying locale override.")
appLanguageManager.applyOverrideLocale()
applyOverrideLocaleToConfiguration()
}
}
}
return resources
}
companion object {

View file

@ -45,6 +45,12 @@ class AppLanguageManager(
setLocale(appLanguage)
}
fun applyOverrideLocale() {
currentOverrideLocale?.let { overrideLocale ->
Locale.setDefault(overrideLocale)
}
}
private fun setLocale(appLanguage: String) {
val overrideLocale = getOverrideLocaleForLanguage(appLanguage)
currentOverrideLocale = overrideLocale