4

I can not change my application to another language on Android 8.0

my code: Application class

class MyApplication : Application() {

companion object {
    fun changeLanguage(context: Context, lang: String) {
        Log.e(context.packageName, lang)
        val locale = Locale(lang)
        Locale.setDefault(locale)
        val config = context.resources.configuration
        config.setLocale(locale)
        context.createConfigurationContext(config)
        context.resources.updateConfiguration(config, context.resources.displayMetrics)

        val sharedPreference = PreferenceManager.getDefaultSharedPreferences(context)
        sharedPreference.edit().putString("lang", lang).apply()
    }
}

override fun onCreate() {
    super.onCreate()
    val sharedPreference = PreferenceManager.getDefaultSharedPreferences(this)
    val lang = sharedPreference.getString("lang", "en")

    changeLanguage(this, lang)
  }
}

MainActivity class

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val sharedPreference = PreferenceManager.getDefaultSharedPreferences(this)
    val lang = sharedPreference.getString("lang", "en")
    if (lang == "en") {
        switchLanguage.setText(R.string.english)
    } else {
        switchLanguage.setText(R.string.viet)
    }
    switchLanguage.isChecked = lang != "en"
    switchLanguage.setOnCheckedChangeListener { _, b ->
        if (!b) {
            MyApplication.changeLanguage(baseContext, "en")
        } else {
            MyApplication.changeLanguage(baseContext, "vi")
        }

        finish()
        startActivity(intent)
      }
   }
}

When first run app: first run

When I change language to Vietnamese, toolbar not change language toolbar not change language

When I kill app and reopened all textview convert to english all textview convert to english

sorry my English

Hoang Duc Tuan
  • 415
  • 1
  • 4
  • 15

1 Answers1

0

The problem is on restarting the activity.

Instead of finish() and startActivity(intent), use recreate() method to recreate the current activity, the new language.

Change setOnCheckedChangeListener:

switchLanguage.setOnCheckedChangeListener { _, b ->
    if (!b) {
        MyApplication.changeLanguage(baseContext, "en")
    } else {
        MyApplication.changeLanguage(baseContext, "vi")
    }
    recreate()
}

Check your strings.xml also for both languages.

If a string is missing in the translated language, it will get back to the default language.

This approach is working on Android 8.0 and above.


Android 8.0 introduced locale list that allows to use multiple languages in order of preference.

You need this API provided by Android to create new config with locale list and update the app's resources and activity.

class MyApplication : Application() {

  companion object {
      fun changeLanguage(...) {
          val locale = ...
          // Set Default Locale

          val resources = ...
          val configuration = ...
          // Configuration

          val localeList = ...
          // Configuration

          // Resources with metrics if needed

          // get default share preferences
      }
  }

  override fun funName(...Context) {
      // super.attackBaseContext(updateBaseLocale(...))
  }

  private yourFunName {
      
      // Shared Preferences
      
      // Locale

      // Resources

      // Configuration

      return ...(...)
  }

}

updateBaseLocale creates new Context this method being called attachBaseContext.