Android SDKでローカライズとロケールコードを使用する

これが重要な理由

ロケールコードは、Adapty がフローまたはオンボーディングのローカライズを選択するときと、カスタムペイウォール用のリモートコンフィグを読み取るときに使用されます。

ロケールコードはプラットフォームごとに異なる場合があり複雑なため、Adapty はサポートするすべてのプラットフォームで共通の内部標準に依存しています。この標準を理解することで、ユーザーがどのローカライズを受け取るかを予測できます。

Adapty のロケールコード標準

ロケールコードには、Adapty は若干修正した BCP 47 標準 を使用しています。各コードは小文字のサブタグで構成され、ハイフンで区切られます。例:en(英語)、pt-br(ポルトガル語(ブラジル))、zh(簡体字中国語)、zh-hant(繁体字中国語)。

ロケールコードのマッチング

SDK v4では、フローとオンボーディングのロケールコードのマッチング方法が異なります。フローはデバイス上のSDKによってローカライズされ、オンボーディングはAdaptyサーバーによってローカライズされます。

フローとペイウォールビルダーのペイウォール

ペイウォールビルダーで作成されたペイウォールは、SDK v4ではフローとして配信されます。そのため、以下のルールは両方に適用されます。

マッチングは完全一致です。SDKは渡されたコードとフローのローカライゼーションコードを1文字ずつ比較します。大文字・小文字の変換は行わず、アンダースコア(_)とハイフン(-)の置き換えも行わず、言語サブタグへのフォールバックもありません。pt-br のローカライゼーションを持つフローに一致するのは pt-br のみです。pt-BRpt_BRpt-PT はいずれも一致しません。

コードがどのローカライゼーションにも一致しない場合、フローはデフォルトロケールで静かにレンダリングされます — SDKはエラーを返さず、警告もログに記録しません。

コードが一致する場合、Adaptyはそのローカライゼーションをデフォルトのものとマージします:一致したローカライゼーションで定義されていない文字列やアセットは、デフォルトのローカライゼーションから取得されます。

ロケールコードを省略することは、フローのデフォルトローカライゼーションを要求することとは異なります。省略した場合、SDKは固定で en を使用します。デフォルトロケールが de のフローでも、en のローカライゼーションが存在する場合は en で表示され、存在しない場合にのみ de にフォールバックします。この動作は Android SDK 4.0.1 以降に適用されます。4.0.0 では、コードを省略するとフローのデフォルトローカライゼーションで表示されます。

Warning

ダッシュボードで設定されているとおりのロケールコードを渡してください。小文字のサブタグをハイフンで区切った形式です。システムのロケール識別子をそのまま渡さないでください。Locale.getDefault().toLanguageTag()pt-BR を返し、Locale.getDefault().toString()pt_BR を返しますが、どちらもデフォルトのローカライゼーションにフォールバックします。アプリ内で値を変換してから渡してください。

オンボーディング

オンボーディングはサーバー側でローカライズされており、サーバーのルールは他のフォーマットも許容します。getOnboardinglocale を渡すと、次の処理が行われます:

  1. ロケール文字列は小文字に変換され、アンダースコア(_)はすべてハイフン(-)に置換されます
  2. Adapty は完全に一致するロケールコードのローカライズを検索します
  3. 一致するものが見つからない場合、最初のハイフンより前の部分文字列(pt-br なら pt)を取り出し、一致するローカライズを検索します
  4. それでも一致するものが見つからない場合、Adapty はオンボーディングのデフォルトロケールのコンテンツを返します

このようにすることで、pt_BRpt-BRpt-br はすべて同じオンボーディングのローカライゼーションに解決されます。

ローカライズの実装

SDK v4 では、フローを取得する際にロケールコードを渡す必要はありません。getFlow はすべてのローカライズを含むフローを返します。

  • ビルダーで作成したフロー: SDKはデバイスのロケールを自動的に読み取りません。アプリ側でロケールを解決し、AdaptyUI.getFlowConfigurationlocale引数として渡してください。この引数は省略可能です。省略した場合、フローはenでレンダリングされます。ただし、フローにenローカライズがない場合はデフォルトロケールが使用されます。
  • カスタム(リモートコンフィグ)ペイウォール: 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は、AdaptyにおけるLocaleコードの標準で説明されているフォーマットでlocaleコードを保存します。SDKはリモートコンフィグをlocaleに対して照合しないため、どのエントリを適用するかはアプリ側で決定します。

なぜこれが重要なのか

ロケールコードが関係するシナリオはいくつかあります。たとえば、アプリの現在のローカライゼーションに合ったペイウォールを取得しようとする場合などです。

ロケールコードはプラットフォームによって異なる複雑な仕様を持つため、Adapty ではサポートするすべてのプラットフォームに共通の内部標準を採用しています。ただし、コードが複雑であるため、サーバーに送信している内容と、その後どのように処理されて正しいローカライゼーションが返されるかを正確に理解しておくことが非常に重要です。そうすることで、常に期待どおりの結果を受け取れます。

Adaptyにおけるロケールコードの規格

ロケールコードについて、AdaptyはBCP 47規格を一部改変した形式を採用しています。各コードはハイフンで区切られた小文字のサブタグで構成されます。例:en(英語)、pt-br(ポルトガル語(ブラジル))、zh(簡体字中国語)、zh-hant(繁体字中国語)。

ロケールコードのマッチング

Adapty がクライアントサイド SDK からロケールコードを受け取り、ペイウォールの対応するローカライズを検索する際、以下の処理が行われます。

  1. 受信したロケール文字列が小文字に変換され、アンダースコア(_)がすべてハイフン(-)に置き換えられます
  2. 完全に一致するロケールコードのローカライズを検索します
  3. 一致するものが見つからない場合、最初のハイフンより前の部分文字列(pt-br の場合は pt)を取り出して、一致するローカライズを検索します
  4. それでも一致するものが見つからない場合、ペイウォールのデフォルトロケールのコンテンツを返します

これにより、'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のサーバーが何を受け取るかを正確に予測することが難しいため、このアプローチは推奨しません。

それでもこのアプローチを使用する場合は、関連するすべてのユースケースに対応していることを確認してください。