As a platform, Android devices are now multilingual “out of the box.” In theory, you can target practically any country, region, or culture in the world with your app. However, your developer conscience is already whispering to you that diving in just anyhow to make versions for every local language under the sun might not be such a bright idea. But with the right approach to app localization, the world is your oyster.
First Make Your Internationalization-Localization Plan
What you need first is a plan, often best drawn up with your colleagues in the marketing department. In general, such a plan looks like this:
- Decide which countries and languages your app will support, and in which order of priority. This will depend on factors like the sales potential for your app and any commitments you have already made to customers or business partners.
- Internationalize your app by removing any language dependencies from it, moving content such as text and images out to separate files, and using specific functions to handle different international display formats. This step, when done properly, will require the most of your time and effort.
- Proceed with app localization via the translation of the separate content files from step two, via in-house translators (if you have them) or by using professional translation services. As a developer, your role is to then include the translated content in the app and make sure it displays properly.
Getting Started with Internationalization
Start by identifying the different items in your app, which will need to be internationalized.
- Text strings, images, and audio files are natural candidates.
- Time, date, number, and financial formats, which change as users switch from one language to another, will also need attention.
- New lengths of text may need to be supported. Compared to English, for instance, equivalent phrases in other languages may be 30% longer (certain European languages, for instance) or 50% shorter (some Asian languages, for example.) This may alter screen layout and display requirements.
- Text direction may change. Whereas the direction of English is from left to right, other languages like Arabic and Hebrew are read from right to left.
Android Functionality to Help You
Android already has some built-in internationalization (“i18n” for short) features. The creation of a new Android project using Google’s Android SDK tools will trigger the generation of files needed for app localization. A /res/ directory is created at the top level of the project, containing default files such as res/values/strings.xml for storing string resources separately, instead of hardcoding them into your app. Eclipse, the integrated development environment (IDE) for Android, offers a function (under “Refactor”) to make it easier to move localization-dependent text into separate .xml files for app localization. Android also offers classes and methods to handle internationalization of quantities, dates, number, and so on.
Understanding and Handling Locales
Internationalization (“i18n”), the step before localization (“l10n”), uses three concepts: country, language, and locale. A locale, in its most general sense, represents a geographical, political, or cultural region. It can also be viewed as a combination of a country and a language. Thus, US English and UK English are two different locales. Although American and British people both speak English, some formats and vocabulary are locale-sensitive. That means that operations using the date for example must adapt to the locale of the user, as the American date format is month/day/year, but the British format is day/month/year. Other examples of locale-sensitive operations include number formatting: the English format differs from the French, which is in turn different from German, and so on.
Using Resources for App Localization
Resources to be localized include text strings, graphics and images, sounds, layouts, and any other static data used by your Android application. There may be multiple sets of resources, each one corresponding to a specific device configuration. In general, when an app runs, Android automatically loads the resources that best match the device. The same system is used for the locale of the device, which can be modified at any time by the user. Android then selects the most suitable resources for that locale.
The starting point for each app localization is to create specific directories within res/ for each locale (country-language combination) to be supported. For text string resources, the name of each directory uses the format “values-<ISO language code>”. So, for instance, res/values-fr/ contains the strings for French in the file at the location res/values-fr/strings.xml. Locale-specific versions of graphics and layout will then go into res/drawable-<qualifiers>/ and res/layout-<qualifiers>/ folders. To access locale-dependent resources from the Java code of your application you use a reference of the time “R.resource_type.resource_name” or “android.R.resource_type.resource_name”.
Defining Default Resources
The default locale version of app resources is what Android uses, when there is no other version of the app resources for the locale in question. By default, resources for an app exist within the “res/” directory for that application. Localized sets of resources (corresponding to other locales) are placed in other appropriately named subdirectories of the res/ directory (see above.) When a user running Android with a different locale loads your app, Android checks these subdirectories to see if there is one for that locale. If so, the content from that subdirectory will be displayed. Otherwise, Android will either try other related subdirectories or display the default content.
It makes sense to define the default language of your app to be the language you expect most of your application’s users to use. For example, if you are a developer in the US or working for a company in the US, the default language for your app may be US English. Besides storing default text (in the default language) in res/values/strings.xml, put any default text, drawables (graphics), layouts, and other resources into the default resource set as well, using the following subdirectories:
- res/drawable/ (required subdirectory, usually containing at least one graphic file for the icon for the application on Google Play)
- res/layout/ (required subdirectory, containing an XML file to define the default layout)
- res/anim/ (required if the app has any res/anim-<qualifiers> folders)
- res/xml/ (required if the app has any res/xml-<qualifiers> folders)
- res/raw/ (required if the app has any res/raw-<qualifiers> folders)
What Happens if Resource Files are Incomplete?
If a user chooses a locale for which locale-specific resources are lacking in your app, Android will load the corresponding default resources: for example, the default strings from res/values/strings.xml. If the resource does not exist in a default version, the application will not run and the user will see an error.
Consider the following example. An application uses two text strings, A and B, that have been defined in English for a localized resource file, res/values-en/strings.xml. On the other hand, only text string A has been defined in the default resource file of res/values/strings.xml. If the application is launched on a device configured with its locale set to English, it should run correctly, because both text strings can be accessed. However, if the locale is changed to Spanish, the application will not load. After failing to find text string B in the default resource file, it will generate an error message and a Force Close button.
Check Resources for Completeness
The situation above applies to all resources, not just text strings. It is good practice, therefore, to check that a default resource is defined for each reference in an app to an Android resource. Localized resource string files could theoretically be incomplete, because the default value of a string would be available to prevent the app from displaying an error. However, partial app localizations often make for poor usability and bad impressions. Therefore, any localized resource files should be complete as well, or kept separately from the application until they can provide a completely localized user experience.
Cascading Through Locale and Language Resource Files
Localized resources are placed in folders, whose qualifiers reflect the language and possibly the locale of the localization. The folder name format is “values-<language>” or “values-<language-region code>”.
- “Language” in this instance is the language ISO code, such as “fr” for French
- “Region code” is the optional region code, preceded by “r” (lowercase r), for example: fr-rFR for French used in France, or fr-rCA for Canadian French.
Android selects the resource files required by the application when it is launched, based on the device’s locale. If there are no locale-specific resources, the next level of resources will be checked, and finally the default resources used, if not other suitable resources exist.
For example, suppose the locale is Swiss French, but no “fr-rCH” folder or resources (no res/values-fr-rCH/strings.xml, etc.) exist. Android will then check the “fr” folder (res/values-fr/strings.xml, etc.), and finally the default folder if required (res/values/strings.xml) to obtain a version of the resources for display.
Avoid Hardcoding of Text or Other Resources
Placing text resources in your default strings.xml file from the beginning avoids the difficulties associated with hardcoding them in your app. Use of the strings.xml file greatly facilitates modification, updating, and app localization. It also means that translated versions (from appropriate subdirectories) can be used without having to recompile your app’s code. Text used in the generation of images should be placed in the strings.xml file for the same reason. Localized images will then be generated correctly in the same way.
Making Strings.xml Understandable to Translators
Remember that translators producing localized texts may only see your strings.xml file without knowing as much about your app and its purpose as you do. Therefore, think ahead and include information on the context of each string in the strings.xml file. This is especially important for short texts used for buttons for instance, where one word like “clear” in English could correspond to two completely different words in another language (“clear” as in “transparent”, or as in “delete”). Contextual information can even help you be more efficient in managing your text strings, when you come back to them later after working on other projects.
Indicating Content that is not to be Translated
Strings may also contain text that should not be translated, such as code, value placeholders, special symbols, or proper nouns. These texts must be indicated to translators, so that they are not changed. To do this, mark such text using an <xliff:g> tag, as the following example shows. Note the use of the id attribute to explain to readers the purpose of the placeholder and the example attribute to show how the string using the placeholder will be displayed.
<xliff:g id="quantity" example="4 widgets">%1$s</xliff:g>in stock
Using Java and Formatters
If your app uses dates, times, numbers, currencies or other locale-dependent parameters, use the Android system to provide correct locale-specific formats. Like text strings, any attempts to hardcode the use of these entities will necessarily make an assumption about the locale, rapidly leading to problems when users change their Android devices to other locales. Even small flaws in versions for other locales can leave users with a poor impression of your app, depressing sales and adoption rates. For example, where the English format for numbers uses a period (.) as a decimal separator, French format uses a comma (,), but the difference is immediately obvious to native users when the wrong separator is displayed.
Android offers several utilities to help you format correctly across locales, such as:
- DateUtils and DateFormat for dates
- String.format() or DecimalFormat for numbers and currency
- PhoneNumberUtils for phone numbers
Android Assistance in Localizing Plurals
Locale-specific use of plurals can be complex too. Consider the basic rule in English, which is to use the singular with a quantity of one (“1 product”) and the plural with other quantities (“n products”, including “0 products”.) Other languages define more cases and have more rules. For example, Russian has specific plural formats for not just “one” and “other” as in English, but also for “few” and “many”, giving a total of four different formats. The full set of plural formats supported by Android is zero, one, two, few, many, and other. The Android method “getQuantityString()” cuts through the complexity to select the plural format to be used for a given language/locale and a given quantity.
Handling Screen Layouts
In general, the less layouts you have to handle, the better. A single, responsive design that adapts automatically to different devices makes life simpler. However, there may be cases where a user interface cannot properly display text for your Android app localization. A simple example would be a short label or menu item with the word “Now” in a default version using English, where the equivalent word in French would be “Maintenant” (more than three times as long.) One option is to create an alternative layout for that special case and store it in the location with the corresponding resource qualifier. On the other hand, this is an additional resource to manage, check, and update as appropriate for future versions of your app.
Other situations affecting screen layouts include forms for user input with a different number of name fields, depending on the user’s language. Instead of defining a completely new layout, one option might be to include a field to be displayed or not by the code, according to the language being used. Another could be to have the main layout include a secondary layout with the language-dependent field.
Keep Resource Files to a Reasonable Minimum
For reasons of effort required and manageability, it makes sense to minimize the amount of resource files being used. The condition is, of course, that this does not degrade the user experience. In the example above of the form for user input, it may not be necessary to create a completely new layout. In other cases, just one layout defined in the res/layout/main.xml file may suffice for any locale.
Similar remarks apply to text strings. While a user should always see a completely localized version, it is possible that some regional variations overlap to a great extent. For example, American and British English have some differences, but in many other cases, they are identical. An app could use American English as its default language, with American English vocabulary in the res/values/strings.xml file. For certain phrases for which British English vocabulary is important for British app users, a smaller file can be created (res/values-en-rGB/strings.xml), containing only those strings that differ. For any other strings, the application will default back to the res/values/strings.xml file and (identical) American English equivalents.
Getting Files Translated
You determine the quality of your strings.xml file, including its accuracy, its organization, and any necessary explanations for translators. Automated translation software is unlikely to give sufficiently good results, because your explanations cannot be understood (remember our example above about the different possibilities for translating the word “clear”.) However, for human translators, explanations can help avoid many queries or misunderstandings. It may be a good idea to add a terminology list to the translator’s package to explain specific terms or jargon used in your app, so that translators do not have to guess.
App Store Keywords
Remember to have your app description translated for app stores like Google Play. On the other hand, keywords for helping users to find your app and for promoting its use or sales are another matter. Keywords are not only language dependent, but also market dependent. It may make more sense to work with an SEO professional for the country or the market concerned, who will find the most effective keywords in that context. These may be different from translated versions of the keywords used in the default language version (however good the translations are.)
When the localized files are returned to you, check the translations to make sure that all relevant content has been translated, and that any other content (not to be translated) has been left intact. If the files pass this preliminary check, move the localized directories and files back into the resource structure for your app, using the right language and locale qualifiers to ensure proper loading afterwards, according to the locale selected.
Now test your application for each locale to be supported, checking for correct management of the following items among others:
- Formatting of dynamic text, such as numbers and dates
- Handling of word breaks, punctuation, and alphabetical sorting
- Fallbacks to default resources
- Display in landscape and portrait modes.
Where possible, and highly recommended in any case, have a native speaker for the locale review the application thoroughly and give feedback.
Pseudolocalization as a Further Check
Use pseudolocalization to check layouts and displays, for example by generating a version of strings.xml with text for resources that is deliberately nonsensical and/or that is twice as long as the default text. These pseudolocalization techniques make it easier to see if any strings have been missed in the app localization (these are the strings that are still displayed normally.) They can also help to see if any localized texts are likely to run out of space in constrained areas like buttons, titles, and labels.
App Store Considerations
When all necessary checks have been successfully made, it is time to sign your app, make your final build, and then make your localized app available to users. In Google Play for instance:
- Select the languages for your localized app.
- Upload your .apk file.
- Add translations for the Store Listing page and AdWords campaigns. If a user’s language preference matches a language you have selected, the user will then see the translated version of your app. Add localized versions of any promotional graphics and videos too. If necessary, you can create different versions for different locales, linking to the relevant localized video for each language supported by the app.
Afterwards, Rinse and Repeat for New Localizations
The big benefit of correctly internationalizing an app is that each app localization is then relatively simple to do. You get the resource files translated for the new language or locale, check them, and include them in the app in an appropriately named folder (and update the app listing information in the app store.) Internationalization and localization techniques can also go further. One example is greater sophistication in the way Android selects the best resource folder for a locale that has not yet been handled as part of the app localization. Nonetheless, this guide already gives you basic information you should know concerning internationalization and localization of Android apps. With the growing international market for Android solutions, we wish you success in satisfying users in the markets of your choice.
Also published on Medium.