Android is one of the most popular operating system runs on many devices in many regions and growing day by day. When you want your app to support wider audience ,it is always a good idea to make the app localized.To reach the most users, your app should handle text, audio files, numbers, currency, and graphics in ways appropriate to the locales where your app is used.
But this tutorial only covers localizing strings i.e supporting multiple languages.Language plays a crucial role in the overall interface of the app and it is great if you can append more languages to it to make your app globally successful.
In this article we are going to build a Multi-Language supported app that supports French, Dutch, Hindi and Japanese.
How String Localization Works
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 French, you should create a values folder named values-fr and keep a strings.xml file in it with all the strings translated into French 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 French)
2. If the app supports selected language, android looks for it’s string resources in values-(ISO language Code) folder in the project. (For french it loads the string values from values-fr/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.
How to use string in xml and in java code
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.
<string name="personal_info">Personal Information</string>
When referring it in xml, use @strings notation.
<TextView ...
android:text="@string/personal_information">
When defining the string through java code, use R.string
personalInfo.setText(R.string.personal_info);
Creating New Project
1. Create a new project in Android Studio from File ⇒ New Project by filling the required details. When it prompts you to select the activity, choose Empty Activity and continue.
2. Under drawable folder create one file named btn_background.xml with following contents. These files are not related to language support, but just to give nice rounded corners to buttons.
btn_background.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="@android:color/holo_orange_light" />
<stroke android:width="1dp" android:color="#ff3340" />
<corners android:radius="5dp" />
</shape>
</item>
</selector>
3. Open strings.xml located under values folder and add following strings. These are default English language strings.
strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">MultilingualApp</string>
<string name="personal_information">Personal Information</string>
<string name="name">Name</string>
<string name="gender">Gender</string>
<string name="date_of_birth">DateOfBirth</string>
<string name="country">Country</string>
<string name="city">City</string>
<string name="phone_number">Phone Number</string>
<string name="email">Email</string>
<string name="send">SEND</string>
</resources>
4. Now under res folder create four folders named values-nl, values-fr, values-hi, values-ja 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 respected languages and place them in appropriate strings.xml files as shown below:
- French values-fr/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="personal_information">Informations personnelles</string>
<string name="name">prénom</string>
<string name="gender">le genre </string>
<string name="date_of_birth">date de naissance</string>
<string name="country">pays </string>
<string name="city">ville</string>
<string name="phone_number">numéro de telephone</string>
<string name="email">email</string>
<string name="send">envoyer</string>
</resources>
- Hindi values-hi/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="personal_information">व्यक्तिगत जानकारी </string>
<string name="name">नाम </string>
<string name="gender">लिंग </string>
<string name="date_of_birth">जन्म की तारीख </string>
<string name="country">देश </string>
<string name="city">शहर </string>
<string name="phone_number">फ़ोन नंबर </string>
<string name="email">ईमेल </string>
<string name="send">भेजें</string>
</resources>
- Japanese values-ja/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="personal_information">個人情報</string>
<string name="name">名</string>
<string name="gender">性別 </string>
<string name="date_of_birth">生年月日</string>
<string name="country">国 </string>
<string name="city">シティ</string>
<string name="phone_number">電話番号</string>
<string name="email">Eメール</string>
<string name="send">送信する</string>
</resources>
- Dutch values-nl/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="personal_information">Persoonlijke informative</string>
<string name="name">naam</string>
<string name="gender">geslacht </string>
<string name="date_of_birth">geboortedatum</string>
<string name="country">land </string>
<string name="city">stad</string>
<string name="phone_number">telefoonnummer</string>
<string name="email">e-mail</string>
<string name="send">sturen</string>
</resources>
5. Open your activity_main.xml and add the following content to create a simple layout.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:id="@+id/tv_personal_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="18dp"
android:text="@string/personal_information"
android:textColor="@android:color/holo_orange_dark"
android:textSize="20sp"
android:textStyle="bold"
/>
<EditText
android:id="@+id/et_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="@android:color/white"
android:fontFamily="sans-serif"
android:hint="@string/name"
android:inputType="text"
android:maxLines="1"
android:padding="16dp"
android:textColor="@android:color/black"
android:textColorHint="@color/hint_color"
android:textSize="14sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:orientation="horizontal">
<EditText
android:id="@+id/et_gender"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@android:color/white"
android:fontFamily="sans-serif"
android:hint="@string/gender"
android:maxLines="1"
android:padding="16dp"
android:textColor="@android:color/black"
android:textColorHint="@color/hint_color"
android:textSize="14sp" />
<EditText
android:id="@+id/et_dob"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_weight="1"
android:background="@android:color/white"
android:fontFamily="sans-serif"
android:hint="@string/date_of_birth"
android:maxLines="1"
android:padding="16dp"
android:textColor="@android:color/black"
android:textColorHint="@color/hint_color"
android:textSize="14sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:orientation="horizontal">
<EditText
android:id="@+id/et_country"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@android:color/white"
android:fontFamily="sans-serif"
android:hint="@string/country"
android:maxLines="1"
android:padding="16dp"
android:textColor="@android:color/black"
android:textColorHint="@color/hint_color"
android:textSize="14sp" />
<EditText
android:id="@+id/et_city"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_weight="1"
android:background="@android:color/white"
android:fontFamily="sans-serif"
android:hint="@string/city"
android:maxLines="1"
android:padding="16dp"
android:textColor="@android:color/black"
android:textColorHint="@color/hint_color"
android:textSize="14sp" />
</LinearLayout>
<EditText
android:id="@+id/et_phone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:background="@android:color/white"
android:fontFamily="sans-serif"
android:hint="@string/phone_number"
android:inputType="phone"
android:maxLines="1"
android:padding="16dp"
android:textColor="@android:color/black"
android:textColorHint="@color/hint_color"
android:textSize="14sp"
/>
<EditText
android:id="@+id/et_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:background="@android:color/white"
android:fontFamily="sans-serif"
android:hint="@string/email"
android:inputType="textEmailAddress"
android:maxLines="1"
android:padding="16dp"
android:textColor="@android:color/black"
android:textColorHint="@color/hint_color"
android:textSize="14sp"
/>
<Button
android:id="@+id/btn_send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="18dp"
android:background="@drawable/btn_background"
android:text="@string/send"
android:textColor="@android:color/white"
android:textSize="14sp"
android:textStyle="bold" />
</LinearLayout>
6. Open your MainActivity.java and make sure that it has following code. This code will be added automatically when you create new project.
MainActivity.java
package com.c1ctech.multilingualapp;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
Now if you run the project you should see the app in English (assuming that your device is set to English language)

Testing Other Languages
In order to see the app in other languages follow below steps .
1. On the device go to Settings ⇒ Language & Input
2. Select the Language and choose the language that you supported in the app.
MultilingualApp using French
MultilingualApp using Hindi
Android Localization Language ISO Codes
Below table give you ISO languages codes for all the languages that android supports.
Locale Name | locale code | variant (country) | values folder name |
Afrikaans | af | values-af | |
Aghem | agq | values-agq | |
Akan | ak | values-ak | |
Amharic | am | values-am | |
Arabic | ar | values-ar | |
Assamese | as | values-as | |
Asu | asa | values-asa | |
Azerbaijani | az | values-az | |
Basaa | bas | values-bas | |
Belarusian | be | values-be | |
Bemba | bem | values-bem | |
Bena | bez | values-bez | |
Bulgarian | bg | values-bg | |
Bambara | bm | values-bm | |
Bengali | bn | values-bn | |
Tibetan | bo | values-bo | |
Breton | br | values-br | |
Bodo | brx | values-brx | |
Bosnian | bs | values-bs | |
Catalan | ca | values-ca | |
Chiga | cgg | values-cgg | |
Cherokee | chr | values-chr | |
Czech | cs | values-cs | |
Welsh | cy | values-cy | |
Danish | da | values-da | |
Taita | dav | values-dav | |
German | de | values-de | |
Zarma | dje | values-dje | |
Duala | dua | values-dua | |
Jola-Fonyi | dyo | values-dyo | |
Dzongkha | dz | values-dz | |
Embu | ebu | values-ebu | |
Ewe | ee | values-ee | |
Greek | el | values-el | |
English | en | values-en | |
Esperanto | eo | values-eo | |
Spanish | es | values-es | |
Estonian | et | values-et | |
Estonian (Estonia) | et | EE | values-et-rEE |
Basque | eu | values-eu | |
Basque (Spain) | eu | ES | values-eu-rES |
Ewondo | ewo | values-ewo | |
Ewondo (Cameroon) | ewo | CM | values-ewo-rCM |
Persian | fa | values-fa | |
Persian (Afghanistan) | fa | AF | values-fa-rAF |
Persian (Iran) | fa | IR | values-fa-rIR |
Fulah | ff | values-ff | |
Fulah (Senegal) | ff | SN | values-ff-rSN |
Finnish | fi | values-fi | |
Finnish (Finland) | fi | FI | values-fi-rFI |
Filipino | fil | values-fil | |
Filipino (Philippines) | fil | PH | values-fil-rPH |
Faroese | fo | values-fo | |
Faroese (Faroe Islands) | fo | FO | values-fo-rFO |
French | fr | values-fr | |
Irish | ga | values-ga | |
Irish (Ireland) | ga | IE | values-ga-rIE |
Galician | gl | values-gl | |
Galician (Spain) | gl | ES | values-gl-rES |
Swiss German | gsw | values-gsw | |
Swiss German (Switzerland) | gsw | CH | values-gsw-rCH |
Swiss German (Liechtenstein) | gsw | LI | values-gsw-rLI |
Gujarati | gu | values-gu | |
Gujarati (India) | gu | IN | values-gu-rIN |
Gusii | guz | values-guz | |
Gusii (Kenya) | guz | KE | values-guz-rKE |
Manx | gv | values-gv | |
Manx (Isle of Man) | gv | IM | values-gv-rIM |
Hausa | ha | values-ha | |
Hawaiian | haw | values-haw | |
Hawaiian (United States) | haw | US | values-haw-rUS |
Hebrew | iw | values-iw | |
Hebrew (Israel) | iw | IL | values-iw-rIL |
Hindi | hi | values-hi | |
Hindi (India) | hi | IN | values-hi-rIN |
Croatian | hr | values-hr | |
Croatian (Bosnia and Herzegovina) | hr | BA | values-hr-rBA |
Croatian (Croatia) | hr | HR | values-hr-rHR |
Hungarian | hu | values-hu | |
Hungarian (Hungary) | hu | HU | values-hu-rHU |
Armenian | hy | values-hy | |
Armenian (Armenia) | hy | AM | values-hy-rAM |
Indonesian | in | values-in | |
Indonesian (Indonesia) | in | ID | values-in-rID |
Igbo | ig | values-ig | |
Igbo (Nigeria) | ig | NG | values-ig-rNG |
Sichuan Yi | ii | values-ii | |
Sichuan Yi (China) | ii | CN | values-ii-rCN |
Icelandic | is | values-is | |
Icelandic (Iceland) | is | IS | values-is-rIS |
Italian | it | values-it | |
Italian (Switzerland) | it | CH | values-it-rCH |
Italian (Italy) | it | IT | values-it-rIT |
Italian (San Marino) | it | SM | values-it-rSM |
Japanese | ja | values-ja | |
Japanese (Japan) | ja | JP | values-ja-rJP |
Ngomba | jgo | values-jgo | |
Kako | kkj | values-kkj | |
Kako (Cameroon) | kkj | CM | values-kkj-rCM |
Kalaallisut | kl | values-kl | |
Kalaallisut (Greenland) | kl | GL | values-kl-rGL |
Kalenjin | kln | values-kln | |
Kalenjin (Kenya) | kln | KE | values-kln-rKE |
Khmer | km | values-km | |
Khmer (Cambodia) | km | KH | values-km-rKH |
Kannada | kn | values-kn | |
Kannada (India) | kn | IN | values-kn-rIN |
Korean | ko | values-ko | |
Korean (North Korea) | ko | KP | values-ko-rKP |
Korean (South Korea) | ko | KR | values-ko-rKR |
Konkani | kok | values-kok | |
Konkani (India) | kok | IN | values-kok-rIN |
Kashmiri | ks | values-ks | |
Kashmiri (Arabic) | ks | values-ks-r_#Arab | |
Kashmiri (Arabic,India) | ks | IN | values-ks-rIN_#Arab |
Nepali | ne | values-ne | |
Nepali (India) | ne | IN | values-ne-rIN |
Nepali (Nepal) | ne | NP | values-ne-rNP |
Dutch | nl | values-nl | |
Dutch (Aruba) | nl | AW | values-nl-rAW |
Kwasio | nmg | values-nmg | |
Kwasio (Cameroon) | nmg | CM | values-nmg-rCM |
Norwegian Nynorsk | nn | values-nn | |
Norwegian Nynorsk (Norway) | nn | NO | values-nn-rNO |
Ngiemboon | nnh | values-nnh | |
Ngiemboon (Cameroon) | nnh | CM | values-nnh-rCM |
Nuer | nus | values-nus | |
Nuer (Sudan) | nus | SD | values-nus-rSD |
Nyankole | nyn | values-nyn | |
Nyankole (Uganda) | nyn | UG | values-nyn-rUG |
Oromo | om | values-om | |
Oromo (Ethiopia) | om | ET | values-om-rET |
Oromo (Kenya) | om | KE | values-om-rKE |
Oriya | or | values-or | |
Oriya (India) | or | IN | values-or-rIN |
Punjabi | pa | values-pa | |
Polish | pl | values-pl | |
Polish (Poland) | pl | PL | values-pl-rPL |
Pashto | ps | values-ps | |
Pashto (Afghanistan) | ps | AF | values-ps-rAF |
Portuguese | pt | values-pt | |
Romansh | rm | values-rm | |
Romansh (Switzerland) | rm | CH | values-rm-rCH |
Rundi | rn | values-rn | |
Rundi (Burundi) | rn | BI | values-rn-rBI |
Romanian | ro | values-ro | |
Romanian (Moldova) | ro | MD | values-ro-rMD |
Romanian (Romania) | ro | RO | values-ro-rRO |
Rombo | rof | values-rof | |
Rombo (Tanzania) | rof | TZ | values-rof-rTZ |
Russian | ru | values-ru | |
Kinyarwanda | rw | values-rw | |
Kinyarwanda (Rwanda) | rw | RW | values-rw-rRW |
Rwa | rwk | values-rwk | |
Rwa (Tanzania) | rwk | TZ | values-rwk-rTZ |
Samburu | saq | values-saq | |
Samburu (Kenya) | saq | KE | values-saq-rKE |
Sangu | sbp | values-sbp | |
Sangu (Tanzania) | sbp | TZ | values-sbp-rTZ |
Shona | sn | values-sn | |
Shona (Zimbabwe) | sn | ZW | values-sn-rZW |
Somali | so | values-so | |
Albanian | sq | values-sq | |
Serbian | sr | values-sr | |
Swedish | sv | values-sv | |
Swahili | sw | values-sw | |
Congo Swahili | swc | values-swc | |
Congo Swahili (Congo (DRC)) | swc | CD | values-swc-rCD |
Tamil | ta | values-ta | |
Telugu | te | values-te | |
Urdu | ur | values-ur | |
Uzbek | uz | values-uz | |
Vai | vai | values-vai | |
Vietnamese | vi | values-vi | |
Vietnamese (Vietnam) | vi | VN | values-vi-rVN |
Vunjo | vun | values-vun | |
Chinese | zh | values-zh | |
Zulu | zu | values-zu | |
Zulu (South Africa) | zu | ZA | values-zu-rZA |
You can also get more language related ISO codes from here.
Note : Right now I used Google Translate service to translate the strings into other languages.
I hope this tutorial is helpful for you in understanding how to build MultiLanguage supported app.