
Во многих случаях многоязычные пользователи устанавливают системный язык на один язык — например, английский — но хотят выбрать другие языки для конкретных приложений, такие как голландский, китайский или хинди. Чтобы помочь приложениям обеспечить лучший пользовательский опыт, Android 13 представляет следующие функции для приложений, поддерживающих несколько языков:
Системные настройки : централизованное место, где пользователи могут выбрать предпочтительный язык для каждого приложения.
Вы можете настроить приложение таким образом, чтобы оно автоматически генерировало файлы, необходимые для поддержки языковых настроек для каждого приложения, и отображало их в системных настройках. Для получения дополнительной информации см. инструкции по включению автоматической поддержки языка для каждого приложения .
Дополнительные API : Эти общедоступные API, такие как методы
setApplicationLocalesиgetApplicationLocalesвLocaleManager, позволяют приложениям устанавливать язык, отличный от системного языка, во время выполнения.Эти API автоматически синхронизируются с системными настройками; поэтому приложения, использующие эти API для создания пользовательских средств выбора языка внутри приложения, обеспечат пользователям единообразный пользовательский опыт независимо от того, где они выбирают языковые предпочтения. Публичные API также помогают сократить объем шаблонного кода, поддерживают разделение APK-файлов и автоматическое резервное копирование приложений для хранения языковых настроек пользователей на уровне приложения.
Для обеспечения обратной совместимости с предыдущими версиями Android эквивалентные API также доступны в AndroidX. Однако, для Android 12 (уровень API 32) и более ранних версий, обратно совместимые API работают с контекстом AppCompatActivity, а не с контекстом приложения. Доступ к обратно совместимым API осуществляется с помощью Appcompat 1.6.0 или более поздней версии.
Обзор реализации этой функции
В таблице ниже представлены рекомендуемые варианты реализации в зависимости от различных сценариев использования.
| Вариант использования | Рекомендуемая реализация |
|---|---|
| В вашем приложении отсутствует встроенная функция выбора языка. |
|
| В вашем приложении уже есть встроенная функция выбора языка. |
|
Системные настройки для пользователей
Начиная с Android 13, в системных настройках Android есть централизованное место для установки языковых параметров для каждого приложения. Чтобы обеспечить возможность настройки языка вашего приложения в системных настройках на устройствах под управлением Android 13 или выше, включите автоматическую поддержку языка для каждого приложения (рекомендуется) или настройте поддержку вручную .
Включить автоматическую поддержку языков для каждого приложения.
Это рекомендуемый способ добавления языковой поддержки для каждого приложения, поскольку он не требует модификации XML-файлов.
Начиная с Android Studio Giraffe и AGP 8.1, вы можете настроить свое приложение для автоматической поддержки языковых настроек для каждого приложения . На основе ресурсов вашего проекта AGP генерирует файл LocaleConfig и добавляет ссылку на него в итоговый файл манифеста, поэтому вам больше не нужно делать это вручную. AGP использует ресурсы в папках res модулей вашего приложения и любых зависимостей модулей библиотек для определения локалей, которые следует включить в файл LocaleConfig . Это означает, что если вы добавите ресурсы для нового языка в свое приложение, вам не нужно беспокоиться об обновлении файла LocaleConfig .
Обратите внимание, что функция автоматического выбора языка для каждого приложения поддерживает приложения, работающие под управлением Android 13 (уровень API 33) или выше. Для использования этой функции необходимо установить compileSdkVersion равным 33 или выше. Для настройки языковых параметров для более ранних версий Android по-прежнему необходимо использовать API и встроенные средства выбора языка .
Чтобы включить автоматическую поддержку языков для каждого приложения, выполните следующие действия:
- Чтобы включить эту функцию, используйте параметр
generateLocaleConfigв блокеandroidResources {}файлаbuild.gradle.ktsна уровне модуля (файлаbuild.gradle, если вы используете Groovy). По умолчанию эта функция отключена.
Котлин
android {
androidResources {
generateLocaleConfig = true
}
}
Классный
android {
androidResources {
generateLocaleConfig true
}
}
- Укажите языковые настройки по умолчанию:
- В папке
resмодуля приложения создайте новый файл с именемresources.properties. - В файле
resources.propertiesзадайте локаль по умолчанию с помощью меткиunqualifiedResLocale. Чтобы отформатировать имена локалей, см. раздел «Как сформировать имена локалей» .
- В папке
AGP добавляет этот язык по умолчанию, а также любые альтернативные языки , указанные вами с помощью каталогов values-* в папке res , в автоматически сгенерированный файл LocaleConfig .
Как формировать названия локали
Для формирования названий локали объедините код языка с необязательными кодами шрифта и региона, разделяя их дефисом:
- Язык: Используйте двух- или трехбуквенный код ISO 639-2 .
- Скрипт (необязательно): Используйте код ISO 15924 .
- Регион (необязательно): Используйте либо двухбуквенный код ISO 3166-1-alpha-2 , либо трехзначный код UN_M.49 .
Например, если ваш язык по умолчанию — американский английский:
unqualifiedResLocale=en-US
Используйте android:localeConfig , чтобы добавить поддерживаемые языки в системные настройки.
Вы можете вручную настроить свое приложение, чтобы обеспечить возможность выбора языка в системных настройках на устройствах под управлением Android 13 или выше. Для этого создайте XML-файл locale_config и добавьте его в манифест вашего приложения, используя атрибут android:localeConfig . Отсутствие записи android:localeConfig в манифесте означает, что пользователи не должны иметь возможность устанавливать язык вашего приложения независимо от системного языка в своих системных настройках.
Чтобы вручную добавить поддерживаемые вашим приложением языки в системные настройки пользователя:
Создайте файл с именем
res/xml/locale_config.xmlи укажите языки вашего приложения, включая резервный язык , который указан в файлеres/values/strings.xml.Требования к формату см. в разделе «Как формировать названия локалей» . Также см. пример файла
locale_config.xmlсо списком наиболее часто используемых локалей.Например, для приложения, поддерживающего следующие языки, файл
locale_config.xmlследует отформатировать следующим образом:- Английский (США) как крайний запасной вариант.
- Английский (Великобритания)
- Французский
- японский
- Китайский (упрощенный, Макао)
- Китайский (традиционный, Макао)
<?xml version="1.0" encoding="utf-8"?> <locale-config xmlns:android="http://schemas.android.com/apk/res/android"> <locale android:name="en-US"/> <locale android:name="en-GB"/> <locale android:name="fr"/> <locale android:name="ja"/> <locale android:name="zh-Hans-MO"/> <locale android:name="zh-Hant-MO"/> </locale-config>В файл манифеста добавьте строку, указывающую на этот новый файл:
<manifest> ... <application ... android:localeConfig="@xml/locale_config"> </application> </manifest>
Вы можете динамически обновлять localeConfig вашего приложения с помощью LocaleManager.setOverrideLocaleConfig , чтобы настроить набор языков, отображаемых в списке языков для каждого приложения в настройках Android. Это позволяет настраивать список языков для каждого региона, проводить A/B-тесты и предоставлять обновленные языковые настройки, если ваше приложение использует серверную локализацию, как показано в следующем примере:
//For setOverrideLocaleConfig
val localeManager = applicationContext
.getSystemService(LocaleManager::class.java)
localeManager.overrideLocaleConfig = LocaleConfig(
LocaleList.forLanguageTags("en-US,ja-JP,zh-Hans-SG")
)
//For getOverrideLocaleConfig
// The app calls the API to get the override LocaleConfig
val overrideLocaleConfig = localeManager.overrideLocaleConfig
// If the returned overrideLocaleConfig isn't equal to NULL, then the app calls the API to get the supported Locales
val supportedLocales = overrideLocaleConfig.supportedLocales()
Кроме того, теперь IME могут использовать LocaleManager.getApplicationLocales , чтобы узнать язык пользовательского интерфейса текущего приложения и обновить язык клавиатуры, как показано ниже:
val currentAppLocales: LocaleList = applicationContext.getSystemService(LocaleManager::class.java).getApplicationLocales(appPackageName)
Укажите поддерживаемые языки в Gradle.
Если языки еще не указаны, укажите их с помощью свойства resourceConfigurations в файле build.gradle вашего модуля:
android {
...
defaultConfig {
resourceConfigurations += ["en", "en-rGB", "fr", "ja", "b+zh+Hans+MO", "b+zh+Hant+MO"]
}
}
Если свойство resourceConfigurations присутствует, система сборки включает в APK только языковые ресурсы для указанных языков, предотвращая включение переведенных строк из других библиотек, которые могут поддерживать языки, не поддерживаемые вашим приложением. Для получения дополнительной информации см. раздел «Укажите языки, поддерживаемые вашим приложением» .
Как пользователи выбирают язык приложения в системных настройках
Пользователи могут выбрать предпочитаемый язык для каждого приложения через системные настройки. Доступ к этим настройкам можно получить двумя способами:
Доступ осуществляется через системные настройки.
Настройки > Система > Языки и ввод > Языки приложений > (выберите приложение)
Доступ через настройки приложений.
Настройки > Приложения > (выберите приложение) > Язык
Обработка выбора языка в приложении
Для приложений, которые уже имеют встроенный язык выбора языка или хотят его использовать, вместо собственной логики приложения используйте общедоступные API для обработки установки и получения предпочтительного языка пользователя. Если вы используете общедоступные API для встроенного языка выбора языка, системные настройки устройства автоматически обновляются в соответствии с языком, выбранным пользователем в вашем приложении.
Реализация с использованием Jetpack Compose
Для приложений, полностью созданных с помощью Jetpack Compose, система автоматически обрабатывает обновления пользовательского интерфейса при изменении локали приложения. Вызов API для установки нового языка запускает изменение конфигурации. Compose реагирует, перестраивая пользовательский интерфейс и автоматически разрешая все вызовы stringResource с использованием новой локали.
Для обеспечения обратной совместимости с Android 12 (уровень API 32) и более ранними версиями мы настоятельно рекомендуем использовать библиотеку поддержки AndroidX ( AppCompatDelegate ) при реализации встроенного средства выбора языка. При использовании этого подхода активность, в которой размещается ваш Compose UI, должна наследовать AppCompatActivity . Однако при необходимости вы также можете реализовать API фреймворка напрямую .
Приведённый ниже фрагмент кода демонстрирует пример того, как считать текущую локаль приложения и установить новую внутри составной функции:
import androidx.appcompat.app.AppCompatDelegate
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.core.os.LocaleListCompat
@Composable
fun LanguageSelector() {
// Retrieve the currently configured app locale.
// If no app-specific locale is set, LocaleListCompat.get(0) returns null,
// so we safely fall back to a default (e.g., "en").
val appLocales = AppCompatDelegate.getApplicationLocales()
val currentLocaleTag = appLocales.get(0)?.toLanguageTag() ?: "en"
// Example UI: A button to toggle between English and Spanish
Button(
onClick = {
val newLanguageTag = if (currentLocaleTag == "en") "es" else "en"
val localeList = LocaleListCompat.forLanguageTags(newLanguageTag)
// Setting the locale re-creates the Activity by default,
// which automatically applies the new configuration to Compose.
AppCompatDelegate.setApplicationLocales(localeList)
}
) {
Text(
text = if (currentLocaleTag == "en") "Switch to Spanish" else "Switch to English"
)
}
}
Чтобы установить предпочтительный язык для пользователя, вам нужно попросить пользователя выбрать языковой стандарт в окне выбора языка, а затем установить это значение в системе:
val appLocale: LocaleListCompat = LocaleListCompat.forLanguageTags("xx-YY")
// Call this on the main thread as it may require Activity.restart()
AppCompatDelegate.setApplicationLocales(appLocale)
Обратите внимание, что вызов setApplicationLocales приводит к повторному созданию вашей Activity , если только ваше приложение не обрабатывает изменения конфигурации локали самостоятельно.
Используйте AppCompatDelegate.getApplicationLocales чтобы получить предпочитаемый пользователем языковой стандарт. Пользователь мог выбрать языковой стандарт приложения в системных настройках или в вашем встроенном средстве выбора языка.
Поддерживаются Android 12 и более ранние версии.
Для поддержки устройств под управлением Android 12 (уровень API 32) и ниже, укажите AndroidX обрабатывать хранилище локали, установив значение autoStoreLocales равным true и android:enabled равным false в записи манифеста для службы AppLocalesMetadataHolderService вашего приложения, как показано в следующем фрагменте кода:
<application
...
<service
android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
android:enabled="false"
android:exported="false">
<meta-data
android:name="autoStoreLocales"
android:value="true" />
</service>
...
</application>
Обратите внимание, что установка значения autoStoreLocales в true приводит к блокирующему чтению в основном потоке и может вызвать нарушение правил StrictMode diskRead и diskWrite если вы регистрируете нарушения потоков. Дополнительную информацию см. в AppCompatDelegate.setApplicationLocales .
Пользовательская обработка хранения
Отсутствие записи в манифесте или установка autoStoreLocales в значение false сигнализирует о том, что вы управляете собственным хранилищем. В этом случае необходимо указать сохраненные локали перед onCreate в жизненном цикле активности и перенаправить вызовы AppCompatDelegate.setApplicationLocales в Android 12 (уровень API 32) или более ранних версиях.
Если ваше приложение использует собственное хранилище языковых настроек, мы рекомендуем использовать одноразовую передачу данных между вашим собственным хранилищем языковых настроек и autoStoreLocales , чтобы пользователи могли продолжать пользоваться вашим приложением на предпочитаемом ими языке. Это особенно актуально в случаях, когда ваше приложение запускается впервые после обновления устройства до Android 13. В этом случае вы можете предоставить уже существующие, запрошенные пользователем языковые настройки, получив их из собственного хранилища и передав в AppCompatDelegate.setApplicationLocales .
Реализация с использованием API фреймворка Android.
Хотя мы настоятельно рекомендуем использовать библиотеку поддержки AndroidX для реализации выбора языка внутри приложений, вы также можете использовать методы setApplicationLocales и getApplicationLocales из фреймворка Android для устройств под управлением Android 13.
Приведенный ниже фрагмент кода демонстрирует, как установить и получить предпочтительный язык пользователя с помощью системной службы LocaleManager :
import android.app.LocaleManager
import android.content.Context
import android.os.Build
import android.os.LocaleList
import androidx.annotation.RequiresApi
import java.util.Locale
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
fun setAppLanguage(context: Context, languageTag: String) {
// 1. Retrieve the system service
val localeManager = context.getSystemService(LocaleManager::class.java)
// 2. Create a LocaleList from the language tag (e.g., "es-ES" or "ja")
val localeList = LocaleList(Locale.forLanguageTag(languageTag))
// 3. Set the locale. The system automatically updates the locale and
// restarts the app, including any necessary configuration updates.
localeManager.applicationLocales = localeList
}
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
fun getAppLanguage(context: Context): String {
val localeManager = context.getSystemService(LocaleManager::class.java)
val currentLocales = localeManager.applicationLocales
// Return the primary app locale, or fall back to the system default
return if (!currentLocales.isEmpty) {
currentLocales.get(0).toLanguageTag()
} else {
Locale.getDefault().toLanguageTag()
}
}
Дополнительные передовые методы
Обратите внимание на следующие рекомендации.
При вызове Intent в другом приложении учитывайте язык интерфейса.
Интенты, ориентированные на язык, могут позволить вам указать язык, на котором должно работать вызываемое приложение. Одним из примеров является функция EXTRA_LANGUAGE из API распознавания речи.
Обратите внимание на заголовок Accept-Language во вкладке «Пользовательские настройки» в Chrome.
Рекомендуется добавить заголовок Accept-Language через Browser.EXTRA_HEADERS , чтобы при открытии пользовательской вкладки Chrome веб-страница открывалась на языке вашего приложения.
Если вы удалите языковые настройки для каждого приложения в системных параметрах, ваш языковой стандарт приложения вернется к системному языку.
Если вы удалите языковые настройки вашего приложения из системных параметров (удалив android:localeConfig из файла AndroidManifest.xml вашего приложения), пользователи не смогут легко вернуть язык приложения к системному значению по умолчанию.
По этой причине, если вы удалите android:localeConfig , рассмотрите возможность сброса локали приложения до системной локали с помощью LocaleListCompat.getEmptyLocaleList или LocaleList.getEmptyLocaleList , как показано в следующем фрагменте кода:
// Use the AndroidX APIs to reset to the system locale for backward and forward compatibility
AppCompatDelegate.setApplicationLocales(
LocaleListCompat.getEmptyLocaleList()
)
// Or use the Framework APIs for Android 13 and above to reset to the system locale
val context = LocalContext.current
context.getSystemService(LocaleManager::class.java)
.applicationLocales = LocaleList.getEmptyLocaleList()
Пример файла locale_config.xml
По умолчанию Android включает системные переводы из проекта Android Open Source Project (AOSP) для стандартного набора наиболее часто используемых языковых версий. Пример файла locale_config.xml , приведенный в этом разделе, демонстрирует рекомендуемый формат для каждой из этих языковых версий. Используйте этот пример, чтобы создать собственный файл locale_config.xml для набора языков, поддерживаемых вашим приложением.
<?xml version="1.0" encoding="utf-8"?>
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
<locale android:name="af"/> <!-- Afrikaans -->
<locale android:name="am"/> <!-- Amharic -->
<locale android:name="ar"/> <!-- Arabic -->
<locale android:name="as"/> <!-- Assamese -->
<locale android:name="az"/> <!-- Azerbaijani -->
<locale android:name="be"/> <!-- Belarusian -->
<locale android:name="bg"/> <!-- Bulgarian -->
<locale android:name="bn"/> <!-- Bengali -->
<locale android:name="bs"/> <!-- Bosnian -->
<locale android:name="ca"/> <!-- Catalan -->
<locale android:name="cs"/> <!-- Czech -->
<locale android:name="da"/> <!-- Danish -->
<locale android:name="de"/> <!-- German -->
<locale android:name="el"/> <!-- Greek -->
<locale android:name="en-AU"/> <!-- English (Australia) -->
<locale android:name="en-CA"/> <!-- English (Canada) -->
<locale android:name="en-GB"/> <!-- English (United Kingdom) -->
<locale android:name="en-IN"/> <!-- English (India) -->
<locale android:name="en-US"/> <!-- English (United States) -->
<locale android:name="es"/> <!-- Spanish (Spain) -->
<locale android:name="es-US"/> <!-- Spanish (United States) -->
<locale android:name="et"/> <!-- Estonian -->
<locale android:name="eu"/> <!-- Basque -->
<locale android:name="fa"/> <!-- Farsi -->
<locale android:name="fi"/> <!-- Finnish -->
<locale android:name="fil"/> <!-- Filipino -->
<locale android:name="fr"/> <!-- French (France) -->
<locale android:name="fr-CA"/> <!-- French (Canada) -->
<locale android:name="gl"/> <!-- Galician -->
<locale android:name="gu"/> <!-- Gujarati -->
<locale android:name="hi"/> <!-- Hindi -->
<locale android:name="hr"/> <!-- Croatian -->
<locale android:name="hu"/> <!-- Hungarian -->
<locale android:name="hy"/> <!-- Armenian -->
<locale android:name="in"/> <!-- Indonesian -->
<locale android:name="is"/> <!-- Icelandic -->
<locale android:name="it"/> <!-- Italian -->
<locale android:name="iw"/> <!-- Hebrew -->
<locale android:name="ja"/> <!-- Japanese -->
<locale android:name="ka"/> <!-- Georgian -->
<locale android:name="kk"/> <!-- Kazakh -->
<locale android:name="km"/> <!-- Khmer -->
<locale android:name="kn"/> <!-- Kannada -->
<locale android:name="ko"/> <!-- Korean -->
<locale android:name="ky"/> <!-- Kyrgyz -->
<locale android:name="lo"/> <!-- Lao -->
<locale android:name="lt"/> <!-- Lithuanian -->
<locale android:name="lv"/> <!-- Latvian -->
<locale android:name="mk"/> <!-- Macedonian -->
<locale android:name="ml"/> <!-- Malayalam -->
<locale android:name="mn"/> <!-- Mongolian -->
<locale android:name="mr"/> <!-- Marathi -->
<locale android:name="ms"/> <!-- Malay -->
<locale android:name="my"/> <!-- Burmese -->
<locale android:name="nb"/> <!-- Norwegian -->
<locale android:name="ne"/> <!-- Nepali -->
<locale android:name="nl"/> <!-- Dutch -->
<locale android:name="or"/> <!-- Odia -->
<locale android:name="pa"/> <!-- Punjabi -->
<locale android:name="pl"/> <!-- Polish -->
<locale android:name="pt-BR"/> <!-- Portuguese (Brazil) -->
<locale android:name="pt-PT"/> <!-- Portuguese (Portugal) -->
<locale android:name="ro"/> <!-- Romanian -->
<locale android:name="ru"/> <!-- Russian -->
<locale android:name="si"/> <!-- Sinhala -->
<locale android:name="sk"/> <!-- Slovak -->
<locale android:name="sl"/> <!-- Slovenian -->
<locale android:name="sq"/> <!-- Albanian -->
<locale android:name="sr"/> <!-- Serbian (Cyrillic) -->
<locale android:name="sr-Latn"/> <!-- Serbian (Latin) -->
<locale android:name="sv"/> <!-- Swedish -->
<locale android:name="sw"/> <!-- Swahili -->
<locale android:name="ta"/> <!-- Tamil -->
<locale android:name="te"/> <!-- Telugu -->
<locale android:name="th"/> <!-- Thai -->
<locale android:name="tr"/> <!-- Turkish -->
<locale android:name="uk"/> <!-- Ukrainian -->
<locale android:name="ur"/> <!-- Urdu -->
<locale android:name="uz"/> <!-- Uzbek -->
<locale android:name="vi"/> <!-- Vietnamese -->
<locale android:name="zh-Hans"/> <!-- Chinese (Simplified) -->
<locale android:name="zh-Hant"/> <!-- Chinese (Traditional) -->
<locale android:name="zu"/> <!-- Zulu -->
</locale-config>
Дополнительные ресурсы
Для получения дополнительной информации ознакомьтесь с примерами кода, статьями в блоге и видеороликами.
- Блог « Настройки языка для каждого приложения. Часть 1»
- Настройки языка для каждого приложения. Часть 2. Блог.
- Видео о создании многоязычного мира
- Ресурсы в Compose