Статьи

Android SDK: создание локализованного разговорника

Из этого руководства вы узнаете, как создавать и использовать альтернативные файлы ресурсов с помощью приложения для Android под названием «Разговорник за минуту». Это приложение отображает определенный текст и графику в зависимости от языка / локали системы Android.

Авторы предполагают, что читатель имеет некоторые базовые знания об Android и все необходимые инструменты, такие как Eclipse и Android SDK, установлены и работают. Приведенные здесь примеры разработаны для того, чтобы показать, как можно локализовать ресурсы проекта Android. В частности, этот учебник покажет вам, как включать ресурсы для разных языков и локалей.

Примечание. Код для приложения OneMinutePhrasebook также доступен в Google Code .

Начните с создания нового проекта Android.

Чтобы сделать это в Eclipse, выберите « Файл» -> «Новый проект Android», чтобы запустить мастер проекта Android.

Назовите проект: например, «Разговорник»

Выберите подходящую цель сборки, например Android 2.1.

Назовите приложение: например, «Минутный разговорник»

Назовите пакет: например, com.mamlambo.article.phrasebook

Создать активность при запуске: например, PhrasebookActivity

Создание проекта Android разговорника.

Вы будете отлаживать это приложение, поэтому вам нужно установить для атрибута Debuggable в файле манифеста Android значение true.

Изменение файла манифеста Android.

Вы захотите иметь возможность легко запускать приложение в эмуляторе Android и на устройстве из Eclipse, поэтому вам необходимо создать конфигурацию отладки.

Чтобы сделать это в Eclipse, выберите Run-> Debug Configurations ….

Дважды щелкните по опции Android Project.

Назовите вашу новую конфигурацию: «Тест разговорника»

Выберите проект: разговорник

Выбор проекта Android разговорник.

One Minute разговорник отображает локаль, а также несколько строк («Привет», «До свидания», «Пожалуйста», «Спасибо» и «Помощь!») На экране. Поэтому вам нужно добавить кучу строковых ресурсов в файл /res/values/strings.xml. В частности, добавьте одну строку для каждой фразы, а также метку для каждой фразы. Кроме того, добавьте строки для ссылки «Флаг (метка)», «Карта» (метка) и CIA World Factbook (подробнее об этом чуть позже).

Для строк по умолчанию мы используем один из самых распространенных в мире языков — английский. (Конечно, вы можете выбрать другой язык по умолчанию, если хотите.)

Полученный файл strings.xml должен выглядеть примерно так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?xml version=»1.0″ encoding=»utf-8″?>
<resources>
    <string name=»app_name»>The One Minute Phrasebook </string>
 
    <string name=»locale_label»>Locale: </string>
    <string name=»locale»>»World-Wide» </string>
 
    <string name=»hello_label»>Greet Someone: </string>
    <string name=»hello»>Hello!</string>
 
    <string name=»goodbye_label»>Say Farewell: </string>
    <string name=»goodbye»>Goodbye!</string>
 
    <string name=»please_label»>Say Please: </string>
    <string name=»please»>Please </string>
 
    <string name=»thankyou_label»>Thank Someone: </string>
    <string name=»thankyou»>Thank You!
 
    <string name=»help_label»>Call for Aid: </string>
    <string name=»help»>Help!
 
    <string name=»flag_label»>Flag: </string>
    <string name=»map_label»>Map: </string>
 
    <string name=»cia_factbook_label»>CIA World Factbook URL: </string>
    <string name=»cia_factbook_url»>»https://www.cia.gov/library/publications/the-world-factbook/index.html» </string>
</resources>

Это строковые ресурсы по умолчанию, которые используются этим приложением. Многие приложения используют только ресурсы по умолчанию.

Приложение «Разговорник за одну минуту» также требует нескольких других типов ресурсов. В частности:

  • Некоторые ресурсы цвета для текстовых цветов TextView (/res/values/colors.xml)
  • Некоторые ресурсы измерения для размера текста TextView (/res/values/dimens.xml)
  • Два графических файла: один для карты и один для флага (/res/drawable/flag.png и /res/drawable/map.png)

