Android runtime language changes not working when language is not present in the Add a language section

Viewed 41

I am attempting to change my app language locally using the following code. If English and French are present in the Add a language of my phone's Settings, and then go into my app and change the language, the language change is successful, but if I remove the language from the Add a language in the phone's settings, the changes doesn't work. From the examples I am seeing online, it should be possible to change it without having any additional languages in the Add a language of the phone's Settings. I'm not sure what I am doing wrong, is there a way to enable language changes without having to add the language in the phone settings?

Any links to some documentation would also be quite appreciated.

This is the LocalUtil object I am creating to enable the language switching:

object LocalUtil {

    fun applyLanguageContext(context: Context, locale: Locale?): Context {

        if (locale == null) return context
        if (locale == getLocale(context.resources.configuration)) return context
        return try {
            setupLocale(locale)
            val resources = context.resources
            val configuration = getOverridingConfig(locale, resources)
            updateResources(context, resources, configuration)
            context.createConfigurationContext(configuration)
        } catch (e: Exception) {
            e.printStackTrace()
            context
        }
    }

    private fun updateResources(
        context: Context,
        resources: Resources,
        config: Configuration
    ) {
        if (context.applicationContext !== context) {
            resources.updateConfiguration(config, resources.displayMetrics)
        }
    }

    private fun setupLocale(locale: Locale) {
        Locale.setDefault(locale)
        LocaleList.setDefault(LocaleList(locale))
    }

    private fun getOverridingConfig(locale: Locale, resources: Resources): Configuration {
        val configuration = resources.configuration
        configuration.setLocales(LocaleList(locale))
        return configuration
    }

    private fun getLocale(configuration: Configuration): Locale {
        return configuration.locales.get(0)
    }
}

This is the Application() class which includes the LANGUAGE companion object variable

class MyApp: Application() {

    override fun getApplicationContext(): Context {
        val context = super.getApplicationContext()
        return LocalUtil.applyLanguageContext(context, Locale(LANGUAGE))
    }

    override fun attachBaseContext(newBase: Context) {
        super.attachBaseContext(LocalUtil.applyLanguageContext(newBase, Locale(LANGUAGE)))
    }

    companion object {
        var LANGUAGE = "en"
    }
}

This is the MainActivity.kt, with a button that toggles between English "en" and French "fr" via the changeLangBtn: Button

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    fun setChangeLangBtn(view: View) {
        val changeLangBtn: Button = findViewById(R.id.change_lang_btn)
        changeLangBtn.setOnClickListener {
            if (MyApp.LANGUAGE == "en") MyApp.LANGUAGE = "fr" else MyApp.LANGUAGE = "en"
            reloadActivity()
        }
    }

    fun reloadActivity() {
         val intent = Intent(this, javaClass).apply {
             addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
             addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION)
         }

         startActivity(intent)
         recreate()
    }

    override fun getBaseContext(): Context {
        return LocalUtil.applyLanguageContext(super.getBaseContext(), Locale(MyApp.LANGUAGE))
    }

    override fun getApplicationContext(): Context {
        val context = super.getApplicationContext()
        return LocalUtil.applyLanguageContext(context, Locale(MyApp.LANGUAGE))
    }

    override fun attachBaseContext(newBase: Context) {
        super.attachBaseContext(LocalUtil.applyLanguageContext(newBase, Locale(MyApp.LANGUAGE)))
    }
}
0 Answers
Related