Мне нужен доступ к локализованным строкам приложения, когда я не использую Context
связанные классы (Activites, Fragments, Services, Views и т. Д.) В ViewModel
или пользовательских классах, где я храню всю свою бизнес-логику. Например, отправка String
на UI
с помощью LiveData
:
toastMessageLiveData.value = buildLastLoginToastMessage()
fun buildLastLoginToastMessage() {
val lastLoginDiff = (System.currentMillis() - getLastLogin()) / DateUtils.HOURS_IN_MILLIS
return MyApp.instance.getString(R.string.last_login_txt, lastLoginDiff)
}
Сейчас в Activity
я наблюдаю за изменением LiveData
и показываю сообщение Toast.
Это работает нормально, но проблема возникает, если пользователь меняет язык приложения . Макеты обновлены, и я вижу, что используется язык новой локали, но функция MyApp.instance.getString(R.string....)
все еще использует старую локаль . Если я принудительно убиваю приложение и перезагружаю его, оно работает, потому что приложение attachBaseContext
вызывается снова и применяется новый язык. Однако я не хочу принудительно уничтожать приложение, мне нужно решение для обновления конфигурации приложения.
Утилита для создания или обновления Context
fun buildLocalizedContext(context: Context): Context {
// From preferences, load the saved Language and Country codes
val language = getSavedLanguage()
val country = getSavedCountry()
// Create the new locale
val locale = Locale(language, country)
Locale.setDefault(locale)
val resources = context.resources
val configuration = Configuration(resources.configuration)
// Create a new configration or update the existing one if the API is less than 17
if (Build.VERSION.SDK_INT >= 17) {
configuration.setLocale(locale)
return context.createConfigurationContext(configuration)
} else {
configuration.locale = locale
resources.updateConfiguration(configuration, resources.getDisplayMetrics())
}
return context
}
Когда приложение запустится, примените новую локаль
class MyApp: Application {
override fun attachBaseContext(base: Context) {
super.attachBaseContext(LocaleHelper.instance.buildLocalizedContext(base))
}
}
Класс BaseActivity
, который используется другими активами:
class BaseActivity: AppCompatActivity {
override fun attachBaseContext(newBase: Context) {
super.attachBaseContext(LocaleHelper.instance.buildLocalizedContext(newBase))
}
}
Это то, что мне удалось сделать до сих пор, однако это тоже не работает:
fun changeLocale(locale: Locale, app: Application) {
Locale.setDefault(locale)
val resources = app.resources
val configuration = resources.configuration
if (Build.VERSION.SDK_INT >= 17) {
configuration.setLocale(locale)
}
else {
configuration.locale = locale
resources.updateConfiguration(configuration, resources.displayMetrics)
}
}
Приведенный выше фрагмент кода не работает, он не меняет локаль приложения, только если я принудительно перезапущу приложение.