7

I have 2 string files "en" and "tr". When I change my telephone's language string files change automatically(I didn't write extra code for this result and I don't know how this happen). I want change string files with programmatically. I used this code. I get Toast message but language doesn't change.WHY? I used these code before for another application which I write with java not Kotlin and these code work fine. Please don't say duplicate because I read a lot of questions. I try a lot of things until now 4 hours.

override fun onResume() {

        buttonDate()
        changeLanguage()
    super.onResume()
    }
fun changeLanguage(){
        val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(applicationContext)
        val language = sharedPreferences.getString("language","bak")
        Toast.makeText(applicationContext,language,Toast.LENGTH_SHORT).show()
        if(language=="English"){
            Toast.makeText(applicationContext,"English",Toast.LENGTH_SHORT).show()
            language("")
        }else if(language=="Turkish"){
            Toast.makeText(applicationContext,"Turkish",Toast.LENGTH_SHORT).show()
            language("tr")
        }
    }


    fun language(language: String){
        val locale = Locale(language)
        Locale.setDefault(locale)
        val resources = getResources()
        val configuration = resources.getConfiguration()
        configuration.locale = locale
        resources.updateConfiguration(configuration, resources.getDisplayMetrics())
    }
Jon Goodwin
  • 8,834
  • 5
  • 29
  • 53
Hacettepe Hesabı
  • 166
  • 1
  • 2
  • 10
  • 1
    First of all you are get your device language using this code Locale.getDefault().getDisplayLanguage(); – Mayur May 22 '19 at 05:23
  • 1
    Try this link for change language. https://stackoverflow.com/questions/56057127/language-not-changing-in-app-android-studio/56057774#56057774 – Mayur May 22 '19 at 05:26
  • I try this link but it didn't work for me. Maybe I can't I don't know – Hacettepe Hesabı May 22 '19 at 11:46
  • 1
    Does this answer your question? [Change app language programmatically in Android](https://stackoverflow.com/questions/2900023/change-app-language-programmatically-in-android) – Heitor Paceli Feb 17 '22 at 02:28

1 Answers1

8

You need to update configuration even before onCreate is called. To do that create a BaseActivity class like this

open class BaseActivity : AppCompatActivity() {

    companion object {
        public var dLocale: Locale? = null
    }

    init {
        updateConfig(this)
    }

    fun updateConfig(wrapper: ContextThemeWrapper) {
        if(dLocale==Locale("") ) // Do nothing if dLocale is null
            return

        Locale.setDefault(dLocale)
        val configuration = Configuration()
        configuration.setLocale(dLocale)
        wrapper.applyOverrideConfiguration(configuration)
    }
}

Extend you activities from this class.

Set dLocale in you App class like this:

class App : Application() {

    override fun onCreate() {
        super.onCreate()

        var change = ""
        val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
        val language = sharedPreferences.getString("language", "bak")
        if (language == "Turkish") {
            change="tr" 
        } else if (language=="English" ) {
            change = "en"
        }else {
            change ="" 
        } 

        BaseActivity.dLocale = Locale(change) //set any locale you want here
    }
}

You will also need to set App class in your manifest file like this:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    //..

    <application
        android:name=".App"
        //..>

    </application>
</manifest>    

Note: We should set dLocale only in App onCreate to ensure that all activities have same language.

Hacettepe Hesabı
  • 166
  • 1
  • 2
  • 10
ahsanali274
  • 431
  • 2
  • 13
  • Thank you. This answer is work. But how can I add my locale with programatically. If I add `private val dLocale: Locale? = Locale("tr")` this work. But how can I add multiple language. – Hacettepe Hesabı May 22 '19 at 14:47
  • If I use this ```var change = "" val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(wrapper) val language = sharedPreferences.getString("language", "bak") if (language == "Turkish") { change="tr" } else{ } val dLocale: Locale? = Locale(change)``` get null point exception error because of `PreferenceManager.getDefaultSharedPreferences(wrapper)` – Hacettepe Hesabı May 22 '19 at 15:10
  • 1
    I have updated my answer. Let me know if you still have any problem. – ahsanali274 May 23 '19 at 06:49
  • Thank you very much. Your answer really helpfull and work. I edit your code in class App `...if (language=="Turkish") {change="tr"} else if(language=="English") {change="en"} else{ change = "" }... ` and in class BaseActivity `...if(dLocale==Locale(""))...` . dLocale cannot be null because of I define it in App class – Hacettepe Hesabı May 23 '19 at 12:47
  • May I ask a further Question. I have two more problem now. When I change the language, activity label doesn't change which I define at manifest file as `android:label="@string/settings"`. And second problem : When I change language I must restart my application. If I don't restart, language doesn't change. How I solve this problems. – Hacettepe Hesabı May 23 '19 at 12:53
  • 1
    You can use `setTitle(getString(R.string.settings))` in `onCreate` of activity to update label. As for your second question, you can set `dLocale` from anywhere you want but you will need to restart you current activity and all other activities in **back stack** to update their language. So the better choice would be to restart you App for consistency. – ahsanali274 May 23 '19 at 15:02