在 Android SDK 中使用本地化和语言区域代码
为什么这很重要
当 Adapty 为流程选择本地化语言,以及当您读取自定义付费墙的远程配置时,语言区域代码就会发挥作用。
语言区域代码较为复杂,在不同平台之间可能存在差异,因此 Adapty 在其支持的所有平台中统一采用同一套内部标准。了解该标准有助于您预测用户最终会收到哪个本地化版本。
Adapty 的语言区域代码标准
Adapty 使用略经修改的 BCP 47 标准作为语言区域代码规范:每个代码由小写子标签组成,以连字符分隔。示例如下:en(英语)、pt-br(葡萄牙语(巴西))、zh(简体中文)、zh-hant(繁体中文)。
语言区域代码匹配
当 Adapty 为用户查找匹配的本地化语言时,会按以下步骤执行:
- 将语言区域字符串转换为小写,并将所有下划线(
_)替换为连字符(-) - Adapty 查找与完整语言区域代码完全匹配的本地化内容
- 如果未找到匹配项,Adapty 会截取第一个连字符之前的子字符串(例如
pt-br对应pt),并查找匹配的本地化内容 - 如果仍未找到匹配项,Adapty 将返回该流程默认语言区域的内容
这样,'pt_BR'、pt-BR 和 pt-br 都会解析到同一个本地化。
实现本地化
在 SDK v4 中,获取流程时无需传入语言区域代码——getFlow 会返回包含所有本地化内容的流程。
- 在编辑工具中构建的流程:SDK 不会读取设备语言,请在应用中自行解析并通过
AdaptyUI.getFlowConfiguration的locale参数传入。该参数为可选项——省略时流程以en渲染,若流程没有en本地化则使用其默认语言。若请求的本地化语言不存在,视图会静默回退到流程默认语言,所选本地化中缺失的字符串也会从默认语言中补全。
默认使用 en 渲染需要 Android SDK 4.0.1。在 4.0.0 中,省略 locale 会渲染流程的默认本地化。
- 自定义(远程配置)付费墙:
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 的语言代码标准
在语言代码方面,Adapty 使用略作修改的 BCP 47 标准:每个代码由小写子标签组成,以连字符分隔。示例:en(英语)、pt-br(葡萄牙语(巴西))、zh(简体中文)、zh-hant(繁体中文)。
地区代码匹配
当 Adapty 收到客户端 SDK 发来的地区代码请求并开始查找对应的付费墙本地化内容时,会依次执行以下步骤:
- 将传入的地区代码字符串转为小写,并将所有下划线(
_)替换为连字符(-) - 查找与完整地区代码完全匹配的本地化内容
- 若未找到匹配项,则截取第一个连字符前的子字符串(例如
pt-br取pt),并再次查找匹配的本地化内容 - 若仍未找到匹配项,则返回该付费墙默认地区的内容
这样,发送 'pt_BR' 的 iOS 设备、发送 pt-BR 的 Android 设备以及发送 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 服务器究竟会收到什么数据。
如果你仍然决定使用这种方式,请确保已覆盖所有相关的使用场景。