Вы можете добавить эти ресурсы сейчас или при создании макета. Изображения флагов и карт, использованные в этом учебном пособии, были получены из общедоступных изображений, доступных на веб-сайте CIA World Factbook .

В качестве причины по умолчанию мы скажем, что локаль — «Весь мир», и отобразим графическое изображение с набором карт мира и картой планеты.

Настройка ресурсов Android

Далее обратите ваше внимание на разработку пользовательского интерфейса приложения. One Minute Разговорник очень простое приложение с одним экраном. На экране отображаются некоторые полезные фразы, флаг и карта страны, а также ссылка на веб-сайт CIA World Factbook для соответствующей страны.

Интерфейс Android Разговорник.

Примечание. Для этого приложения мы используем профиль виртуального устройства Android (AVD), чтобы точно соответствовать профилю Nexus One с экраном 800×480. Не стесняйтесь создавать AVD, чтобы соответствовать любому Android-устройству, с которым вы можете протестировать.

Это приложение имеет только один экран, определенный в файле /res/layout/main.xml. Это файл, который вам нужно отредактировать.

В этом случае нам нужны красивые отформатированные столбцы, поэтому рассмотрите возможность использования элемента управления TableLayout для форматирования элементов управления TextView и ImageView, содержащих фразу, флаг, карту и ссылку на CIA World Factbook.

