Strategies for localizing an application

Một phần của tài liệu Manning android in action 3rd (Trang 541 - 547)

Ideally an application is built from the top down with localization1 in mind from day one. If you always take this approach from the start, congratulations, this topic will be a breeze for you. But if you’ve ever written an application that has some hard-coded strings or perhaps some code that makes specific assumptions about status codes or date formatting, you have some work to do to make your applications play nicely across multiple locales.

There are a number of perspectives on localization. We won’t cover all of them, but the discussion that follows should give you a good foundation for localizing your application. Throughout this chapter, most of the code examples we use are from a localized variant of the Field Service application you met in chapter 12. The code in chapter 12 is not localized. The chapter 20 code is both localized and is additionally translated into Spanish. Let’s get started!

18.3.1 Identifying target locales and data

In all likelihood, you’ll develop your Android application in your native language and your initial target deployment may be in that same language. Your application may be aimed at a specific people group and a specific language. Whether you’re targeting a

1 Localization is the how to, and the why. Frank Ableson’s post on Linux Magazine scratches the surface:

www.linux-mag.com/id/7794.

Figure 18.3

Date and time settings

broader audience or a specific single market, it’s a good idea to always keep your tar- get market in mind.

For example, in the Field Service application, you may have users, customers, and dispatchers distributed anywhere in the world. This means that you need to keep the entire infrastructure in mind, not just the mobile application. You might congratulate yourself for making your application play nicely in the fr_FR locale settings, but if all the application data is still shown in English, you’re missing a vital element of the big- ger objective. So not only does your mobile code need to be localized, but the entire infrastructure needs to keep locale in focus.

Data generated on the server may require on-the-fly translation. Perhaps a simpler approach is to filter query results based on the specified language. The device’s locale can be programmatically obtained at runtime using the toString() method of the Locale class. This is shown in the following listing and demonstrated in figure 18.4 and figure 18.5.

private void RefreshUserInfo() {

final TextView emaillabel = (TextView) findViewById(R.id.emailaddresslabel);

emaillabel.setText(this.getString(R.string.user) +": " + this.myprefs.getEmail() + "\n" + this.getString(R.string.server)+ ": " + this.myprefs.getServer() + "\n" +

this.getString(R.string.locale) + ":" + Locale.getDefault().toString() );

}

You obtain a reference to a TextView widget for dis- playing textual information at runtime. The get- Default() static method returns the currently selected locale. The toString() method displays the ISO format of the locale.

When submitting a request to a server-side applica- tion, this locale value can be passed along as a query parameter:

http://<servername>/somepage.php?a=b&c=d&locale=en_US

How the server side handles the query is application-specific and beyond our discus- sion here. Keep in mind that localization is more than the translation of strings within your application itself. Speaking of strings, they’re up next in our discussion.

18.3.2 Identifying and managing strings

There’s perhaps no more emblematic localization topic than the concept of translat- ing and managing an application’s strings into target languages. Textual strings are the most visible and obvious means to target an application for a particular locale.

Listing 18.1 Getting current locale at runtime

Figure 18.4 en_US locale

Figure 18.5 es_ES locale

The centerpiece of string management within an Android application is the strings.xml file stored in the /res/values folder. The values folder contains the default resources for the application. Values for addi- tional locales are stored in folders with names identify- ing the attributes for a specific language or locale. For example, figure 18.6 shows string files for both the default locale and for Spanish translation of those strings.

A strings.xml file contains a list of strings, as shown in the following listing, which shows some of the strings used in the Field Service application.

<?xml version="1.0" encoding="utf-8"?>

<resources>

<string name="app_name">Unlocking Android</string>

<string name="sign_and_close">Sign and Close</string>

<string name="cancel">Cancel</string>

<string name="refresh_job_list">Refresh Job List</string>

<string name="manage_jobs">Manage Jobs</string>

<string name="settings">Settings</string>

<string name="user">User</string>

<string name="server">Server</string>

<string name="refreshing_job_list">Refreshing Job List</string>

<string name="connecting">Connecting</string>

<string name="there_are_count_jobs">There are %d jobs</string>

<string name="jobid">Job ID</string>

<string name="comments">Comments</string>

<string name="product">Product</string>

<string name="map_job_location">Map Job Location</string>

<string name="get_product_info">Get Product Info</string>

<string name="job_is_closed">Job is closed</string>

<string name="view_signature">View Signature</string>

<string name="email_address">Email Address</string>

<string name="server_url">Server URL</string>

<string name="save_settings">Save Settings</string>

<string name="close_job">Close Job</string>

<string name="locale">Locale</string>

</resources>

The strings.xml files are standard XML files B. To create one of these files, you can either create it by hand or select File > New: Android Xml File in Eclipse. Each string value C has an attribute that uniquely identifies the string along with a value stored between the <string> and </string> tags.

When creating a strings.xml file for any target language beyond the default locale, you have the option of translating every string or just a subset of the strings. At run- time, your application will automatically load the correct string, looking first in the locale-specific file and working back to the default to find the required value. This cas- cading works in a manner similar to CSS. The most precise interpretation of the

Listing 18.2 Default strings.xml file

XML file declaration

B

String entry

C

Figure 18.6

Multiple strings.xml files

device locale is the first file to be searched. If the resource isn’t found in this location, the platform works its way up the tree toward the default. Let’s look at an example.

Let’s say your application is written in a default language of English with 20 unique strings stored in /res/values/strings.xml. You anticipate that your application will be deployed around the globe, but you’re specifically targeting English- and French- speaking users in the United States, France, and Canada.

To implement this strategy, your application contains four different strings.xml files, one in each of the directories listed in table 18.1.

