Localizing Resources

Language settings are part of the device’s configuration, like the screen orientation configuration you have encountered. Android provides qualifiers for different languages just as it does for screen orientation, screen size, and other configuration factors. This makes localization straightforward: You create resource subdirectories with the desired language configuration qualifier and put the alternative resources in them. The Android resource system does the rest.

In your CriminalIntent project, create a new values resource file: In the project tool window, right-click res/values/ and select NewValues resource file. Enter strings for the File name. Leave the Source set option set to main and make sure Directory name is set to values.

Next, select Locale in the Available qualifiers list and click the >> button to move Locale to the Chosen qualifiers section. Select es: Spanish in the Language list. Any Region will be automatically selected in the Specific Region Only list – which is just what you want, so leave that selection be.

The resulting New Resource File window should look similar to Figure 18.2.

Figure 18.2  Adding a qualified strings resource file

Adding a qualified strings resource file

Android Studio automatically changes the Directory name field to values-es. The language configuration qualifiers are taken from ISO 639-1 codes, and each consists of two characters. For Spanish, the qualifier is -es.

Click OK. The new strings.xml file will be listed under res/values, with (es) after its name. The strings files are grouped in the project tool window’s Android view (Figure 18.3).

Figure 18.3  Viewing new strings.xml in Android view

Viewing new strings.xml in Android view

However, if you explore the directory structure, you will see that your project now contains an additional values directory: res/values-es. The newly generated strings.xml is in this new directory (Figure 18.4).

Figure 18.4  Viewing new strings.xml in Project view

Viewing new strings.xml in Project view

Now it is time to make the magic happen. Add Spanish versions of all your strings to res/values-es/strings.xml. (If you do not want to type these strings in, copy the contents from the solutions file at www.bignerdranch.com/​android-5e-solutions.)

Listing 18.1  Adding Spanish alternatives for string resources (res/values-es/strings.xml)

<resources>
    <string name="app_name">IntentoCriminal</string>
    <string name="crime_title_hint">Introduzca un título para el crimen.</string>
    <string name="crime_title_label">Título</string>
    <string name="crime_details_label">Detalles</string>
    <string name="crime_solved_label">Solucionado</string>
    <string name="new_crime">Crimen Nuevo</string>
    <string name="crime_suspect_text">Elegir Sospechoso</string>
    <string name="crime_report_text">Enviar el Informe del Crimen</string>
    <string name="crime_report">%1$s!
        El crimen fue descubierto el %2$s. %3$s, y %4$s
    </string>
    <string name="crime_report_solved">El caso está resuelto</string>
    <string name="crime_report_unsolved">El caso no está resuelto</string>
    <string name="crime_report_no_suspect">no hay sospechoso.</string>
    <string name="crime_report_suspect">el/la sospechoso/a es %s.</string>
    <string name="crime_report_subject">IntentoCriminal Informe del Crimen</string>
    <string name="send_report">Enviar el informe del crimen a través de</string>
</resources>

That is all you have to do to provide localized string resources for your app. To confirm, change your device’s settings to Spanish by opening Settings and finding the language settings. Depending on your version of Android, these settings will be labeled Language and input, Language and Keyboard, or something similar. On the Pixel 4 emulator, the Languages & input settings are within the System section.

When you get to a list of language options, choose a setting for Español. The region (España or Estados Unidos) will not matter, because the qualification -es matches both. (On newer versions of Android, users can select multiple languages and assign a priority order. If you are on a newer device, make sure Español appears first in your language settings list.)

Now run CriminalIntent and bask in the glory of your newly localized app. When you are done basking, return your device’s language setting to English. Look for Ajustes or Configuración (Settings) in the launcher and find the setting that includes Idioma (Language).

Default resources

The configuration qualifier for English is -en. In a fit of localization, you might think to rename your existing values directory to values-en. This is not a good idea, but pretend for a moment you did just that: Your hypothetical update means your app now has an English strings.xml in values-en and a Spanish strings.xml in values-es.