Полученный файл макета main.xml должен выглядеть примерно так:

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<?xml version=»1.0″ encoding=»utf-8″?>
<LinearLayout xmlns:android=»http://schemas.android.com/apk/res/android»
    android:orientation=»vertical» android:layout_width=»fill_parent»
    android:layout_height=»fill_parent»>
    <ScrollView android:id=»@+id/ScrollView01″
        android:layout_width=»wrap_content» android:layout_height=»wrap_content»
        android:layout_gravity=»center»>
        <LinearLayout xmlns:android=»http://schemas.android.com/apk/res/android»
            android:orientation=»vertical» android:layout_width=»fill_parent»
            android:layout_height=»fill_parent»>
            <TableLayout android:id=»@+id/TableLayout01″
                android:layout_margin=»@dimen/phrase_margin» android:layout_height=»wrap_content»
                android:layout_width=»fill_parent» android:stretchColumns=»1″>
                <TableRow android:id=»@+id/TableRow01″
                    android:layout_height=»wrap_content» android:layout_width=»wrap_content»>
                    <TextView android:id=»@+id/TextView_LocaleLabel»
                        android:layout_width=»wrap_content» android:layout_height=»wrap_content»
                        android:text=»@string/locale_label» android:textSize=»@dimen/phrase_size»
                        android:textColor=»@color/locale_color»></TextView>
                    <TextView android:id=»@+id/TextView_Locale»
                        android:layout_height=»wrap_content» android:text=»@string/locale»
                        android:textSize=»@dimen/phrase_size» android:textColor=»@color/phrase_color»
                        android:layout_width=»wrap_content» android:layout_gravity=»right»></TextView>
                </TableRow>
                <TableRow android:id=»@+id/TableRow02″
                    android:layout_width=»wrap_content» android:layout_height=»wrap_content»>
                    <TextView android:id=»@+id/TextView_HelloLabel»
                        android:layout_width=»wrap_content» android:layout_height=»wrap_content»
                        android:text=»@string/hello_label» android:textSize=»@dimen/phrase_size»
                        android:textColor=»@color/label_color»></TextView>
                    <TextView android:id=»@+id/TextView_Hello»
                        android:layout_height=»wrap_content» android:text=»@string/hello»
                        android:textSize=»@dimen/phrase_size» android:layout_width=»wrap_content»
                        android:textColor=»@color/phrase_color» android:layout_gravity=»right»></TextView>
                </TableRow>
                <TableRow android:id=»@+id/TableRow03″
                    android:layout_width=»wrap_content» android:layout_height=»wrap_content»>
                    <TextView android:id=»@+id/TextView_GoodbyeLabel»
                        android:layout_width=»wrap_content» android:layout_height=»wrap_content»
                        android:text=»@string/goodbye_label» android:textSize=»@dimen/phrase_size»
                        android:textColor=»@color/label_color»></TextView>
                    <TextView android:id=»@+id/TextView_Goodbye»
                        android:layout_width=»wrap_content» android:layout_height=»wrap_content»
                        android:text=»@string/goodbye» android:textSize=»@dimen/phrase_size»
                        android:textColor=»@color/phrase_color» android:layout_gravity=»right»></TextView>
                </TableRow>
                <TableRow android:id=»@+id/TableRow04″
                    android:layout_width=»wrap_content» android:layout_height=»wrap_content»>
                    <TextView android:id=»@+id/TextView_PleaseLabel»
                        android:layout_width=»wrap_content» android:layout_height=»wrap_content»
                        android:text=»@string/please_label» android:textSize=»@dimen/phrase_size»
                        android:textColor=»@color/label_color»></TextView>
                    <TextView android:id=»@+id/TextView_Please»
                        android:layout_width=»wrap_content» android:layout_height=»wrap_content»
                        android:text=»@string/please» android:textSize=»@dimen/phrase_size»
                        android:textColor=»@color/phrase_color» android:layout_gravity=»right»></TextView>
                </TableRow>
                <TableRow android:id=»@+id/TableRow05″
                    android:layout_width=»wrap_content» android:layout_height=»wrap_content»>
                    <TextView android:id=»@+id/TextView_ThankyouLabel»
                        android:layout_width=»wrap_content» android:layout_height=»wrap_content»
                        android:text=»@string/thankyou_label» android:textSize=»@dimen/phrase_size»
                        android:textColor=»@color/label_color»></TextView>
                    <TextView android:id=»@+id/TextView_Thankyou»
                        android:layout_width=»wrap_content» android:layout_height=»wrap_content»
                        android:text=»@string/thankyou» android:textSize=»@dimen/phrase_size»
                        android:textColor=»@color/phrase_color» android:layout_gravity=»right»></TextView>
                </TableRow>
                <TableRow android:id=»@+id/TableRow06″
                    android:layout_width=»wrap_content» android:layout_height=»wrap_content»>
                    <TextView android:id=»@+id/TextView_HelpLabel»
                        android:layout_width=»wrap_content» android:layout_height=»wrap_content»
                        android:text=»@string/help_label» android:textSize=»@dimen/phrase_size»
                        android:textColor=»@color/label_color»></TextView>
                    <TextView android:id=»@+id/TextView_help»
                        android:layout_width=»wrap_content» android:layout_height=»wrap_content»
                        android:text=»@string/help» android:textSize=»@dimen/phrase_size»
                        android:textColor=»@color/phrase_color» android:layout_gravity=»right»></TextView>
                </TableRow>
            </TableLayout>
            <TableLayout android:id=»@+id/TableLayout02″
                android:layout_margin=»@dimen/phrase_margin» android:layout_height=»wrap_content»
                android:layout_width=»fill_parent»>
                <TableRow android:id=»@+id/TableRow07″
                    android:layout_width=»wrap_content» android:layout_height=»wrap_content»>
                    <TextView android:id=»@+id/TextView_FlagLabel»
                        android:layout_width=»wrap_content» android:layout_height=»wrap_content»
                        android:text=»@string/flag_label» android:textSize=»@dimen/phrase_size»
                        android:textColor=»@color/label_color»></TextView>
                </TableRow>
                <TableRow android:id=»@+id/TableRow08″
                    android:layout_width=»wrap_content» android:layout_height=»wrap_content»>
                    <ImageView android:id=»@+id/ImageView01″
                        android:layout_width=»wrap_content» android:layout_height=»wrap_content»
                        android:src=»@drawable/flag» android:adjustViewBounds=»true»
                        android:saveEnabled=»true»></ImageView>
                </TableRow>
                <TableRow android:id=»@+id/TableRow09″
                    android:layout_width=»wrap_content» android:layout_height=»wrap_content»>
                    <TextView android:id=»@+id/TextView_MapLabel»
                        android:layout_width=»wrap_content» android:layout_height=»wrap_content»
                        android:text=»@string/map_label» android:textSize=»@dimen/phrase_size»
                        android:textColor=»@color/label_color»></TextView>
                </TableRow>
                <TableRow android:id=»@+id/TableRow10″
                    android:layout_width=»wrap_content» android:layout_height=»wrap_content»>
                    <ImageView android:id=»@+id/ImageViewMap»
                        android:layout_width=»wrap_content» android:layout_height=»wrap_content»
                        android:src=»@drawable/map»></ImageView>
                </TableRow>
                <TableRow android:id=»@+id/TableRow11″
                    android:layout_width=»wrap_content» android:layout_height=»wrap_content»>
                    <TextView android:id=»@+id/TextView_CIAFactbookLabel»
                        android:layout_width=»wrap_content» android:layout_height=»wrap_content»
                        android:textSize=»@dimen/phrase_size» android:textColor=»@color/label_color»
                        android:text=»@string/cia_factbook_label»></TextView>
                </TableRow>
                <TableRow android:id=»@+id/TableRow12″
                    android:layout_width=»wrap_content» android:layout_height=»wrap_content»>
                    <TextView android:id=»@+id/TextView_help»
                        android:layout_width=»wrap_content» android:layout_height=»wrap_content»
                        android:textSize=»@dimen/phrase_size» android:textColor=»@color/phrase_color»
                        android:layout_gravity=»right» android:text=»@string/cia_factbook_url»
                        android:autoLink=»web»></TextView>
                </TableRow>
            </TableLayout>
        </LinearLayout>
    </ScrollView>
