Статьи

Как локализовать приложение для Android

Локализация — это больше, чем просто перевод строк в вашем приложении на другие языки. Это также включает отображение данных, таких как даты и время, в нужном формате для ваших пользователей. Даже если вам нужна только английская версия приложения, полезно знать, что такое локализация. Таким образом, вы будете готовы, если решите добавить поддержку дополнительных локалей, и вам не придется искать строки и значения во всей кодовой базе вашего приложения.

В Android SDK язык локализованных строк и формат, используемый для отображения значений, зависят от локали устройства. Локаль — это сочетание языка и страны. Язык определяется стандартом ISO 639-1, а страна — стандартом ISO 3166-1 . Это означает, что локаль Android совместима с культурой или локалью, используемой большинством других языков программирования и сред.

Единственным языком, который гарантированно будет присутствовать на каждом устройстве Android, является английский, как говорят в Соединенных Штатах . Он представлен кодом en_US , с en   код языка для английского и США , код страны для США. Вы также можете использовать ан только код языка в качестве локали для представления всех англоязычных стран и регионов.

Чтобы локализовать приложение для языка или для конкретной страны и языка, вам необходимо включить ресурсы для этого языка в папку / res вашего приложения. Это обычно включает строковые ресурсы в папке / res / values , но может также включать другие типы ресурсов, такие как изображения и макеты. Android SDK идентифицирует различные альтернативные ресурсы с помощью квалификаторов конфигурации, которые затем используются для именования папки, содержащей эти ресурсы. Спецификатор конфигурации для локали — это код языка, за которым может следовать код страны. Таким образом, локализованные строковые ресурсы для вашего приложения должны быть в   / res / values- <код языка> или / res / values- <языковой код> -r <код страны> папка.

Следует помнить, что ресурсы, определенные с помощью квалификатора конфигурации для конкретной локали, имеют приоритет над большинством других ресурсов. Другие общие квалификаторы конфигурации для ресурсов с более низким приоритетом включают размер экрана и плотность пикселей экрана для описания различных макетов в зависимости от размера экрана. Только ресурсы, идентифицированные с помощью квалификатора конфигурации мобильного кода страны (MCC), имеют больший приоритет, чем строковые ресурсы, идентифицированные с помощью квалификатора конфигурации локали. Код страны мобильной связи используется для определения ресурсов для страны, за которыми может необязательно следовать код мобильной сети (MNC) с SIM-карты для нацеливания на конкретного оператора мобильной связи в этой стране. Он используется для предоставления контента, специфичного для такой страны, как договор или политика конфиденциальности.

Каждое Android-приложение должно иметь все свои строковые ресурсы в файле /res/values/strings.xml . Это позволяет повторно использовать строки в вашем приложении, даже если не требуется локализация. Кроме того, если файл не доступен для текущей локали устройства, это файл используется. Если у вас его нет и ваше приложение пытается получить доступ к строковому ресурсу, который доступен только в файле strings.xml, специфичном для локали, ваше приложение будет аварийно завершать работу, поскольку ресурсы загружаются во время выполнения, а не во время компиляции.

Файл strings.xml, специфичный для локали, не должен иметь все строковые ресурсы из файла /res/values/strings.xml . Это означает, что если ресурс, такой как имя вашего приложения, не нуждается в локализации, вам не нужно включать его в каждый строковый файл.

Во время выполнения, / Проверяется файл res / values- <код языка> -r <код страны> /strings.xml для локали устройства, а затем файл / r es / values- <код языка> /strings.xml только для языка. Если указанная строка недоступна в этих файлах, приложение возвращается к / r es / values ​​/ strings.xml .

Например, если вы хотите локализовать ваше приложение для всех франкоязычных регионов и стран, не ориентируясь на конкретную, вы помещаете строки для приложения в файл / r es / values-fr / strings.xml . Однако, если вы хотите локализовать некоторые строки с написанием, специфичным для французского языка, как написано во Франции, вы должны поместить их в файл /res/values-fr-rFr/strings.xml . Обязательно добавьте r перед кодом страны в названии папки, иначе он не будет найден во время выполнения, когда приложение локализовано.

Вот пример файла / res / values ​​/ strings.xml с несколькими строковыми ресурсами на английском языке:

1
2
3
4
5
6
<?xml version=»1.0″ encoding=»utf-8″?>
<resources>
   <string name=»app_name»>Android Localization Demo</string>
   <string name=»hello_world»>Hello world!</string>
   <string name=»hello_world_name»>Hello %s!</string>
</resources>

А вот и / res / values-fr / strings.xml   файл с теми же ресурсами на французском языке:

1
2
3
4
5
6
<?xml version=»1.0″ encoding=»utf-8″?>
<resources>
   <string name=»app_name»>Démo de localisation Android</string>
   <string name=»hello_world»>Bonjour le monde!</string>
   <string name=»hello_world_name»>Bonjour %s!</string>
</resources>

Строки в ваших макетах должны быть строковыми ресурсами. На самом деле, предупреждение Lint отображается, если строка жестко запрограммирована. Вы можете использовать ресурсы везде, где вы будете устанавливать строки в макетах. Строковые ресурсы обозначаются @string/ за которыми следует имя ресурса из файла strings.xml . Следующее отображает строку hello_world из предыдущего примера в TextView соответствии с hello_world устройства:

