Search code examples
androidxmlkotlinlocaledefault

How do I force the app to follow the phone's system language?


In the application settings I have a RadioGroup that contains four RadioButtons, each one labeled with a specific language name and the last one labeled “Automatic (depending on device language)”.

activity_settings.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/a10"
tools:context=".Settings">

<TextView
    android:id="@+id/textView13"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="10dp"
    android:fontFamily="@font/tajawal_medium"
    android:text="@string/settings"
    android:textColor="@color/a1"
    android:textSize="30sp"
    android:textStyle="bold"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<TextView
    android:id="@+id/textView14"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="20dp"
    android:layout_marginTop="40dp"
    android:fontFamily="@font/tajawal"
    android:text="@string/language"
    android:textColor="@color/a1"
    android:textSize="20sp"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/textView13" />

<RadioGroup
    android:id="@+id/languages"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="20dp"
    android:layout_marginTop="20dp"
    app:layout_constraintStart_toStartOf="@+id/textView14"
    app:layout_constraintTop_toBottomOf="@+id/textView14">

    <RadioButton
        android:id="@+id/ar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/arabic" />

    <RadioButton
        android:id="@+id/en"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/english" />

    <RadioButton
        android:id="@+id/fr"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/français" />

    <RadioButton
        android:id="@+id/auto_lang"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/auto_lang" />
</RadioGroup>

<TextView
    android:id="@+id/textView15"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="20dp"
    android:layout_marginTop="40dp"
    android:fontFamily="@font/tajawal"
    android:text="@string/mode"
    android:textColor="@color/a1"
    android:textSize="20sp"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@id/languages" />

<RadioGroup
    android:id="@+id/modes"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="20dp"
    android:layout_marginTop="20dp"
    app:layout_constraintStart_toStartOf="@id/textView15"
    app:layout_constraintTop_toBottomOf="@id/textView15">

    <RadioButton
        android:id="@+id/dark"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/dark_mode" />

    <RadioButton
        android:id="@+id/light"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/light_mode" />

    <RadioButton
        android:id="@+id/auto_mode"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/auto_mode" />
</RadioGroup>

<Button
    android:id="@+id/save"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginBottom="20dp"
    android:backgroundTint="@color/a5"
    android:fontFamily="@font/tajawal_medium"
    android:text="@string/save"
    android:textColor="@color/a1"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent" />

 </androidx.constraintlayout.widget.ConstraintLayout>

Setting.kt:

package com.example.quranprompter

import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.content.res.Configuration
import android.media.VolumeShaper
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.preference.PreferenceManager
import android.view.View
import android.widget.Button
import android.widget.RadioButton
import android.widget.RadioGroup
import android.widget.Toast
import androidx.appcompat.app.AppCompatDelegate
import java.util.Locale


class Settings : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_settings)

    val buSave = findViewById<Button>(R.id.save)

    val currentLocale = resources.configuration.locale
    val currentLanguage = currentLocale.language
    val preferences = PreferenceManager.getDefaultSharedPreferences(this)
    val a = preferences.edit()
    val selectedLanguage = preferences.getString("language", "en")
    val currentMode = preferences.getString("mode", 
    AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM.toString())

    //RadioButton of Languages
    val ar = findViewById<RadioButton>(R.id.ar)
    val en = findViewById<RadioButton>(R.id.en)
    val fr = findViewById<RadioButton>(R.id.fr)
    val auLa = findViewById<RadioButton>(R.id.auto_lang)

    when(selectedLanguage){
        "ar" -> ar.isChecked = true
        "en" -> en.isChecked = true
        "fr" -> fr.isChecked = true
        else -> auLa.isChecked = true
    }

    //RadioButton Modes
    var dark = findViewById<RadioButton>(R.id.dark)
    var light = findViewById<RadioButton>(R.id.light)
    var auMo = findViewById<RadioButton>(R.id.auto_mode)

    when(currentMode){
        AppCompatDelegate.MODE_NIGHT_YES.toString() ->
            dark.isChecked = true
        AppCompatDelegate.MODE_NIGHT_NO.toString() ->
            light.isChecked = true
        AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM.toString() ->
            auMo.isChecked = true
    }
    //Save Button
    buSave.setOnClickListener {
        //Languages
        var codeLang : String = "en"
        if(ar.isChecked){
            codeLang = "ar"
        }else if(en.isChecked){
            codeLang = "en"
        }else if(fr.isChecked){
            codeLang = "fr"
        }else if(auLa.isChecked){
            codeLang = Locale.getDefault().toString()
        }

        val locale = Locale(codeLang)
        Locale.setDefault(locale)
        val configuration = Configuration()
        configuration.locale = locale
        resources.updateConfiguration(configuration, resources.displayMetrics)
        a.putString("language",codeLang )
        a.apply()


        //Modes
        var codeMode : String = AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM.toString()
        if(dark.isChecked){
            codeMode = AppCompatDelegate.MODE_NIGHT_YES.toString()
        }else if(light.isChecked){
            codeMode = AppCompatDelegate.MODE_NIGHT_NO.toString()
        }else if(auMo.isChecked){
            codeMode = AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM.toString()
        }

        AppCompatDelegate.setDefaultNightMode(codeMode.toInt())
        a.putString("mode",codeMode)
        a.apply()

        val intent = Intent(applicationContext, Levels::class.java)
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        startActivity(intent)
        finish()
    }
}
}

Note: After pressing the save button, you will switch between languages.

Switching between languages goes well, while if you want to switch to the device language, the last language in the application is used.

For example, if the application is in French and the phone is in English and you select “Automatic (depending on device language)” and then save, the French language will be applied, but I want to apply the phone language.

I think that this code is not appropriate in this case to retrieve the phone's language code.

                codeLang = Locale.getDefault().toString()

Solution

  • Use this to get the device current language:

    Resources.getSystem().configuration.locale.language
    

    In your code replace when "Automatic" is clicked with this:

       // ....
            else if(auLa.isChecked){
                    codeLang = Resources.getSystem().configuration.locale.language
                }
        // ....