Thursday, 29 September 2011

Android: Localizing your Android app - Part 1

Nowadays one could think that everybody speaks English so your English-only app is probably good enough.
Well, localizing software is not just about translating, there are several cultural and behavioral aspects you have to consider.
The Android framework brilliantly provides us with several resources to make our apps shine anywhere in the world.

As I said, depending on the app, we need more than just translating to make it localized. A financial app definitely wants to use the correct currency and number formatting of the targeted country/culture.

That said, today we will start small: learning how to write our apps so it can be easily translated to other languages.

1) Using string resources
One  of the first things we learn (or should have learned) in computer programming is to never leave hardcoded strings (text) lying around in the code. That, by the way, is a code smell and it's why we make constants.

However when we're talking translation of text to another languages, the simple use of constants is not useful anymore.
We need to put ALL strings/text that will be DISPLAYED to the user in a separate place. The Android solution for that is the use of string resources.

By default, a file called strings.xml is created by Eclipse under res/values/ and it looks somewhat like this:

<xml version="1.0" encoding="utf-8">
    <string name="app_title">Test app</string>

Eclipse has a nice editor to help you edit and add more strings but you'll find that editing the XML directly is more efficient. So to add a new string (anything you want to localize), just add a new string node setting the attribute name to something you know to be unique.

The name is how we refer to that string in our app. For instance, if my title of the application is displayed in a TextView sitting on the activity's layout like

<TextView android:text="Test app"

the "localizable" version of the TextView would look like

<TextView android:text="@string/app_title"

by referring to the content using @string we are telling the framework to find the string resource where name=app_title and use it as text for the TextView.

Tips when working with string resources:
  1. use them even if you're not planning to translate your app;
  2. the default file is called strings.xml but what really matters is the xml tags so you can name your string resource files the way you find more appropriate;
  3. if your app has several activities and/or fragments, it's probably a good idea to create multiple string resource files;
  4. name (remember name="..." attribute?) the strings as if you're naming variables: you'll need to refer to them quite often.
  5. you can use xml tags in your string resource files and the framework will automatically interpreted them for you. For example if you put Test app as the content of the string, android will display the text in bold letters.

2) Creating string resources for each of the languages
Now to the interesting part: the translated resources.
I wrote somewhere above that the string resources reside under res/values. Well, the name of directory values is that one that tells android what language the string resources are. The name of the directory is prefixed with a dash "-" plus the locale code for the language in question.

So a directory called values-fr will have content in French, values-es in Spanish and so on. Creating another strings.xml under res/values-es with the content

<xml version="1.0" encoding="utf-8">
    <string name="app_title">AplicaciĆ³n de Test</string>

will make your app automatically display the content in Spanish for devices using Spanish locale.
notice that the name "app_title" is the same and must be the same for any locale.

The directory res/values contains the default string resources for any locale and it's always a good practice to have defaults.

3) Testing your app

Testing the translated version of your app is simple, just change the locale of the phone/emulator and reboot it (at least I always had to reboot for the change to take effect).
To change the locale in the emulator, click on the apps button and you should see an app called Custom Locales. Select an existing one or create your own.
Reboot the emulator and done!

Next post I will talk about using resource strings in the code and how to localize other types of resources.

Programming tricks and tips for android developers