When a string is looked up at runtime, Android uses the current locale as a filter to choose resources. Let’s say our device is set for the French Canadian locale: fr_CA. If the string we require is found in the /res/values-fr-rCA/strings.xml file, it’s used. If the string isn’t found there, the file /res/values-fr/strings.xml is searched next because it’s the general French strings file. If it’s still not found, the string will be taken from the default strings file /res/values/strings.xml.

Not every string needs to be provided in each file. If only a handful of strings differ in Canada versus the general French strings, just provide the Canada-specific values in the fr_rCA file. Following this practice of managing a minimum number of strings can be helpful, because it can be labor- and testing-intensive to manage multiple string tables.

So far, our discussion has included only strings, language, and region-specific files.

Strings aren’t the only resources that may be localized. In the next section, we take a brief look at other localized resources.

18.3.3 Drawables and layouts

Beyond strings, your application may need to provide locale-specific resources for drawables (images) and for user interface layouts. The process of managing drawables and layouts is identical to managing strings. If you require locale-specific versions of your images and layouts, they should be put in locale-specific folders in the /res folder.

Providing locale-specific images seems reasonable, because your application’s images may have textual contents, or perhaps your application has images of region- specific currency. It’d make sense to show an appropriate image of a greenback dollar in the US or a Euro in most of Europe. But what about layouts: why would you want to localize a layout?

Table 18.1 List of strings.xml files

Directory Comment

/res/values/strings.xml Default strings.xml stores values in English for this example /res/values-fr/strings.xml Complete translation of strings in French

/res/values-fr-rFR/strings.xml A subset of strings with France-specific translations, spellings, etc.

/res/values-fr-rCA/strings.xml A subset of strings with Canada-specific translations, spellings, etc.

Most UI elements such as TextView widgets and Buttons display textual values. If those textual values vary in length from one language to the next—which they can and often do—it may be prudent to provide a locale-specific layout file in some instances. The idea here is to be intentional about your application’s visual appear- ance rather than letting the user have a nondeterministic experience. Recall that many UI elements specify a width value wrap_content. This may not result in a visually appealing layout at runtime. If a particular string is going to distort the UI of your application, find out ahead of time and rearrange your widgets within a locale-specific layout as required.

In addition to your resources, you need to consider the data values your applica- tion uses, such as date and time, numbers, and currency. This is the topic of the next section.

18.3.4 Dates, times, numbers, and currencies

When working with data, keep in mind that users in various parts of the world manip- ulate dates and numbers differently. If you doubt that, just try to enter the thirteenth day of December 2010 into an application expecting input in the form of DD/MM/ YYYY. If you enter 12/13/2010, the application will choke because there’s no thir- teenth month!

Manipulating these values isn’t so much of an Android topic as it is a Java topic. As such, our discussion here is limited to a quick survey of commonly used Java classes for the purpose of handling data in a locale-specific fashion. Demonstrating each of these classes is beyond the scope of this chapter, and we encourage you to view the exhaustive Javadocs available for these classes. Table 18.2 enumerates some of the classes you’re likely to employ when working with a localized application.

Table 18.2 Helpful classes for localized applications

Class name Comment

java.util.GregorianCalendar Subclass of the Calendar class, allowing for date and time manipulation specific to a locale.

java.text.SimpleDateFormat Useful for formatting date and time according to custom developer-supplied formats.

java.text.DecimalFormat Formats a decimal value according to a specific locale and string format.

java.text.DecimalFormatSymbols Helper class to DecimalFormat. Use this class to retrieve currency symbols, grouping, and decimal sym- bols. Some locales use commas for grouping and period for decimal separation; others do the opposite. This class helps navigate those formatting distinctions.

java.util.Locale Most of the previous classes rely on this class in one way or another.

Before examining the localized version of our Field Service application in more detail, there’s one more topic to discuss that has less to do with code than it does with coding.

Most developers we know won’t translate their applications to multiple languages and locales on their own—they’ll employ a teammate or an outside service. Regardless of whom you work with, it’s helpful to keep them in mind from the start of your proj- ect. The next section discusses things you can do to work successfully with your trans- lation team.

18.3.5 Working with the translation team

Managing the strings within an application is straightforward on the surface, but it’s not without some challenges, in part because you’re working with others. The transla- tion professionals may be part of your organization or they may be an outside service.

If you have the good fortune of working closely with a teammate for translation, things may go easier for you, as you can rely on them for not only term translation but also context. An outside party can provide those services as well, but the cost in terms of dollars and time may be much greater.

Some of the challenges relate to the translation task itself, but there’s another chal- lenge with building a localized application: discipline. Unless you’re working in a structured environment, some aspects of software creation are fluid. You may have an idea for an enhancement to a section of your code. You’re excited about this feature, so you code the enhancement and add a menu item to enable this new aspect of your application. Terrific, your application is now more functional and your users love you!

Hold on a moment. Did you use any string literals when you coded the new feature, including the menu? If so, did you get translations yet? A localized application may suffer from some latency and added expense when you factor in the translation and testing steps. When you send data out to your translation team, it’s important not only to provide an exhaustive list of strings or terms that need to be translated, but also to provide as much context as possible. For example, when we had the Field Service application’s terms translated to Spanish, we sent the list to our outside translation vendor. Included in that list was a brief description of each term and its use in the application. A further helpful step would be to storyboard the application with screen- shots (or screencasts), thereby equipping the translation team with as much context as possible.

It’s also a good idea to keep cultural references in mind. Remember: your objec- tive is to translate user experience, not just textual terms!

At this point, you have enough information on why localization is important and some feel for what needs to be done to make it happen. The next section digs deeper into the capabilities built within the Android resource subsystem to aid in localization.

Một phần của tài liệu Manning android in action 3rd (Trang 541 - 547)

Tải bản đầy đủ (PDF)

(662 trang)