1
2
3
4
5
<TextView
       android:id=»@+id/hello_world_textview»
       android:layout_width=»wrap_content»
       android:layout_height=»wrap_content»
       android:text=»@string/hello_world» />

Это показывает «Bonjour le monde!» на устройстве Android установлен языковой стандарт, включающий французский язык. Для всех остальных локалей «Привет, мир!» Строка показана.

Вам также нужно будет локализовать строки из вашего кода, если вы создаете или изменяете элементы управления вне макетов. Чтобы локализовать эти строки, вы должны сначала получить объект android.content.res.Resources который содержит все ресурсы в пакете приложения для текущего контекста. Затем вы вызываете метод getString для этого объекта, передавая идентификатор отображаемой строки. Например, следующий блок кода показывает, как установить текст объекта TextView :

1
2
3
4
5
6
7
8
// Get the translated string from the string resource
android.content.res.Resources res = context.getResources();
String helloWorld = res.getString(R.string.hello_world);
 
// Set the string to the textview
TextView helloTextView;
helloTextView = (TextView)findViewById(R.id.hello_world_textview);
helloTextView.setText(helloWorld);

Более сложные строки, с одним или несколькими переменными компонентами, вам нужно использовать строки формата. Строки формата позволяют указать значения параметров для отображения. Параметры в строке формата идентифицируются с помощью спецификаторов формата. Наиболее часто используемый спецификатор формата — это %s , представляющий строку. Фактически доступны все строки формата из класса java.util.Formatter . Кроме того, если требуется несколько параметров, необходимо указать нумерацию спецификаторов формата. В случае спецификаторов формата строки, первый должен быть %1$s , второй %2$s и так далее.

После того как строки формата указаны, вы используете метод String.format для передачи параметров, отображаемых в вашей строке. Вот как настроить отображение текста в TextView с помощью hello_world_name формата hello_world_name из файла strings.xml . Эта строка формата включает в себя спецификатор формата для имени пользователя:

01
02
03
04
05
06
07
08
09
10
11
12
// Get the format string
android.content.res.Resources res = context.getResources();
String helloFormatString = res.getString(R.string.hello_world_name);
String userName = «Bob»;
 
// Insert the name in the format string
String helloWorldName = String.format(helloFormatString, userName);
 
// Set text of the textview
TextView helloTextView;
helloTextView = (TextView)findViewById(R.id.hello_world_textview);
helloTextView.setText(helloWorldName);

Это показывает «Bonjour Bob!» строка для устройства Android с локалью, включающей французский язык. Для всех остальных языков «Привет, Боб!» Строка показана.

Если строки вашего приложения уже локализованы, ваше приложение уже в довольно хорошей форме. Тем не менее, вам может понадобиться показывать дату и время пользователю во многих случаях. Эти даты и время также должны быть адаптированы к текущей локали устройства. К счастью, Android SDK содержит классы, которые форматируют даты и время в соответствии с локалью.

В Android SDK даты и время управляются классом Date из пространства имен java.util . Текущая дата и время устройства возвращаются java.util.Calendar .

Даты могут быть отформатированы с использованием экземпляра форматера DateFormat из пространства имен java.text . Вы должны использовать класс DateFormat из Android SDK в пространстве имен android.text.format чтобы получить правильный форматер для локали устройства. В следующем фрагменте кода показано, как получить строку с текущей датой, отформатированной для локали устройства:

01
02
03
04
05
06
07
08
09
10
// Gets the current date and time
Date currentDate = Calendar.getInstance().getTime();
 
// Gets the standard date formatter for the current locale of
// the device
java.text.DateFormat dateFormat;
dateFormat = android.text.format.DateFormat.getDateFormat(this);
 
// Formats the current date according to the locale
String formattedCurrentDate = dateFormat.format(currentDate);

Если текущим языком устройства является английский, как говорят в США, строка будет содержать текущую дату в формате короткой даты, 30.11.2014 . Класс DateFormat включает в себя несколько других форматов даты. Например, метод getLongDateFormat возвращает формат длинной даты, воскресенье, 30 ноября 2014 г.

Поскольку времена представлены как объекты Date в Android SDK, они также должны отображаться с использованием средства форматирования, возвращаемого классом DateFormat из пространства имен android.text.format . Метод getTimeFormat возвращает формат, который отображает только время объекта Date . В следующем фрагменте кода показано, как получить строку с текущим временем, отформатированным для локали устройства:

01
02
03
04
05
06
07
08
09
10
// Gets the current date and time
java.util.Date currentDate = Calendar.getInstance().getTime();
 
// Gets a date formatter for the current locale of the device
// that shows times.
java.text.DateFormat timeFormat;
timeFormat = android.text.format.DateFormat.getTimeFormat(this);
 
// Formats the current time according to the locale
String formattedTime = timeFormat.format(currentDate);

Если текущим языком устройства является английский, как говорят в США, строка будет содержать текущее время в следующем формате, 20:15 .

Важно только локализовать строки, которые используются в пользовательском интерфейсе приложения. Например, нет необходимости локализовать отладочные сообщения, которые используются только во время разработки или в целях диагностики. Также обратите внимание, что вы не должны записывать локализованные даты и время на диск или в базу данных. Меняется не только языковой стандарт устройства, но и работа с локализованными датами и временем делает разработку излишне сложной и сложной.