Android is one of the few popular mobile operating systems having millions of users over 190 countries and growing day by day. So when you are aiming your app to be globally successful, it is always a good idea to make the app localised by supporting different languages.
While localising, you should consider using appropriate text, audio, currency, numbers and graphics depending upon the region or country. But this tutorial only covers localising strings i.e supporting multiple languages. Localizing with Resources explains about other things should be considered when localizing your app.
By default android considers English as primary language and loads the string resources from res ⇒ values ⇒ strings.xml. When you want to add support for another language, you need to create a values folder by appending an Hyphen and the ISO language code. For example if you want to add support for Russian, you should create a values folder named values-ru under res directory and keep a strings.xml file in it with all the strings translated into Russian language.
In brief the localization works as follows :
1. When user changes the device language through Settings ⇒ Language & Input, android OS itself checks for appropriate language resources in the app. (Let’s say user is selecting Russian)
or
If you don’t want to change language from settings then you have to create language options in your app and save that locale in Shared Preferences for future use. (This method will change language of your app only not whole device like above one.)
2. If the app supports selected language, android looks for it’s string resources in values-(ISO language Code) folder in the project. (For russian it loads the string values from values-ru/string.xml)
3. If the supported language strings.xml misses any string value, android always loads the missing strings from default strings.xml file i.e values/strings.xml
So it is mandatory that the default stings.xml file should contains all the string values that app uses. Other wise the app will crash with Force Close error.
Below are two things that you have to follow:
1. Never hard code the string in xml or in java code which make the translation difficult.
1 |
<TextView android:text="Hello World" /> |
1 |
textView.setText("Hello World"); |
2. While you are supporting multiple languages, you should consider below as a best practice while defining the strings. Always declare the string in strings.xml only.
1 |
<string name="hello">Hello World</string> |
When referring declared strings in xml, use @string notation.
1 |
<TextView android:text="@string/hello" /> |
When defining the string through java code, use R.string
1 |
textView.setText(R.string.hello); |
In this tutorial, we are going to build a Multi-Language (Multilingual) supported app that supports English, French, Deutsch (German), Hindi and Russian.
1. Create a new project in Android Studio by navigating to File ⇒ New ⇒ New Project and fill required details. By default my activity is MainActivity.java.
2. Open strings.xml located under res=>values folder and add following strings. These are default English language strings.
1 2 3 4 5 6 7 8 9 10 11 |
<resources> <string name="app_name">Multilingual Demo</string> <string name="tap_text">Select any language below :</string> <string name="btn_en">English</string> <string name="btn_ru">Russian</string> <string name="btn_de">German</string> <string name="btn_fr">French</string> <string name="btn_hi">Hindi</string> </resources> |
3. Now under res folder create three folders named values-de, values-fr, values-hi, values-ru and a strings.xml file in each of the folders.
Your project should look like this once you created the required files/folders.
Now translate the strings into their respected languages and place them in appropriate strings.xml files You can use Google Translator for strings conversion.
1 2 3 4 5 6 7 8 9 |
<resources> <string name="tap_text">नीचे दिए गए किसी भी भाषा का चयन करें :</string> <string name="btn_en">अंग्रेज़ी</string> <string name="btn_ru">रूसी</string> <string name="btn_de">जर्मन</string> <string name="btn_fr">फ्रेंच</string> <string name="btn_hi">हिंदी</string> </resources> |
1 2 3 4 5 6 7 8 9 |
<resources> <string name="tap_text">Выберите язык ниже :</string> <string name="btn_en">Английский</string> <string name="btn_ru">Русский</string> <string name="btn_de">Немецкий</string> <string name="btn_fr">Французский</string> <string name="btn_hi">хинди</string> </resources> |
1 2 3 4 5 6 7 8 9 10 |
<resources> <string name="tap_text">Wählen Sie eine beliebige Sprache im Handumdrehen:</string> <string name="btn_en">Englisch</string> <string name="btn_ru">Russisch</string> <string name="btn_de">Deutsch</string> <string name="btn_fr">Französisch</string> <string name="btn_hi">Hindi</string> </resources> |
1 2 3 4 5 6 7 8 9 |
<resources> <string name="tap_text">Sélectionnez une langue ci-dessous :</string> <string name="btn_en">Anglais</string> <string name="btn_ru">Russie</string> <string name="btn_de">Allemand</string> <string name="btn_fr">Français</string> <string name="btn_hi">Hindi</string> </resources> |
4. Now create a layout naming activity_main.xml and add the following code. In this there are several buttons for different language selection.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="#EEEEEE" android:padding="10dp"> <TextView android:text="@string/tap_text" android:textColor="#ff0000" android:textSize="18sp" android:id="@+id/choose_text" android:layout_gravity="center_horizontal" android:padding="5dp" android:layout_marginTop="5dp" android:layout_marginBottom="5dp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/english" android:text="@string/btn_en" android:textSize="14sp" android:layout_margin="3dp" android:background="#FAFAFA"/> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/hindi" android:text="@string/btn_hi" android:textSize="14sp" android:layout_margin="3dp" android:background="#FAFAFA"/> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/russian" android:text="@string/btn_ru" android:textSize="15sp" android:layout_margin="3dp" android:background="#FAFAFA"/> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/french" android:text="@string/btn_fr" android:textSize="14sp" android:layout_margin="3dp" android:background="#FAFAFA"/> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/german" android:text="@string/btn_de" android:textSize="14sp" android:layout_margin="3dp" android:background="#FAFAFA"/> </LinearLayout> |
5. Finally come to your MainActivity.java and add the following code. In this we are saving the selected language in SharedPreferences and loading saved language by refreshing texts.
The below method is important for changing selected language.
1 2 3 4 5 6 7 8 9 |
public void changeLocale(String lang) { if (lang.equalsIgnoreCase("")) return; Locale myLocale = new Locale(lang);//Set Selected Locale Locale.setDefault(myLocale);//set new locale as default Configuration config = new Configuration();//get Configuration config.locale = myLocale;//set config locale as selected locale getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());//Update the config } |
Full MainActivtiy.java Source Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
package com.multilingual_demo; import android.app.Activity; import android.content.SharedPreferences; import android.content.res.Configuration; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.TextView; import java.util.Locale; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private static Button english, hindi, french, german, russian; private static TextView chooseText; private static Locale myLocale; //Shared Preferences Variables private static final String Locale_Preference = "Locale Preference"; private static final String Locale_KeyValue = "Saved Locale"; private static SharedPreferences sharedPreferences; private static SharedPreferences.Editor editor; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initViews(); setListeners(); loadLocale(); } //Initiate all views private void initViews() { sharedPreferences = getSharedPreferences(Locale_Preference, Activity.MODE_PRIVATE); editor = sharedPreferences.edit(); chooseText = (TextView) findViewById(R.id.choose_text); english = (Button) findViewById(R.id.english); hindi = (Button) findViewById(R.id.hindi); french = (Button) findViewById(R.id.french); german = (Button) findViewById(R.id.german); russian = (Button) findViewById(R.id.russian); } //Set Click Listener private void setListeners() { english.setOnClickListener(this); hindi.setOnClickListener(this); french.setOnClickListener(this); german.setOnClickListener(this); russian.setOnClickListener(this); } @Override public void onClick(View view) { String lang = "en";//Default Language switch (view.getId()) { case R.id.english: lang = "en"; break; case R.id.hindi: lang = "hi"; break; case R.id.french: lang = "fr"; break; case R.id.german: lang = "de"; break; case R.id.russian: lang = "ru"; break; } changeLocale(lang);//Change Locale on selection basis } //Change Locale public void changeLocale(String lang) { if (lang.equalsIgnoreCase("")) return; myLocale = new Locale(lang);//Set Selected Locale saveLocale(lang);//Save the selected locale Locale.setDefault(myLocale);//set new locale as default Configuration config = new Configuration();//get Configuration config.locale = myLocale;//set config locale as selected locale getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());//Update the config updateTexts();//Update texts according to locale } //Save locale method in preferences public void saveLocale(String lang) { editor.putString(Locale_KeyValue, lang); editor.commit(); } //Get locale method in preferences public void loadLocale() { String language = sharedPreferences.getString(Locale_KeyValue, ""); changeLocale(language); } //Update text methods private void updateTexts() { chooseText.setText(R.string.tap_text); english.setText(R.string.btn_en); hindi.setText(R.string.btn_hi); russian.setText(R.string.btn_ru); french.setText(R.string.btn_fr); german.setText(R.string.btn_de); } } |
6. Finally, run the application and you will get the output as shown in video.
Thanks.
Subscribe to us and get the latest news.
26 Comments
byron
Tuesday, March 14th, 2017Dear Dr. Droid,
Thank you, thank you, THANK YOU for your amazing work! You just helped me a great deal. Pls kindly give directions on how to implement this in a project with more than one activity? Your help is much appreciated. Thanks again.
Dr. Droid
Tuesday, March 14th, 2017Hi Byron,
To implement the string localisation in whole app/project you need to re-start the app again. Like a button in your app is changing language then on your button click you need to call below method:
Intent i = new Intent(Your_Activity.this, Splash.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
finish();
Thanks
byron
Wednesday, March 15th, 2017Dear Dr. Droid,
Thanks for your quick reply. I am assuming that “splash.class” is just an example? Also, can i put your new code inside your “changeLocale” method? it will look something like this;
public void changeLocale(String lang) {
if (lang.equalsIgnoreCase(“”))
return;
myLocale = new Locale(lang);//Set Selected Locale
saveLocale(lang);//Save the selected locale
Locale.setDefault(myLocale);//set new locale as default
Configuration config = new Configuration();//get Configuration
config.locale = myLocale;//set config locale as selected locale
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
updateTexts();//Update texts according to locale
Intent i = new Intent(Your_Activity.this, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
finish();
}
Also, what about extending your mainactivity from other activities?
i tried it when i added a second activity to your project, and it seemed to work well. is it safe to do this?
I ask because in my project, most of the activities are using different color themes. if it will work, perhaps i can make your project a “settings” page and extend it from other activities? Thanks again, Dr. Droid, for your valued help.
Dr. Droid
Wednesday, March 15th, 2017Hi Byron,
Below are the answers of your queries:
1. I am assuming that “splash.class” is just an example? – YES
2. Do not call this updateTexts(); method because as you are restarting app so this method no more required to call.
3. i added a second activity to your project, and it seemed to work well. is it safe to do this? – YES
4. In manifest you can change the theme of my project activity if it is not matching with yours.
Thanks
Rupin Sahu
Friday, July 28th, 2017Hi Dr. Droid, it was great to see your knowledge on Android. I need your help as I am preparing a project and I am also a freelancer and very keen to learn new things. In my project I want multilingual feature but as you said that there is another method without android localisation means I do not want to change the language from device’s settings so I want to try your alternate method as you defined in your point no. 1. So how could it be done and what will be the code? Please help me.
Samir
Sunday, August 27th, 2017hello
how are ?
how to implement this in a project with more than one activity?
if we use 3 activity
Samir
Sunday, August 27th, 2017and what we need to work for all activity this change
Dr. Droid
Sunday, August 27th, 2017Hi Samir,
You have to use this changeLocale(String lang) method to update the language of your app. This method you need to put into your first activity like your SplashActivity or your MainActivity rest android will handle itself to show particular changed language.
Thanks
Samir
Sunday, August 27th, 2017very thanks my bro to answer me
if send me to i put with first activity
thanks
Samir
Sunday, August 27th, 2017if upload code for me my bro is very good
to all activity i want use for some activity
thanks
Dr. Droid
Sunday, August 27th, 2017Hi Samir,
Put the below code to your starting activity and call it onCreate method. You need to pass a locale(language) that you want to change to this method and also create a shared preference so that whenever you start your app again it will pick the saved locale.
//Change Locale
public void changeLocale(String lang) {
if (lang.equalsIgnoreCase(“”))
return;
myLocale = new Locale(lang);//Set Selected Locale
saveLocale(lang);//Save the selected locale
Locale.setDefault(myLocale);//set new locale as default
Configuration config = new Configuration();//get Configuration
config.locale = myLocale;//set config locale as selected locale
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());//Update the config
updateTexts();//Update texts according to locale
}
Try this, if you face any issue let me know.
Thanks
Samir
Sunday, August 27th, 2017my bro i’m very try not succeeded
if make for me and send very thanks
Dr. Droid
Sunday, August 27th, 2017Hi Samir,
Can you share your code with me or can you connect with me via TeamViewer so that i can help you properly.
My email id is at my blog.
Thanks
Samir
Sunday, August 27th, 2017Hi
my bro tomorrow i send my code for you
paresh
Wednesday, November 8th, 2017brother, i got your locale, and know the concept of Typeface, but i am not suceeding with Marathi language or Hindi language printing through android bluetooth printing, can you help me please
Dr. Droid
Wednesday, November 8th, 2017Hi Paresh,
The problem of not printing Hindi or Marathi language can be that the printing device is not supporting those languages.
If that is not the case then let me know how i can help you.
Thanks
Abhijit Lenka
Tuesday, July 31st, 2018Hi Sonu,
I need your help urgently. I have the issue with language again set back to default upon exiting the app.
Thanks
Abhijit Lenka
mail_to:[email protected]
Dr. Droid
Tuesday, July 31st, 2018Hi Abhijit,
Can you tell me what exactly you are doing and if possible share your code where you are facing issue.
Thanks
Omkar Kamate
Wednesday, August 8th, 2018I am not getting how can I use this for multiple activities. Can u modify my project and show me
Dr. Droid
Wednesday, August 8th, 2018Hi Omkar,
You have to use changeLocale and loadLocale method in your splash or launching activity and changeLocale and save locale inside your changing locale activity. Once you change the locale restart your app to see the effects.
Thanks
Ansa
Monday, December 24th, 2018english.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent i = new Intent(MainActivity.this, Main2Activity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
finish();
}
}); set the second activity on onclicklistner of english button but language of second activity doesnt change.Please help
Farahnaz Reza
Monday, January 21st, 2019Whenever i insert this code in my project i get the following error Binary XML file line #130: Binary XML file line #130: You must supply a layout_width attribute. and the app crashes. Can you please help me debug.?
mispruebas
Saturday, April 27th, 2019Hello friends, thanks for the contribution, very good tutorial, I have a problem, when I select the button for the change of language, the application changes the language without problems, but the action bar title of the open activity did not change. Can you help me with that?
for the moment I used a restartActiviti ();
thanks greetings!!
Dr. Droid
Sunday, April 28th, 2019Hi Mispruebas,
You have to restart your application to see the changes in whole app.
Thanks
Dheenadhayalan
Thursday, February 13th, 2020Its working on one app . i used same code but that app is not working
Dr. Droid
Friday, February 14th, 2020Hi Dheenadhayalan,
Can you check your code once again and check if anything you missed?
And also can you check if you are getting any error logs?
Thanks