</LinearLayout>

Пришло время запустить приложение в первый раз. Чтобы сделать это из Eclipse, выберите Run-> Debug Configurations . Выберите конфигурацию теста разговорника и нажмите кнопку «Отладка».

Экран отладки Android.

Теперь пришло время изучить языковые настройки вашего эмулятора или устройства. Чтобы просмотреть и изменить настройки языка / локали на главном экране, нажмите кнопку «Меню» и выберите « Настройки» -> «Язык и клавиатура» -> «Выбрать локаль» .

Попробуйте изменить язык на иностранный язык, с которым вы знакомы.

Предупреждение: имейте в виду, что если вы измените язык и покинете настройки, вам нужно будет вернуться к экрану настроек на этом языке. Запоминание или запись нажатий клавиш для этого может упростить это.

Обратите внимание, как все меню меняются на этот язык. Запустите приложение Разговорник за одну минуту в этой локали. Обратите внимание, что приложение не выглядит иначе, чем до изменения языкового стандарта — оно все еще отображается на английском языке.

Теперь вернитесь к вашему любимому языку. Мой английский (США).

Список языковых фраз для Android.

Примечание. Эмулятор имеет все параметры локали, доступные в данной версии Android SDK. Однако конкретные устройства могут иметь ограниченный набор локалей на выбор.

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

Когда альтернативные ресурсы включены в приложение как часть их пакета, операционная система Android всегда пытается загрузить наиболее конкретные доступные ресурсы.

Альтернативные ресурсы могут создаваться по многим различным критериям, включая, помимо прочего, языки и регионы, характеристики экрана и методы ввода устройства. Некоторые общие альтернативные ресурсы — это языки, локали и ориентация экрана (особенно макеты). Критерии организованы иерархически, и каждый тип критериев можно использовать в качестве суффикса для соответствующего имени каталога ресурсов проекта.

