Использование локализаций и кодов локалей в Android SDK
Почему это важно
Коды локали используются, когда Adapty подбирает локализацию для флоу или онбординга, а также когда вы запрашиваете Remote Config для кастомного пейвола.
Коды локали устроены непросто и могут различаться от платформы к платформе, поэтому Adapty придерживается единого внутреннего стандарта для всех поддерживаемых платформ. Понимание этого стандарта поможет вам предсказать, какую локализацию получит пользователь.
Стандарт кодов локали в Adapty
Для кодов локали Adapty использует слегка модифицированный стандарт BCP 47: каждый код состоит из подтегов в нижнем регистре, разделённых дефисами. Примеры: en (английский), pt-br (португальский (Бразилия)), zh (упрощённый китайский), zh-hant (традиционный китайский).
Сопоставление кодов локалей
В SDK v4 флоу и онбординги сопоставляют коды локалей по-разному: флоу локализуются SDK на устройстве, онбординги — сервером Adapty.
Флоу и пейволы Paywall Builder
Пейвол, созданный в Paywall Builder, в SDK v4 доставляется как флоу, поэтому правило ниже распространяется на оба случая.
Совпадение точное. SDK сравнивает переданный вами код с кодами локализации флоу посимвольно: регистр не меняет, подчёркивания (_) на дефисы (-) не заменяет и к языковому субтегу не откатывается. Для флоу с локализацией pt-br подойдёт только pt-br: pt-BR, pt_BR и pt-PT — не подойдут.
Если код не совпадает ни с одной локализацией, флоу отображается в локализации по умолчанию — SDK не возвращает ошибку и не записывает предупреждение.
Если код совпадает, Adapty объединяет найденную локализацию с локализацией по умолчанию: строки и ресурсы, не определённые в найденной локализации, берутся из локализации по умолчанию.
Отсутствие кода локали не равнозначно запросу локализации флоу по умолчанию: SDK подставляет фиксированный en. Флоу, у которого локаль по умолчанию — de, всё равно отобразится на en, если у него есть локализация en, и лишь при её отсутствии вернётся к de. Это относится к Android SDK версии 4.0.1 и выше — в версии 4.0.0 отсутствие кода отображает локализацию флоу по умолчанию.
Передавайте код локали точно так, как он настроен в дашборде — строчные буквы, разделённые дефисами. Не передавайте системный идентификатор локали как есть: Locale.getDefault().toLanguageTag() возвращает pt-BR, а Locale.getDefault().toString() возвращает pt_BR, и оба варианта приводят к использованию локализации по умолчанию. Преобразуйте значение в приложении перед тем, как передавать его.
Онбординги
Онбординги локализуются на сервере, и серверные правила допускают другие форматы. Когда вы передаёте locale в getOnboarding:
- Строка локали приводится к нижнему регистру, а все символы подчёркивания (
_) заменяются дефисами (-) - Adapty ищет локализацию с полностью совпадающим кодом локали
- Если совпадение не найдено, Adapty берёт подстроку до первого дефиса (
ptдляpt-br) и ищет соответствующую локализацию - Если совпадение снова не найдено, Adapty возвращает контент для локали онбординга по умолчанию
Таким образом, pt_BR, pt-BR и pt-br — все они указывают на одну и ту же локализацию онбординга.
Реализация локализаций
В SDK v4 вы не передаёте код локали при получении флоу — getFlow возвращает флоу со всеми его локализациями.
- Флоу, созданные в билдере: SDK не считывает локаль устройства, поэтому определите её в своём приложении и передайте в аргумент
localeметодаAdaptyUI.getFlowConfiguration. Аргумент необязательный — если его не передать, флоу отобразится наenили на языке по умолчанию, если локализацияenне настроена. - Кастомные пейволы (Remote Config):
getFlowвозвращает все настроенные локализации вflow.remoteConfigs. Каждая запись содержит кодlocaleи содержимое конфига (jsonStringили разобранныйdataMap). Выберите запись, соответствующую пользователю, с собственной логикой фолбэка:
Adapty.getFlow("YOUR_PLACEMENT_ID") { result ->
when (result) {
is AdaptyResult.Success -> {
val flow = result.value
val config = flow.remoteConfigs.firstOrNull { it.locale == "en" }
?: flow.remoteConfigs.firstOrNull()
// read your values from config?.dataMap
}
is AdaptyResult.Error -> {
// handle the error
}
}
}Adapty хранит коды locale в формате, описанном в разделе Стандарт кодов локалей в Adapty. SDK не сопоставляет Remote Config с локалью, поэтому выбор нужной записи остаётся за вашим приложением.
Почему это важно
Есть несколько сценариев, когда в игру вступают коды локалей — например, когда нужно получить правильный пейвол для текущей локализации приложения.
Поскольку коды локалей устроены сложно и могут различаться от платформы к платформе, мы опираемся на внутренний стандарт для всех поддерживаемых платформ. Но именно из-за этой сложности важно чётко понимать, что именно вы отправляете на наш сервер для получения нужной локализации и что происходит дальше — чтобы вы всегда получали именно то, что ожидаете.
Стандарт кодов локалей в Adapty
Для кодов локалей Adapty использует немного изменённый стандарт BCP 47: каждый код состоит из подтегов в нижнем регистре, разделённых дефисами. Примеры: en (английский), pt-br (португальский (Бразилия)), zh (упрощённый китайский), zh-hant (традиционный китайский).
Сопоставление кода локали
Когда Adapty получает вызов от клиентского SDK с кодом локали и начинает искать соответствующую локализацию пейвола, происходит следующее:
- Входящая строка локали приводится к нижнему регистру, а все символы подчёркивания (
_) заменяются дефисами (-) - Затем выполняется поиск локализации с полностью совпадающим кодом локали
- Если совпадение не найдено, берётся подстрока до первого дефиса (
ptдляpt-br) и выполняется поиск соответствующей локализации - Если совпадение снова не найдено, возвращается контент для локали по умолчанию данного пейвола
Таким образом устройство iOS, отправившее 'pt_BR', устройство Android, отправившее pt-BR, и другое устройство, отправившее pt-br, получат одинаковый результат.
Рекомендуемый способ реализации локализаций
Если вас интересуют локализации, скорее всего, вы уже работаете с файлами локализованных строк в своём проекте. В таком случае мы рекомендуем добавить в каждый из этих файлов пару ключ-значение с нужным кодом локали Adapty для соответствующей локализации, а затем извлекать значение по этому ключу при вызове нашего SDK:
// 1. Modify your strings.xml files
/*
strings.xml - Spanish
*/
<string name="adapty_paywalls_locale">es</string>
/*
strings.xml - Portuguese (Brazil)
*/
<string name="adapty_paywalls_locale">pt-br</string>
// 2. Extract and use the locale code
val localeCode = context.getString(R.string.adapty_paywalls_locale)
// pass locale code to AdaptyUI.getViewConfiguration or Adapty.getPaywall methodЭто позволяет полностью контролировать, какая локализация будет загружена для каждого пользователя вашего приложения.
Альтернативный способ реализации локализаций
Похожего (но не идентичного) результата можно добиться без явного определения кодов локали для каждой локализации. Для этого можно извлечь код локали из других объектов, предоставляемых платформой:
val locale = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
context.resources.configuration.locales[0]
else
context.resources.configuration.locale
val localeCode = locale.toLanguageTag()
// pass locale code to AdaptyUI.getViewConfiguration or Adapty.getPaywall methodОбратите внимание, что мы не рекомендуем этот подход, поскольку сложно предсказать, что именно получит сервер Adapty.
Если вы всё же решили использовать этот подход — убедитесь, что охватили все соответствующие сценарии.