Использование локализаций и кодов локалей в Android SDK
Почему это важно
Коды локали используются, когда Adapty подбирает локализацию для флоу или онбординга, а также когда вы запрашиваете Remote Config для кастомного пейвола.
Коды локали устроены непросто и могут различаться от платформы к платформе, поэтому Adapty придерживается единого внутреннего стандарта для всех поддерживаемых платформ. Понимание этого стандарта поможет вам предсказать, какую локализацию получит пользователь.
Стандарт кодов локали в Adapty
Для кодов локали Adapty использует слегка модифицированный стандарт BCP 47: каждый код состоит из подтегов в нижнем регистре, разделённых дефисами. Примеры: en (английский), pt-br (португальский (Бразилия)), zh (упрощённый китайский), zh-hant (традиционный китайский).
Сопоставление кодов локалей
В SDK v4 флоу и онбординги сопоставляют коды локалей по-разному: флоу локализуются SDK на устройстве, онбординги — сервером Adapty.
Флоу и пейволы
Пейвол, который рендерит Adapty, в SDK v4 доставляется как флоу, поэтому правило ниже распространяется на оба случая.
Сопоставление точное. SDK сравнивает переданный вами код с кодами локализации флоу посимвольно: не меняет регистр, не заменяет подчёркивания (_) на дефисы (-) и не откатывается к языковому subtag. Для флоу с локализацией 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.
Если вы всё же решите использовать этот подход — убедитесь, что охватили все актуальные сценарии.