Home | History | Annotate | Download | only in resources
      1 page.title=Language and Locale
      2 page.tags=androidn
      3 page.image=images/cards/card-nyc_2x.jpg
      4 
      5 @jd:body
      6 
      7 <div id="qv-wrapper">
      8 <div id="qv">
      9 <h2>In this document:</h2>
     10 <ol>
     11 	  <li><a href="#preN">Challenges in Resolving Language Resources</a></li>
     12     <li><a href="#postN">Improvements to Resource-Resolution Strategy</a></li>
     13     <li><a href="#design">Designing your App to Support Additional
     14       Locales</a></li>
     15 
     16 </ol>
     17 
     18 </div>
     19 </div>
     20 
     21 <p>Starting in Android 7.0 (API level 24),
     22 Android provides enhanced support for multilingual users,
     23 allowing them to select multiple locales in settings. Android
     24 provides this capability by greatly expanding the number of locales supported
     25 and changing the way the system resolves resources.</p>
     26 
     27 <p>This document starts by explaining the resource resolution strategy in
     28 versions of Android lower than 7.0 (API level 24). Next, it describes
     29 the improved resource-resolution strategy in Android 7.0.
     30 Last, it explains how to take advantage of
     31 the expanded number of locales to support more multilingual users.</p>
     32 
     33 <h2 id="preN">Challenges in Resolving Language Resources</h2>
     34 
     35 <p>Prior to Android 7.0, Android could not always successfully
     36  match app and system locales.</p>
     37 
     38  <p>For example, assume that you have the following situation:</p>
     39  <ul>
     40  <li>Your app's default language is {@code en_US} (US English), and it also has
     41   Spanish strings localized in {@code es_ES}
     42   resource files.</li>
     43  <li> A device is set to {@code es_MX} </li>
     44 
     45 <p>When your Java code refers to strings, the system would load
     46 strings from the default ({@code en_US}) resource file, even if the app has
     47 Spanish resources localized under {@code es_ES}. This is because when the system
     48  cannot find an exact match, it continues to look for resources by stripping the
     49  country code off the locale. Finally, if no match is found, the system falls
     50  back to the default, which is {@code en_US}. </p>
     51 
     52 
     53 <p>The system would also default to {@code en_US} if the user chose a language that
     54 the app didn't support at all, like French. For example:</p>
     55 
     56 <p class="table-caption" id="t-resource-res">
     57 <strong>Table 1.</strong> Resource resolution without an exact locale match.
     58 </p>
     59 <table>
     60 <tbody>
     61 <tr>
     62 <th>User Settings</th>
     63 <th>App Resources</th>
     64 <th>Resource Resolution</th>
     65 </tr>
     66 <tr>
     67 <td>fr_CH</td>
     68 <td>
     69 default (en)<br>
     70 de_DE<br>
     71 es_ES<br>
     72 fr_FR<br>
     73 it_IT<br>
     74 </td>
     75  <td>
     76 Try fr_CH =&gt; Fail<br>
     77 Try fr =&gt; Fail<br>
     78 Use default (en)
     79 </td>
     80  </tr>
     81  </tbody>
     82 </table>
     83 
     84 
     85 <p>In this example, the system displays English strings without
     86 knowing whether the user can understand English. This behavior is pretty common
     87 today.</p>
     88 
     89 <h2 id="postN">Improvements to Resource-Resolution Strategy</h2>
     90 <p>Android 7.0 (API level 24) brings more robust resource resolution, and
     91  finds better fallbacks automatically. However, to speed up resolution and
     92  improve
     93  maintainability, you should store resources in the most common parent dialect.
     94  For example, if you were storing Spanish resources in the {@code es-US}
     95  directory
     96  before, move them into the {@code es-419} directory, which contains Latin
     97  American Spanish.
     98  Similarly, if you have resource strings in a folder named {@code en-GB}, rename
     99  the folder to {@code en-001} (international English), because the most common
    100  parent for <code>en-GB</code> strings is {@code en-001}.
    101  The following examples explain why these practices improve performance and
    102 reliability of resource resolution.</p>
    103 
    104 <h3>Resource resolution examples</h3>
    105 
    106 <p>With versions of Android greater than 7.0, the case described in
    107 	<strong>Table 1</strong> is resolved differently:</p>
    108 
    109 <p class="table-caption" id="t-improved-res">
    110 <strong>Table 2.</strong> An improved resolution strategy for when there is no
    111 exact locale match.</p>
    112 <table>
    113 <tr>
    114 <th>User Settings</th>
    115 <th>App Resources</th>
    116 <th>Resource Resolution</th>
    117 </tr>
    118 <tr>
    119 <td><ol>
    120 <li> fr_CH</li>
    121 </ol>
    122 </td>
    123 <td>
    124 default (en)<br>
    125 de_DE<br>
    126 es_ES<br>
    127 fr_FR<br>
    128 it_IT<br>
    129 </td>
    130 <td>
    131 Try fr_CH =&gt; Fail<br>
    132 Try fr =&gt; Fail<br>
    133 Try children of fr =&gt; fr_FR<br>
    134 Use fr_FR
    135 </td>
    136 </tr>
    137 
    138 </table>
    139 
    140 
    141 <p>Now the user gets French resources instead of English. This example also shows
    142  why you should store French strings in {@code fr} rather than {@code fr_FR}
    143  for Android 7.0 or higher. Here the course of action is
    144  to match the closest parent dialect,
    145  making resolution faster and more predictable.</p>
    146 
    147 <p>In addition to this improved resolution logic, Android now offers more
    148  user languages to choose from. Lets try the above example again with Italian
    149  specified as an additional user language, but without app support for French.  </p>
    150 
    151 <p class="table-caption" id="t-2d-choice">
    152 <strong>Table 3.</strong> Resource resolution when the app only matches the
    153 user's second-preferred locale setting.</p>
    154 <table>
    155 <tr>
    156 <th>User Settings</th>
    157 <th>App Resources</th>
    158 <th>Resource Resolution</th>
    159 
    160 </tr>
    161 <tr>
    162 <td><ol>
    163 <li> fr_CH</li>
    164 <li> it_CH</li>
    165 </ol>
    166 </td>
    167 <td>
    168 default (en)<br>
    169 de_DE<br>
    170 es_ES<br>
    171 it_IT<br>
    172 </td>
    173 <td>
    174 Try fr_CH =&gt; Fail<br>
    175 Try fr =&gt; Fail<br>
    176 Try children of fr =&gt; Fail<br>
    177 Try it_CH =&gt; Fail<br>
    178 Try it =&gt; Fail<br>
    179 Try children of it =&gt; it_IT<br>
    180 Use it_IT
    181 </td>
    182 
    183 </tr>
    184 
    185 </table>
    186 <p>
    187   The user still gets a language they understand, even though the app doesnt
    188   support French.
    189 </p>
    190 
    191 
    192 <h2 id="design">Designing your App to Support Additional Locales</h2>
    193 <h3>LocaleList API</h3>
    194 
    195 <p>
    196   Starting with Android 7.0 (API level 24), Android exposes the
    197   {@code LocaleList.getDefault()} API
    198   that lets apps directly query the list of languages a user has specified. This API
    199   allows you to create more sophisticated
    200   app behavior and better-optimized display of content. For example, Search
    201   can show results in multiple languages based on users settings.  Browser apps
    202   can avoid offering to translate pages in a language the user already knows,
    203   and keyboard apps can auto-enable all appropriate layouts.
    204 </p>
    205 
    206 <h3>Formatters</h3>
    207 
    208 <p>
    209   Up through Android 6.0 (API level 23), Android supported only one or
    210   two locales
    211   for many common languages
    212   (en, es, ar, fr, ru). Because there were only a few variants of each language,
    213   apps could get away with storing some numbers and dates as hard coded strings
    214   in resource files.  However, with Android's broadened set of supported
    215   locales, there can be
    216   significant differences in formats for dates, times, currencies, and similar
    217   information even within a single locale. Hard-coding your formats can produce
    218   a confusing experience for end users.
    219   Therefore, when developing for Android 7.0 or higher versions,
    220   make sure to use formatters instead of hard coding numbers and date strings.</p>
    221 
    222 <p>
    223   For example, Android 7.0 and higher includes support for
    224   27 Arabic locales. These locales can share most resources,
    225   but some prefer ASCII digits, while others prefer native digits. For example,
    226   when you want to create a sentence with a digit variable, such as
    227   "Choose a 4 digit pin", use formatters as shown below:
    228 </p>
    229 
    230 <pre> format(locale, "Choose a %d-digit PIN", 4)</pre>
    231