Альтернативные ресурсы должны использовать те же имена, что и ресурсы по умолчанию. Разрешение ресурсов Android лучше всего показать на примере. В этом руководстве мы сосредоточены только на создании альтернативных ресурсов для определенных языков и регионов.

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

Вы можете добавить языковые ресурсы в любой проект, создавая специально названные каталоги проектов. Просто возьмите имя существующего каталога проекта (например, / res / values) и нажмите на тире, за которым следует двухбуквенный код языка, как определено в ISO 639-2 . Например, английский — это en , французский — это fr , испанский — это es , немецкий — это de и т. Д.

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

Каждая из альтернативных строк ресурса должна иметь то же имя, что и используемый по умолчанию ресурс (хранится в /res/values/strings.xml). Операционная система Android выберет наиболее конкретный ресурс, доступный во время выполнения. Вам не нужно предоставлять переводы для всех строк, только те, которые вы хотите изменить при выборе настройки для французскоязычной локали.

Получившийся файл /res/values-fr/strings.xml должен выглядеть примерно так:

1
2
3
4
5
6
7
8
<?xml version=»1.0″ encoding=»utf-8″?>
<resources>
    <string name=»hello»>Bon jour!</string>
    <string name=»goodbye»>Au revoir!</string>
    <string name=»please»>»S’il vous plaît»</string>
    <string name=»thankyou»>Merci!</string>
    <string name=»help»>Au Secours!</string>
</resources>

Обратите внимание, что вам может потребоваться заключить в кавычки строки ресурса, если они сами содержат одинарные кавычки (например, «S’il vous plaît»).

Теперь, когда вы определили французские строковые ресурсы (фразы), которые можно использовать во всех франкоязычных регионах и регионах, вы хотите создать альтернативные строковые ресурсы для конкретных стран: Бельгии, Канады, Франции и Швейцарии.

Каждой стране потребуется:

  • Строка региона региона
  • Строка URL CIA World Factbook

Платформа Android поддерживает языковые альтернативные ресурсы (например, созданные на предыдущем шаге). Однако вы не можете создавать специфичные для региона ресурсы без языка. Вместо этого вы должны включить язык и код страны в имя каталога ресурсов.

Для создания ресурсов, специфичных для региона, вы должны использовать его язык (в данном случае «fr»), после которого ставится тире, за которым следует код региона в форме «rXX», где XX — код региона для страны, как определено Код ISO 3166-1-альфа-2 .

Например, коды языков и регионов для франкоязычных стран, поддерживаемых в Android, будут следующими:

Бельгия: fr-rBE
Канада: фр-рКА
Франция: фр-рфр
Швейцария: фр-рч

Так, например, вы можете создать файл strings.xml в каталоге проекта / res / values-fr-rBE для строковых значений специально для настройки французского языка (Бельгия).

/res/values-fr-rBE/strings.xml может выглядеть так:

1
2
3
4
5
<?xml version=»1.0″ encoding=»utf-8″?>
<resources>
    <string name=»locale»>Belgium</string>
    <string name=»cia_factbook_url»>https://www.cia.gov/library/publications/the-world-factbook/geos/be.html</string>
</resources>

Альтернативные ресурсы могут быть созданы для других типов данных, кроме строк. Вы можете создавать альтернативные ресурсы для любого типа ресурса, включая строки, размеры, цвета, ресурсы для рисования и другие типы. Вы просто используете те же правила иерархии каталогов ресурсов проекта.

Таким образом, чтобы добавить ресурсы для рисования флага и карты для каждой страны (Belguim, Канада, Франция и Швейцария), вам необходимо создать четыре новых каталога в рамках проекта:

  • Сохраните графику бельгийского flag.png и map.png в каталоге / res / drawable-fr-rBE /.
  • Сохраните графические изображения Canadian flag.png и map.png в каталоге / res / drawable-fr-rCA /.
  • Сохраните графику Swiss flag.png и map.png в каталоге / res / drawable-fr-rCH /.
  • Сохраните графику French flag.png и map.png в каталоге / res / drawable-fr-rFR /.

Обратите внимание, что имена файлов для рисования должны точно соответствовать именам файлов для рисования по умолчанию (хранящимся в / res / drawable).

Ваш проект теперь должен быть организован так:

Список проектов Android Project.

В вашем эмуляторе или на вашем устройстве измените Locale на один из французских вариантов (Français (Франция), Français (Канада), Français (Belguim), Français (Швейцария).)

Примечание. Для тех, кто не владеет французским языком, вы можете вернуться в меню настроек локали на главном экране, выбрав: Меню-> Параметры-> Язык и клавир-> Язык и регион .

Перезапустите приложение «Разговорник за одну минуту» и просмотрите результаты. Обратите внимание, как соответствующие французские строки загружаются для всех французских языков. Также обратите внимание, как конкретный регион определяет, какая информация о стране отображается в приложении.

На рисунке показано, что происходит, когда вы выбираете Français (Франция).

Android французский экранный контент.

Интернационализация заставляет проектировать выбор в команде разработчиков. Например, вы создадите один большой проект для всех языков или разбите приложения по регионам? Для некоторых проектов с легкой интернационализацией вы можете выбрать один проект со всеми интернационализированными ресурсами. Для глубокой интернационализации вам может потребоваться реорганизовать проекты, чтобы ни одно приложение не становилось слишком большим или громоздким для пользователя.

Возможно, вы заметили, что за всю эту интернационализацию мы ни разу не коснулись исходных файлов java проекта. Это важно отметить, потому что это означает, что работа по интернационализации приложения может быть поручена не разработчику, который хорошо знает, как использовать Eclipse и инструменты Android, а кому-то еще, кому потребуется некоторое обучение тому, как работает интернационализация Android, как ресурсы могут быть многоуровневыми, а недостатки чрезмерно интернационализируются (что приводит к очень большим пакетным файлам с большим количеством графики и тому подобным). С другой стороны, это дает разработчикам свободу делать то, что у них получается лучше всего: разработку кода.

Наконец, вы, вероятно, заметили, что структура интернационализации Android не идеальна, особенно для стран с несколькими официальными (и неофициальными) языками. Нет смысла включать одну и ту же графику (флаг и карту) в каталоги en-rCA и fr-rCA для англоязычных и франкоязычных канадцев. Однако вы можете обойти эти ограничения, программно определив локаль и загрузив соответствующие графические файлы самостоятельно. Это, однако, для другого урока.

Более полное объяснение разрешения ресурсов Android можно найти в документации по Android SDK здесь .

В этом руководстве вы узнали, как создавать и использовать альтернативные файлы ресурсов с помощью приложения для Android под названием «Разговорник за одну минуту». Это приложение отображает определенные строки и графику в зависимости от языка / локали системы Android. Вы узнали о том, как операционная система Android разрешает ресурсы и выбирает наиболее подходящий ресурс, доступный во время выполнения. Вы также узнали, как эффективно организовать ресурсы, чтобы предоставить вашим пользователям по всему миру наилучшие возможности использования приложений.

Мы надеемся, что вам понравился этот урок, и с нетерпением ждем ваших отзывов!

Разработчики мобильных приложений Лорен Дарси и Шейн Кондер являются соавторами нескольких книг по разработке Android: углубленная книга по программированию под названием « Разработка беспроводных приложений для Android» и « Разработка Android-приложений Sams TeachYourself за 24 часа» . Когда они не пишут, они тратят свое время на разработку мобильного программного обеспечения в своей компании и оказание консультационных услуг. С ними можно связаться по электронной почте androidwirelessdev+mt@gmail.com , через их блог на androidbook.blogspot.com и в Twitter @androidwireless .

Купить Android-разработку беспроводных приложений, 2-е издание Купить Sam's Teach Yourself для Android-разработки приложений в течение 24 часов Код Мамламбо в Код-Каньоне