As you might expect, the app would run just fine on devices with the language set to Spanish or English. But what happens if the user’s device language is set to Italian? Bad things. Very bad things. If the app is allowed to run, Android will not find string resources that match the current configuration. This will cause your app to crash with a Resources.NotFoundException.

Android Studio takes steps to save you from this fate. The Android Asset Packaging Tool (AAPT) does many checks while packaging up your resources. If AAPT finds that you are using resources that are not included in the default resource files, it will throw an error at compile time:

    Android resource linking failed

    warn: removing resource
    com.bignerdranch.android.criminalintent:string/crime_title_label
    without required default value.

    AAPT: error: resource string/crime_title_label
    (aka com.bignerdranch.android.criminalintent:string/crime_title_label)
    not found.

    error: failed linking file resources.

The moral of the story is this: Provide a default resource for each of your resources. Resources in unqualified resource directories are your default resources. Default resources will be used if no match for the current device configuration is found. Your app will misbehave if Android looks for a resource and cannot find either one that matches the device configuration or a default.

Checking string coverage using the Translations Editor

As the number of languages you support grows, making sure you provide a version of each string for each language becomes more difficult. Luckily, Android Studio provides a handy Translations Editor to see all your translations in one place. Before starting, create some “missing” strings by opening your default strings.xml and commenting out crime_title_label and crime_details_label (Listing 18.2).

Listing 18.2  Commenting out strings (res/values/strings.xml)

<resources>
    <string name="app_name">CriminalIntent</string>
    <string name="crime_title_hint">Enter a title for the crime.</string>
    <!--<string name="crime_title_label">Title</string>-->
    <!--<string name="crime_details_label">Details</string>-->
    <string name="crime_solved_label">Solved</string>
    ...
</resources>

To launch the Translations Editor, right-click one of the strings.xml files in the project tool window and select Open Translations Editor. The Translations Editor displays all the app’s strings and the translation status for each of the languages for which your app provides any qualified string values. Since crime_title_label and crime_details_label are commented out, you will see those field names in red (Figure 18.5).

Figure 18.5  Using the Translations Editor to check your string coverage

Using the Translations Editor to check your string coverage

This provides an easy way to identify resources that are missing from any locale configuration and add them to the related strings file.

Although you can add strings right in the Translations Editor, in your case you only need to uncomment crime_title_label and crime_details_label. Do that before moving on.

Targeting a region

You can qualify a resource directory with a language-plus-region qualifier that targets resources even more specifically. For instance, the qualifier for Spanish spoken in Spain is -es-rES, where the r denotes a region qualifier and ES is the ISO 3166-1-alpha-2 code for Spain. The qualifier for Spanish spoken in Mexico is -es-rMX. (Configuration qualifiers are not case sensitive, but it is good to follow Android’s convention here: Use a lowercase language code and an uppercase region code prefixed with a lowercase r.)

Note that a language-region qualifier, such as -es-rES, may look like two distinct configuration qualifiers that have been combined, but it is just one. The region is not a valid qualifier on its own.

A resource qualified with both a locale and region has two opportunities for matching a user’s locale. An exact match occurs when both the language and region qualifiers match the user’s locale. If no exact match is found, the system will strip off the region qualifier and look for an exact match for the language only.

Which brings us to an important point: Always provide strings in as general a context as possible, using language-only qualified directories as much as possible and region-qualified directories only when necessary. For example, if the differences between European and North or South American Spanish are an issue, it is better to store most of the Spanish strings in a language-only qualified values-es directory and provide region-qualified strings only for words and phrases that are different in the different regional dialects.

(For more about supporting languages and regions, check out developer.android.com/​guide/​topics/​resources/​multilingual-support.)

In fact, this advice goes for all types of alternative resources in the values directories: Provide shared resources in more general directories and only include those resources that need to be tailored in more specifically qualified directories.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset