The All-In-One Guide for Changing App Locale Dynamically in Android (Kotlin)

Tareq Rahman Joy
The Startup
Published in
5 min readFeb 3, 2021

--

Changing in-App locale is not straight forward in Android as there is no native library support for that. So, here is the one-by-one production level approach you can follow. We will copy the locale change mechanism like WhatsApp.

1. Setup SharedPreferences class

To save the current locale settings, we must need to save them in SharedPrefrenece. So, we will create a Storage class to save and to get the saved locale. As an example for English, we are saving “en” in the storage.

2. Setup Locale support class

We are now at the main stage, implementing the locale changes functionality independent of the system settings. This is a Util class, so we can call the methods without initializing the class.

Note: We are using “sys_def” for defining the option for following system language.

3. Setup Application class

As we wanted to change locale throughout the app we must need to modify the application class. So, we will get the localized string even with the applicationContext.

  1. Create Application Class:

2. Mention the application class name in AndroidMenifest.xml

We will need to specify the application class name in AndroidMenifest. Just add android:name=”.MyApp” inside the application tag like below:

4. Setup BaseActivity class

We will need a top-level activity class which will handle the locale changes so that we won’t need to write code for every activity we have.

Note: We will need to restart every activity after changing the locale. So, we use recreate method in onResume.

5. Extending BaseActivity in each Activity

Now, we can simply extend the BaseActivity class in every activity to make it work. So, AppCompatActivity() will be replaced with BaseActivity() in all the activity classes like below:

Extending BaseActicty class to MainActvity class

If you have more Activities you should do the same.

6. Adding localized strings.xml files

Now, we will add our localized strings in res/values folder. If we go to app > res > values in the project view, we will see there is a file named strings.xml which should contain all the strings that will be used by our app. This file is the default file. So, if we want to use our localized strings we will need to add new strings.xml file specifying the locale. To do so, we will have to follow the steps: File > New > Android Resouce File.

File Name: strings
Resource type: Values
Directory name: values

Select locale in available qualifiers then press >>. Now you can select language and region. The final screen will be like below. I have chosen my locale Bengali.

Now, you will have two strings.xml files in res > value like below:

One is for root (= No Language Dependency) and another one is for Bengali. We will add values to both of the strings file. If we want to add support for more languages, we can add more strings.xml file.

Note: For each entry in root strings.xml there should be corresponding translated value in each strings.xml. If we don’t want to translate, we can use translatable=“false” in root

strings.xml will be:

strings.xml (bn) will be:

7. Adding dynamic locale change Settings

Now, we are about the change the locale dynamically with a view like below. We will follow the Whatsapp locale change logic. In WhatsApp, there is two option available, the first one follows the phone language and the second one is the other available language. For the screenshot of below, the phone language is English, and the other available language is Bangla.

  1. Creating the xml file

To make it simple we will make the UI not so beautiful like the above image. The xml code for the UI:

2. Creating the activity

Remember? We have to extend BaseActivity!

3. Specify the activity in AndroidManifest.xml

We will add android:name=”.LocaleChangeActivity” with a new activity tag. By “…….” means there could be more properties or tags if you have any. After adding the new activity tag the resultant AndoirdManifest.xml will be:

8. Final Step! Changing the locale

Ugh! A very very long work! Now, we will test the code.

From anywhere we can get the updated localized text if we have context (or applicationContext)

🠗🠗 (Optional Step) If you want to use localization in Service 🠗🠗

Ugh!! There is still something missing for perfect solution! You can’t get the localized string in Service (if you have any) without restarting it. But restarting a service may be not possible sometimes. So, what to do?

Np. Here is the solution:

  1. Setup BaseService

We will override the onStartCommand method and update it’s baseContext according to localization. We will need to override the getResources method also only for below of Android Pie. So, after or in Android Pie, we will simply call it’s super.

2. Extend BaseService in each Service

We will now extend BaseService in every Services we have.

Note: we must call super when we override onStartCommand method as the logic of localization is defined in onStartCommand of BaseService.

3. Now, let’s use localization in Service

Now we can simply use getString in services as well like below:

The facility of the given mechanism:

  1. Production level code.
  2. Can be integrated into any design like MVVM.
  3. Bug-free and not hackish way like others on the Internet.
  4. Supported of getString() from Activity, Application and Service Context.
  5. No need to restart any Service.
  6. No need to change any old code if getString() is used, anywhere!

Thanks for reading!

Feel free to connect with my LinkedIn:

--

--

Tareq Rahman Joy
The Startup

Soft Dev Eng @Amazon, who loves to learn, explore and implement