diff --git a/app/src/main/java/eu/kanade/tachiyomi/App.kt b/app/src/main/java/eu/kanade/tachiyomi/App.kt index 2efc85ea7d..c1e3c25626 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/App.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/App.kt @@ -2,7 +2,6 @@ package eu.kanade.tachiyomi import android.app.Application import android.content.Context -import android.content.res.Configuration import android.os.Build import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleObserver @@ -14,7 +13,6 @@ import eu.kanade.tachiyomi.data.notification.Notifications import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate -import eu.kanade.tachiyomi.util.system.LocaleHelper import org.acra.ACRA import org.acra.config.httpSender import org.acra.data.StringFormat @@ -54,7 +52,6 @@ open class App : Application(), LifecycleObserver { setupAcra() setupNotificationChannels() - LocaleHelper.updateConfiguration(this, resources.configuration) ProcessLifecycleOwner.get().lifecycle.addObserver(this) // Reset Incognito Mode on relaunch @@ -75,11 +72,6 @@ open class App : Application(), LifecycleObserver { MultiDex.install(this) } - override fun onConfigurationChanged(newConfig: Configuration) { - super.onConfigurationChanged(newConfig) - LocaleHelper.updateConfiguration(this, newConfig, true) - } - protected open fun setupAcra() { initAcra { reportFormat = StringFormat.JSON diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseActivity.kt index 5ba5c19200..612efe9d2a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseActivity.kt @@ -1,5 +1,6 @@ package eu.kanade.tachiyomi.ui.base.activity +import android.content.Context import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import androidx.viewbinding.ViewBinding @@ -17,9 +18,8 @@ abstract class BaseActivity : AppCompatActivity() { lateinit var binding: VB val isBindingInitialized get() = this::binding.isInitialized - init { - @Suppress("LeakingThis") - LocaleHelper.updateConfiguration(this) + override fun attachBaseContext(newBase: Context) { + super.attachBaseContext(LocaleHelper.createLocaleWrapper(newBase)) } override fun onCreate(savedInstanceState: Bundle?) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseRxActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseRxActivity.kt index 8a5e979ac7..5137d026d9 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseRxActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseRxActivity.kt @@ -1,5 +1,6 @@ package eu.kanade.tachiyomi.ui.base.activity +import android.content.Context import android.os.Bundle import androidx.lifecycle.lifecycleScope import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter @@ -11,9 +12,8 @@ abstract class BaseRxActivity

> : NucleusAppCompatActivity

- val activity = activity ?: return@onChange false - val app = activity.application - LocaleHelper.changeLocale(newValue.toString()) - LocaleHelper.updateConfiguration(app, app.resources.configuration) - activity.recreate() + activity?.recreate() true } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/system/LocaleHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/util/system/LocaleHelper.kt index 50d4d902fd..dac4fae8f2 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/system/LocaleHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/system/LocaleHelper.kt @@ -1,10 +1,11 @@ package eu.kanade.tachiyomi.util.system -import android.app.Application import android.content.Context +import android.content.ContextWrapper import android.content.res.Configuration import android.os.Build -import android.view.ContextThemeWrapper +import android.os.LocaleList +import androidx.core.os.LocaleListCompat import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.ui.source.SourcePresenter @@ -14,7 +15,6 @@ import java.util.Locale /** * Utility class to change the application's language in runtime. */ -@Suppress("DEPRECATION") object LocaleHelper { /** @@ -22,34 +22,6 @@ object LocaleHelper { */ private val preferences: PreferencesHelper by injectLazy() - /** - * The system's locale. - */ - private var systemLocale: Locale? = null - - /** - * The application's locale. When it's null, the system locale is used. - */ - private var appLocale = getLocaleFromString(preferences.lang().get()) - - /** - * The currently applied locale. Used to avoid losing the selected language after a non locale - * configuration change to the application. - */ - private var currentLocale: Locale? = null - - /** - * Returns the locale for the value stored in preferences, or null if it's system language. - * - * @param pref the string value stored in preferences. - */ - fun getLocaleFromString(pref: String?): Locale? { - if (pref.isNullOrEmpty()) { - return null - } - return getLocale(pref) - } - /** * Returns Display name of a string language code */ @@ -65,18 +37,35 @@ object LocaleHelper { /** * Returns Display name of a string language code + * + * @param lang empty for system language */ fun getDisplayName(lang: String?): String { - return when (lang) { - null -> "" - "" -> { - systemLocale!!.getDisplayName(systemLocale).capitalize() - } - else -> { - val locale = getLocale(lang) - locale.getDisplayName(locale).capitalize() - } + if (lang == null) { + return "" } + + val locale = if (lang.isEmpty()) { + LocaleListCompat.getAdjustedDefault()[0] + } else { + getLocale(lang) + } + return locale.getDisplayName(locale).replaceFirstChar { it.uppercase(locale) } + } + + /** + * Creates a ContextWrapper using selected Locale + */ + fun createLocaleWrapper(context: Context): ContextWrapper { + val appLocale = getLocaleFromString(preferences.lang().get()) + val newConfiguration = Configuration(context.resources.configuration) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + val localeList = LocaleList(appLocale) + newConfiguration.setLocales(localeList) + } else { + newConfiguration.setLocale(appLocale) + } + return ContextWrapper(context.createConfigurationContext(newConfiguration)) } /*Return Locale from string language code @@ -92,68 +81,14 @@ object LocaleHelper { } /** - * Changes the application's locale with a new preference. + * Returns the locale for the value stored in preferences, defaults to main system language. * - * @param pref the new value stored in preferences. + * @param pref the string value stored in preferences. */ - fun changeLocale(pref: String) { - appLocale = getLocaleFromString(pref) - } - - /** - * Updates the app's language to an activity. - */ - fun updateConfiguration(wrapper: ContextThemeWrapper) { - if (appLocale != null) { - val config = Configuration(preferences.context.resources.configuration) - config.setLocale(appLocale) - wrapper.applyOverrideConfiguration(config) + private fun getLocaleFromString(pref: String?): Locale { + if (pref.isNullOrEmpty()) { + return LocaleListCompat.getDefault()[0] } - } - - /** - * Updates the app's language to the application. - */ - fun updateConfiguration(app: Application, config: Configuration, configChange: Boolean = false) { - if (systemLocale == null) { - systemLocale = getConfigLocale(config) - } - if (configChange) { - val configLocale = getConfigLocale(config) - if (currentLocale == configLocale) { - return - } - systemLocale = configLocale - } - currentLocale = appLocale ?: systemLocale ?: Locale.getDefault() - val newConfig = updateConfigLocale(config, currentLocale!!) - val resources = app.resources - resources.updateConfiguration(newConfig, resources.displayMetrics) - - Locale.setDefault(currentLocale) - } - - /** - * Returns the locale applied in the given configuration. - */ - private fun getConfigLocale(config: Configuration): Locale { - return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { - config.locale - } else { - config.locales[0] - } - } - - /** - * Returns a new configuration with the given locale applied. - */ - private fun updateConfigLocale(config: Configuration, locale: Locale): Configuration { - val newConfig = Configuration(config) - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { - newConfig.setLocale(locale) - } else { - newConfig.setLocale(locale) - } - return newConfig + return getLocale(pref) } }