To change the locale, I am using method of creating a new Context and passing it into #super.attachBaseContext
.
This works fine for the Activities, since in my use-case it is applicable in the initial activities before the main workflow starts, so I can get away with simply calling #Activity.recreate()
and the attachBaseContext
will be called again.
However, this is not the case with Application class and I am using Application Context to load resources where a Context is not easily available, such as View Models, Repositories, and Helper classes.
So the locales are not updated when accessed using Application Context, since I am not letting the application class know, anywhere, that the resources have changed. #Application.attachBaseContext
can only be called once, and I could not find a way to recreate the application class, and it will be a bad user experience as well.
So is there a way to reload Application-level resources dynamically? Is there a way to recreate the application class?
How can we change Locale on Application level resources dynamically?
override fun attachBaseContext(newBase: Context?) {
newBase?.let {
val langCode : String = LocaleHelper().getCurrentLocale().code
toast("attachBaseContext")
val context : Context = changeLang(it, langCode)
super.attachBaseContext(context)
} ?: run {
super.attachBaseContext(newBase)
}
}
private fun changeLang(newContext: Context, langCode: String): ContextWrapper {
var context = newContext
val sysLocale: Locale
val rs = context.resources
val config = rs.configuration
if (langCode != "") {
val locale = Locale(langCode)
Locale.setDefault(locale)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
config.setLocale(locale)
} else {
config.locale = locale
}
context = context.createConfigurationContext(config)
}
return ContextWrapper(context)
}