I want to change my app language programatically. I have some code which is working on older phones ( Android 6) but it is not working on Android 8 and Android 9. Any working solution for app language change? After calling setLocal I call recreate() inside Activity. Still no changes in strings.
In my MainActivity which is extending BaseActivity in onCreate() If I call Locale.getDefault().language it is returning correct language code but strings are still in English which is default string.xml.
fun setLocale(context: Context, language: String?): Context {
app.setLanguage(language)
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
updateResources(context, language)
} else updateResourcesLegacy(
context,
language
)
}
@TargetApi(Build.VERSION_CODES.N)
private fun updateResources(context: Context, language: String?): Context {
val locale =
if (language == null){
Locale(Locale.getDefault().language)
} else {
Locale(language)
}
Locale.setDefault(locale)
val configuration = context.resources.configuration
configuration.setLocale(locale)
return context.createConfigurationContext(configuration)
}
@Suppress("DEPRECATION")
private fun updateResourcesLegacy(context: Context, language: String?): Context {
val locale =
if (language == null){
Locale(Locale.getDefault().language)
} else {
Locale(language)
}
Locale.setDefault(locale)
val resources = context.resources
val configuration = resources.configuration
configuration.locale = locale
resources.updateConfiguration(configuration, resources.displayMetrics)
return context
}
UPDATE:
Ive used combination of both solutions below, but still without success. I made BaseActivity class which is extended by all of my activities. And there I call changeLocale function which is similar to LocaleHelper. app.getSavedLanguage() returns saved language code in my sharedPrefs. This code is overwritten based on which language user choose in app. App is Application class which is working with shared preferences.
override fun onCreate(si: Bundle?) {
super.onCreate(si)
app = application as App
changeLocale(this, app.getSavedLanguage())
}
open fun changeLocale(context: Context, lang: String) {
val newLocale = Locale(lang)
Locale.setDefault(newLocale)
val res: Resources = context.resources
val conf: Configuration = res.configuration
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
conf.apply {
setLocale(newLocale)
setLayoutDirection(newLocale)
}
context.createConfigurationContext(conf)
} else {
conf.apply {
locale = newLocale
setLayoutDirection(newLocale)
}
res.updateConfiguration(conf, res.displayMetrics)
}
}