> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kameleoon.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Android SDK

> Kameleoon Android SDK を統合して、ネイティブ Android アプリケーションで実験を実行し、フィーチャーフラグを有効化します。

Kameleoon Android SDK を使用すると、ネイティブモバイル Android アプリケーション上でフィーチャーフラグを実行できます。Android SDK は Kotlin と Java の両方に対応しています。SDK はアプリケーションへの統合が簡単で、メモリとネットワークの使用量も少ないです。

**はじめに**: 開始するには、[開発者ガイド](#開発者ガイド) を参照してください。

**変更履歴**: Android SDK の最新バージョン: 4.26.0 [変更履歴](https://github.com/Kameleoon/client-android/blob/master/CHANGELOG.md)

**SDK メソッド**: Android SDK メソッドの完全なリファレンスドキュメントについては、[リファレンス](#リファレンス) セクションを参照してください。

## 開発者ガイド

このセクションに従って、Android アプリに Android SDK をインストールおよび構成し、高度な機能について学びます。

### はじめに

以下の手順に従って、アプリケーションに Kameleoon Android SDK をインストールおよび構成します。

#### インストール

Android アプリの `build.gradle` ファイルに以下の依存関係を追加することで、Android SDK をインストールできます。

```java theme={null}
dependencies {
  implementation 'com.kameleoon:kameleoon-client-android:4.20.0'
}
```

#### 追加の設定

SDK の動作をカスタマイズするには、`.properties` 設定ファイルを作成します。プロパティファイルの名前と場所は重要です。

* アプリの `assets/` ディレクトリにファイルを作成します。
* ファイル名は `kameleoon-client.properties` とします。

[サンプル設定ファイル](/assets/developer-docs/sdks/mobile-sdks/client-configs/kameleoon-client.properties) をダウンロードすることもできます。

設定可能なプロパティは次のとおりです。

| キー                                                                                         | 説明                                                                                                                                                                                                                                                                                                                                                                                                                                                               | デフォルト値              |
| ------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- |
| `refreshIntervalMinute` / `refresh_interval_minute` (*オプション*)                              | SDK がアクティブな実験やフィーチャーフラグの構成を取得する更新間隔(分単位)を指定します。この値により、フィーチャーフラグの有効化/無効化や実験の開始などの変更が伝播される最大時間が決まります。指定しない場合、デフォルトの間隔は 60 分です。さらに、サーバー送信イベント (SSE) を使用して新しい設定を SDK に自動的にプッシュし、リアルタイムで適用する [ストリーミングモード](/developer-docs/feature-experimentation/technical-reference/technical-considerations/#streaming-premium-option) も利用可能です。                                                                                                                                    | `60` 分              |
| `dataExpirationIntervalMinute` / `data_expiration_interval_minute` (*オプション*)               | SDK が訪問者とそれに関連するデータを保存する所定の期間(分単位)を指定します。各データインスタンスは個別に評価されるため、SDK が自動的にデータを削除するまでの保存時間を設定できます。間隔が指定されていない場合、SDK はデバイスからデータを自動的に削除しません。                                                                                                                                                                                                                                                                                                                          | `Integer.MAX_VALUE` |
| `defaultTimeoutMillisecond` / `default_timeout_millisecond` (*オプション*)                      | SDK からのネットワークリクエストがタイムアウトするまでの時間間隔(ミリ秒単位)を指定します。安定した接続がない場合は、値を `30000` ミリ秒 (30 秒) 以上に設定してください。一部のメソッドにはメソッド固有のタイムアウトのための追加パラメータがありますが、明示的に指定しない場合はデフォルト値が使用されます。                                                                                                                                                                                                                                                                                                | `10000` ミリ秒         |
| `trackingIntervalMillisecond` / `tracking_interval_millisecond` (*オプション*)                  | トラッキングリクエストの間隔(ミリ秒単位)を指定します。フィーチャーフラグで評価された、またはデータがフラッシュされたすべての訪問者がこのトラッキングリクエストに含まれ、間隔ごとに 1 回実行されます。最小値は `1000` ミリ秒、最大値は `5000` ミリ秒です。                                                                                                                                                                                                                                                                                                                          | `1000` ミリ秒          |
| `environment` / `environment` (*オプション*)                                                    | マルチ環境の実験とフィーチャーフラグを使用するお客様向けに、このオプションでは使用するフィーチャーフラグ構成を指定します。デフォルトでは、各フィーチャーフラグには `production`、`staging`、`development` のオプションがあります。指定しない場合、デフォルト値は `production` です。[詳細情報](/user-manual/experimentation/feature-experimentation/configure-your-feature-flags/manage-environments)。                                                                                                                                                                                | `nil`               |
| `isUniqueIdentifier` / `is_unique_identifier` (*オプション*)                                    | 指定された `visitorCode` が一意の識別子であることを示します。                                                                                                                                                                                                                                                                                                                                                                                                                           | `false`             |
| `networkDomain` / `network_domain` (*オプション*)                                               | SDK が送信リクエストに使用するカスタムドメイン。多くの場合プロキシ用です。有効なドメイン (例: example.com または sub.example.com) である必要があります。無効な形式の場合は、Kameleoon のデフォルト値が使用されます。                                                                                                                                                                                                                                                                                                                               | `nil`               |
| `defaultDataFile` / `default_datafile` (*オプション*)                                           | `default_datafile` 機能により、キャッシュされたデータファイルが存在しない場合にフォールバック構成を提供することで、Kameleoon SDK が常に **READY** 状態であることを保証します。開発者は、`https://sdk-config.kameleoon.eu/v3/<sitecode>` から有効な構成を取得し、初期化時に `default_datafile` として渡すことで、構成を事前にロードできます。`dateModified` タイムスタンプ(ミリ秒単位)が指定され、キャッシュされたバージョンよりも新しい場合、SDK はキャッシュされたバージョンの代わりにデフォルトのデータファイルを使用します。**`dateModified` が省略された場合、デフォルトのデータファイルはキャッシュされたバージョンが存在しない場合にのみ適用されます**。これにより、SDK は常にデフォルト、キャッシュ済み、または更新済みの有効な構成を持つことが保証されます。 | `nil`               |
| `activityTrackingIntervalMillisecond` / `activity_tracking_interval_millisecond` (*オプション*) | SDK が訪問者のセッションを延長するためにアクティビティイベントを送信する頻度を設定します。最小値およびデフォルト値はいずれも `60 000` ミリ秒で、これより低い 0 以外の値は無視され、代わりにデフォルト値が適用されます。`0` に設定すると、定期的なアクティビティトラッキングは無効になり、この場合はアプリケーション起動時にアクティビティイベントが 1 回だけ送信されます。この値の変更には副作用があるため、事前に [このセクション](#using-activitytrackingintervalmillisecond) を確認してください。                                                                                                                                                                           | `60 000` ミリ秒        |

<Note>
  `visitorCode` を指定して `isUniqueIdentifier` パラメータを `true` に設定した場合、SDK メソッドは `visitorCode` の値を一意の訪問者識別子として使用します。これは [クロスデバイス実験](/developer-docs/cross-device-experimentation) に便利です。SDK は、フラッシュされたデータを指定された識別子に関連付けられた訪問者にリンクします。

  `isUniqueIdentifier` は、もともと訪問者に割り当てられた匿名の `visitorCode` にアクセスできないが、セッションマージを通じて匿名訪問者にリンクされた内部 ID にアクセスできる場合など、その他のエッジケースのシナリオでも役立ちます。
</Note>

##### `activityTrackingIntervalMillisecond` の使用

activityTrackingIntervalMillisecond パラメータは、SDK が Data API 上の訪問者のセッションを延長するためにアクティビティイベントを送信する頻度を制御することで、ネットワーク使用量とバッテリー消費を削減するのに役立ちます。デフォルト値および許容される最小値は `60 000` ミリ秒 (60 秒) で、これより低い 0 以外の値は無視され、デフォルト値が適用されます。アプリがバックグラウンドにある間はタイマーが一時停止するため、間隔はアプリがフォアグラウンドにあるときにのみ実質的に進行します。

#### Kameleoon クライアントの初期化

アプリケーションに SDK をインストールしてアプリプロパティをセットアップした後、Kameleoon クライアントを作成する必要があります。クライアントは、アプリケーションと Kameleoon プラットフォーム間のブリッジとして機能するシングルトンオブジェクトです。フィーチャーフラグを実行するために必要なすべてのメソッドとプロパティが含まれています。

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    import com.kameleoon.KameleoonClient;
    import com.kameleoon.KameleoonClientConfig;
    import com.kameleoon.KameleoonClientFactory;
    import com.kameleoon.KameleoonException;

    public class MyApplication extends Application
    {
        private KameleoonClient kameleoonClient;
        @Override
        public void onCreate() {
            super.onCreate();
            try {
                KameleoonClientConfig config = new KameleoonClientConfig.Builder()
                    .refreshIntervalMinute(15) // in minutes, 1 hour by default, optional
                    .defaultTimeoutMillisecond(10_000) // in milliseconds, 10 seconds by default, optional
                    .trackingIntervalMillisecond(1000) // in milliseconds, 1000 ms by default, optional
                    .dataExpirationIntervalMinute(1440 * 365) // in minutes, infinity by default, optional
                    .environment("staging") // optional
                    .isUniqueIdentifier(false) // optional, false by default. Set to true if the visitorCode corresponds to your customer's unique userId.
                    .networkDomain("example.com") // optional
                    .defaultDataFile("{...}") // optional
                    .activityTrackingIntervalMillisecond(20_000) // optional, 15_000 milliseconds by default
                    .build();
                String siteCode = "a8st4f59bj";
                String visitorCode = "yourVisitorCode";
                kameleoonClient = KameleoonClientFactory.create(siteCode, visitorCode, config, getApplicationContext());
                // or, if you want, the visitor code will be generated automatically
                kameleoonClient = KameleoonClientFactory.create(siteCode, config, getApplicationContext());
            } catch (KameleoonException.SiteCodeIsEmpty | KameleoonException.VisitorCodeInvalid exception) {
                // Exceptions indicate that provided siteCode is empty or visitorCode is invalid
            } catch (Exception exception) {
                // Recommended (but optional) safeguard for unexpected exceptions from third-party libraries
            }
        }
        public KameleoonClient getKameleoonClient() {
            return kameleoonClient;
        }
    }
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    import com.kameleoon.KameleoonClientConfig
    import com.kameleoon.KameleoonClientFactory
    import com.kameleoon.KameleoonException

    class MyApplication : Application() {
        var kameleoonClient: KameleoonClient? = null
            private set

        override fun onCreate() {
            super.onCreate()
            try {
                val config = KameleoonClientConfig.Builder()
                    .refreshIntervalMinute(15) // in minutes, 1 hour by default, optional
                    .defaultTimeoutMillisecond(10_000) // in milliseconds, 10 seconds by default, optional
                    .trackingIntervalMillisecond(1000) // in milliseconds, 1000 ms by default, optional
                    .dataExpirationIntervalMinute(1440 * 365) // in minutes, infinity by default, optional
                    .environment("staging") // optional
                    .networkDomain("example.com") // optional
                    .defaultDataFile("{...}") // optional
                    .activityTrackingIntervalMillisecond(20_000) // optional, 15_000 milliseconds by default
                    .build()
                val siteCode = "a8st4f59bj"
                val visitorCode = "yourVisitorCode"
                val kameleoonClient = KameleoonClientFactory.create(siteCode, visitorCode, config, applicationContext)
                // or if you want that visitor code will be generated automatically
                kameleoonClient = KameleoonClientFactory.create(siteCode, config, applicationContext)
            } catch (e: KameleoonException.SiteCodeIsEmpty) {
                // Exception indicating that provided siteCode is empty
            } catch (e: KameleoonException.VisitorCodeInvalid) {
                // Exception indicating that provided visitor code is invalid
            } catch (e: Exception) {
                // Recommended (but optional) safeguard for unexpected exceptions from third-party libraries
            }
        }
    }
    ```
  </Tab>
</Tabs>

実行中、`KameleoonClientFactory.create()` メソッドはクライアントを初期化しますが、すぐには使用できる状態にはなりません。この遅延は、Kameleoon クライアントが Kameleoon リモートサーバーからフィーチャーフラグの現在の構成(およびトラフィック分配)を取得する必要があるためです。この取得にはネットワークアクセスが必要ですが、常に利用可能とは限りません。Kameleoon クライアントが完全に準備完了するまで、Kameleoon Android SDK の他のメソッドを実行しようとしないでください。フィーチャーフラグの最初の構成が取得されると、定期的に更新されますが、何らかの理由で更新が失敗した場合でも、Kameleoon クライアントは以前の構成を使用して動作を継続します。

[`isReady()`](#isready) メソッドを使用して、Kameleoon クライアントの初期化が完了したかどうかを確認できます。

別の方法として、**ヘルパーコールバック** がフィーチャーフラグの起動とバリエーション実装のロジックをカプセル化できます。最適なアプローチ([`isReady()`](#isready) または **コールバック**)は、好みと具体的なユースケースによって異なります。SDK がまもなく使用可能になる見込みの場合は、[`isReady()`](#isready) の使用が推奨されます。たとえば、ユーザーがアプリ内のナビゲーション中の最初の数秒または数分はアクセスしない可能性が高いダイアログ上でフィーチャーフラグを実行する場合、`isReady()` が適切です。SDK がまだ初期化中である可能性が高い場合は、コールバックが推奨されます。たとえば、アプリケーション起動時に画面に表示されるフィーチャーフラグでは、SDK が準備完了するまでまたは指定されたタイムアウトが満了するまでアプリケーションを待機させるコールバックを使用する必要があります。

<Note>
  Kameleoon を使用した A/B テストのコンテキスト内で、アプリケーションコードのロジックが正しいことを保証するのは、アプリ開発者の責任です。良いプラクティスは、Kameleoon クライアントがまだ準備できていないときには、アプリケーションのユーザーが常にフィーチャーフラグから除外される可能性があると想定することです。これはデフォルトまたは参照バリエーションロジックの実装に対応するため、簡単に実装できます。次の段落のコードサンプルは、このアプローチの例を示しています。
</Note>

これで、フィーチャー管理とフィーチャーフラグを実装する準備ができました。追加メソッドの詳細については、[リファレンス](#リファレンス) セクションを参照してください。

#### 初期化と使用のベストプラクティス

* 初期化には時間がかかる可能性があるため、アプリケーション開始後にできるだけ早くシングルトンとして [`KameleoonClient`](#create) を初期化することが推奨されます。初期化は非同期であるため、アプリケーションの起動プロセスをブロックしたり遅延させたりすることはありません。
* `KameleoonClient` を使用する前に、[`runWhenReady`](#runwhenready) メソッドを呼び出して初期化されているかを確認してください。そうしないと、準備が完了する前にクライアントを使用しようとするとエラーが発生します。
* ⚠️ 主要なメソッドのほとんどは例外をスローする可能性があるため、適切な例外処理が必要です。使用する各メソッドのドキュメントを必ず確認して、潜在的な例外を理解してください。

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    // Initialize `KameleoonClient` on application startup and use it as a singleton later
    try {
        KameleoonClient kameleoonClient = KameleoonClientFactory.create("<siteCode>", getApplicationContext());
    } catch (KameleoonException ignored) {}

    // Example: Apply a discount percentage based on an feature flag variable's value
    void applyDiscountIfApplicable() {
        kameleoonClient.runWhenReady(1000, result -> {
            double discount = 0.0;
            try {
                if (result.getOrThrow()) {
                    Variation variation = kameleoonClient.getVariation("discount");
                    discount = (double) variation.getVariables().get("discount_value").getValue();
                }
            } catch (Exception ignored) { }

            if (discount > 0) {
                applyDiscount(discount);
            }
        });
    }
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    // Initialize `KameleoonClient` on application startup and use it as a singleton later
    try {
        KameleoonClient kameleoonClient = KameleoonClientFactory.create("<siteCode>", applicationContext)
    } catch (ignored: KameleoonException) {}

    // Example: Apply a discount percentage based on a feature flag variable's value
    fun applyDiscountIfApplicable() {
        kameleoonClient.runWhenReady(1000) { result ->
            val discount = runCatching {
                if (result.getOrThrow()) {
                    val variation = kameleoonClient.getVariation("discount")
                    variation.variables["discount_value"]?.value as? Double
                } else {
                    null
                }
            }.getOrNull() ?: 0.0

            if (discount > 0) {
                applyDiscount(discount)
            }
        }
    }
    ```
  </Tab>

  <Tab title="Kotlin (Coroutines)">
    ```kotlin theme={null}
    // Initialize `KameleoonClient` on application startup and use it as a singleton later
    try {
        val kameleoonClient = KameleoonClientFactory.create("<siteCode>", applicationContext)
    } catch (ignored: KameleoonException) {}

    // Example: Apply a discount percentage based on a feature flag variable's value
    suspend fun applyDiscountIfApplicable() {
        kameleoonClient.runWhenReady(1000).getOrNull() ?: return // Exit if initialization fails

        val discount = runCatching {
            val variation = kameleoonClient.getVariation("discount")
            variation.variables["discount_value"]?.value as? Double
        }.getOrNull() ?: 0.0

        if (discount > 0) {
            applyDiscount(discount)
        }
    }
    ```
  </Tab>
</Tabs>

#### フィーチャーフラグの有効化

##### フラグ構成の取得

コード内でフィーチャーフラグを実装するには、まず Kameleoon アカウントでフィーチャーフラグを作成する必要があります。

特定のユーザーに対するフィーチャーフラグのステータスまたはバリエーションを判断するには、[`getVariation()`](#getvariation) または [`isFeatureActive()`](#isfeatureactive) メソッドを使用して、`featureKey` に基づく構成を取得する必要があります。

`getVariation()` メソッドは、ON/OFF 状態の単純なフィーチャーフラグと、複数のバリエーションを持つより複雑なフラグの両方を処理します。このメソッドは、フィーチャールールをチェックし、バリエーションを割り当て、`featureKey` と `visitorCode` に基づいて返すことで、ユーザーに適切なバリエーションを取得します。

`isFeatureActive()` メソッドは、複数のバリエーションやターゲティングオプションを持つより複雑なフィーチャーフラグとは対照的に、ON または OFF 状態のみを持つ単純なフィーチャーフラグの構成を取得する場合に使用できます。

フィーチャーフラグに関連する変数 (各バリエーションに関連付けられた特定の動作など) がある場合、`getVariation()` を使用すると [`Variation`](#variation) オブジェクトにアクセスできます。これは、割り当てられたバリエーションとそれに関連付けられた実験の詳細を提供します。このメソッドは、ユーザーがターゲットになっているかどうかを確認し、訪問者に割り当てられたバリエーションを見つけて、ストレージに保存します。`track=true` の場合、SDK は、SDK の [`tracking_interval_millisecond`](#追加の設定) に基づいて自動的にトリガーされる次のトラッキングリクエスト時に、指定された実験に露出イベントを送信します。デフォルトでは、この間隔は 1000 ミリ秒 (1 秒) に設定されています。

`getVariation()` メソッドを使用すると、トラッキングを行うかどうかを制御できます。`track=false` の場合、SDK からは露出イベントは送信されません。これは、SDK 経由でデータを追跡せず、代わりに Kameleoon エンジンによって管理されるクライアントサイドのトラッキングに依存する場合などに便利です。さらに、`getVariations()` メソッドを使用するとき、トラッキングイベントをトリガーせずにすべてのフラグのバリエーションのみが必要な場合にも、`track=false` の設定が役立ちます。トラッキングの仕組みについて詳しく知りたい場合は、[こちらの記事](/developer-docs/feature-experimentation/technical-reference/faq-global#when-does-the-sdk-send-a-tracking-request-for-analytics) をご覧ください。

##### レポートで訪問をターゲット/フィルター/ブレークダウンするためのデータポイントの追加

ユーザーをターゲットにするには、フィーチャーバリエーションを取得する、またはフラグがアクティブかどうかをチェックする前に、関連するデータポイントをプロファイルに追加していることを確認してください。これらのデータポイントをユーザーのプロファイルに追加するには、[`addData()`](#adddata) メソッドを使用します。

他のデバイスで収集されたデータポイントを取得するには、[`getRemoteVisitorData()`](#getremotevisitordata) メソッドを使用します。このメソッドはサーバーからデータを非同期的に取得します。このデータはユーザーを特定のバリエーションに割り当てるために必要となる可能性があるため、バリエーションを取得する *前* またはフィーチャーフラグがアクティブかどうかをチェックする *前* に `getRemoteVisitorData()` を呼び出すことが重要です。

利用可能なターゲティング条件について詳しく知るには、[この件に関する詳細な記事](/developer-docs/feature-experimentation/targeting-and-segmentation/native-segmentation) を参照してください。

さらに、訪問者プロファイルに追加するデータポイントは、実験を分析する際に利用できるため、デバイスなどの要因で結果をフィルタリングおよびブレークダウンできます。完全なリストは [こちら](/ja/user-manual/experiment-analytics/analyze-results/results-page/results-page-settings#オーディエンスの分割) をご覧ください。

自動的に収集されるデータポイント以外に追跡する必要がある場合は、Kameleoon の [カスタムデータ機能](#customdata) を使用できます。カスタムデータを使用すると、実験に関連する特定の情報をキャプチャして分析できます。収集したデータを分析のために Kameleoon サーバーに送信するには、[`flush()`](#flush) メソッドを呼び出すことを忘れないでください。

##### 目標コンバージョンの追跡

ユーザーが希望するアクション(購入など)を完了すると、それはコンバージョンとして記録されます。コンバージョンを追跡するには、[`trackConversion()`](#trackconversion) メソッドを使用し、必須の `goalId` パラメータを提供します。

コンバージョン追跡リクエストは、次のスケジュールされたトラッキングリクエストと一緒に送信されます。これは SDK が定期的な間隔(`tracking_interval_millisecond` で定義) で送信します([`tracking_interval_millisecond`](#追加の設定))。リクエストを即座に送信したい場合は、`instant=true` パラメータを指定して [`flush()`](#flush) メソッドを使用します。

### クロスデバイス実験

複数のデバイスからアプリにアクセスする訪問者をサポートするため、Kameleoon は、以前に収集された訪問者データを各訪問者のデバイス間で同期し、クロスデバイス実験を通じてデバイス間で訪問履歴を調整することを可能にします。Kameleoon がデバイス間でどのようにデータを処理するかについてのケーススタディと詳細情報は、[クロスデバイス実験の記事](/developer-docs/cross-device-experimentation) で参照できます。

#### デバイス間でのカスタムデータの同期

カスタムマッピング同期は、デバイス間で訪問者データを調整するために使用されますが、常に必要というわけではありません。以下は、カスタムマッピング同期が不要な 2 つのシナリオです。

**デバイス間で同じユーザー ID**
すべてのデバイスで同じユーザー ID が一貫して使用される場合、カスタムマッピング同期なしで自動的に同期が処理されます。複数のデバイス間で収集されたデータを同期したい場合は、`getRemoteVisitorData()` メソッドを呼び出すだけで十分です。

**一貫した ID を持つマルチサーバーインスタンス**
複数のサーバーが関与する複雑なセットアップ(例: 分散サーバーインスタンス)で、同じユーザー ID が複数のサーバーで利用できる場合、追加のカスタムマッピング同期なしで、サーバー間の同期(`getRemoteVisitorData()` を使用)で十分です。

追加データが必要なお客様は、詳細なガイダンスについて [`getRemoteVisitorData()`](#getremotevisitordata) メソッドの説明を参照してください。以下のコードでは、2 つのデバイス間で同じ一意の識別子(この場合は `visitorCode`。`userId` とも呼ばれる)が一貫して使用され、正確なデータ取得が可能であると仮定しています。

<Note>
  収集したデータをリアルタイムで同期したい場合は、カスタムデータのスコープを **訪問者** にする必要があります。
</Note>

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java title="デバイス A" theme={null}
    // In this, example Custom data with index `90` was set to "Visitor" scope in Kameleoon.
    final int VISITOR_SCOPE_CUSTOM_DATA_INDEX = 90;

    kameleoonClient.addData(new CustomData(VISITOR_SCOPE_CUSTOM_DATA_INDEX, "your data"));
    kameleoonClient.flush();
    ```

    ```java title="デバイス B" theme={null}
    // Before working with the data, call `getRemoteVisitorData`.
    kameleoonClient.getRemoteVisitorData(result -> {
        // After calling, the SDK on Device B will have access to CustomData of Visitor scope defined on Device A.
        // So, "your data" will be available to target and track the visitor.
    });
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin title="デバイス A" theme={null}
    // In this example Custom data with index `90` was set to "Visitor" scope on Kameleoon Platform.
    val VISITOR_SCOPE_CUSTOM_DATA_INDEX = 90

    kameleoonClient.addData(CustomData(VISITOR_SCOPE_CUSTOM_DATA_INDEX, "your data"))
    kameleoonClient.flush()
    ```

    ```kotlin title="デバイス B" theme={null}
    // Before working with the data, call the `getRemoteVisitorData` method.
    kameleoonClient.getRemoteVisitorData { result ->
        // After that the SDK on Device B will have an access to CustomData of Visitor scope defined on Device A.
        // So "your data" will be available for targeting and tracking for the visitor.
    }
    ```
  </Tab>

  <Tab title="Kotlin (Coroutines)">
    ```kotlin title="デバイス A" theme={null}
    // In this example Custom data with index `90` was set to "Visitor" scope on Kameleoon Platform.
    val VISITOR_SCOPE_CUSTOM_DATA_INDEX = 90

    kameleoonClient.addData(CustomData(VISITOR_SCOPE_CUSTOM_DATA_INDEX, "your data"))
    kameleoonClient.flush()
    ```

    ```kotlin title="デバイス B" theme={null}
    // Before working with the data, call the `getRemoteVisitorData` method.
    kameleoonClient.getRemoteVisitorData()
    // After that the SDK on Device B will have an access to CustomData of Visitor scope defined on Device A.
    // So "your data" will be available for targeting and tracking for the visitor.
    ```
  </Tab>
</Tabs>

#### セッションマージのためのカスタムデータの使用

[クロスデバイス実験](/developer-docs/cross-device-experimentation) を使用すると、訪問者の履歴を各デバイスで結合できます(履歴の調整)。履歴の調整により、異なる訪問者セッションを 1 つにマージできます。訪問履歴を調整するには、[`CustomData`](#customdata) を使用して訪問者の一意の識別子を提供します。詳細については、[専用のドキュメント](/developer-docs/cross-device-experimentation/#activating-cross-device-history-reconciliation) を参照してください。

クロスデバイスの調整が有効化された後、`userId` パラメータを指定して [`getRemoteVisitorData()`](#getremotevisitordata) を呼び出すと、特定のユーザーに対する既知のデータがすべて取得されます。

同じ識別子を持つセッションは、実験において常に同じバリエーションが表示されます。実験結果ページの訪問者ビューでは、これらのセッションは単一の訪問者として表示されます。

SDK 構成は、関連するセッションが常に実験の同じバリエーションを見ることを保証します。ただし、クロスデバイスのバリエーション割り当てにはいくつかの制限があります。これらの制限については [こちら](/developer-docs/cross-device-experimentation#critical-points-and-practical-insights) で説明されています。

[クロスデバイス履歴調整の有効化](#クロスデバイス実験) ガイドに従って、Kameleoon プラットフォームでカスタムデータをセットアップします。

その後、通常通り SDK を使用できます。セッションマージのコンテキストで役立つ可能性のあるメソッドは次のとおりです。

* [`KameleoonClientConfig`](#追加の設定) に `isUniqueIdentifier=true` を渡した `getRemoteVisitorData()` - リンクされたすべての訪問者のデータを取得します。
* `KameleoonClientConfig` に `isUniqueIdentifier=true` を渡した [`trackConversion()`](#trackconversion) または [`flush()`](#flush) - 別の訪問者に関連付けられている特定の訪問者のデータを追跡します。

<Tip>
  識別子として使用するカスタムデータは **訪問者スコープ** に設定する必要があるため、各デバイスで [`getRemoteVisitorData()`](#getremotevisitordata) メソッドを使用して識別子を取得するには、[クロスデバイスカスタムデータ同期](/developer-docs/cross-device-experimentation) を使用する必要があります。
</Tip>

以下は、セッションマージにカスタムデータを使用する例です。

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    // In this example, `91` represents the Custom Data's index,
    // configured as a unique identifier in Kameleoon.
    final int MAPPING_INDEX = 91;
    final String FEATURE_KEY = "ff123";

    // 0. Initializing anonymous KameleoonClient

    // Assume `anonymousVisitorCode` is the randomly generated ID for that visitor.
    KameleoonClient anonymousKameleoonClient = KameleoonClientFactory.create(siteCode, anonymousVisitorCode, getApplicationContext());
    anonymousKameleoonClient.runWhenReady(result -> {
        // ...
    });

    // 1. Before the visitor is authenticated

    // Retrieve the variation for an unauthenticated visitor.
    Variation anonymousVariation = anonymousKameleoonClient.getVariation(FEATURE_KEY);

    // 2. After the visitor is authenticated

    // Assume `userId` is the authenticated visitor's visitor code.
    anonymousKameleoonClient.addData(new CustomData(MAPPING_INDEX, userId));
    anonymousKameleoonClient.flush(true);

    KameleoonClient userKameleoonClient = KameleoonClientFactory.create(
        siteCode, userId,
        (new KameleoonClientConfig.Builder())
            .isUniqueIdentifier(true) // Indicate that `userId` is a unique identifier
            .build(),
        getApplicationContext()
    );
    userKameleoonClient.runWhenReady(result -> {
        // ...
    });

    // 3. After the visitor has been authenticated

    // Retrieve the variation for the `userId`, which will match the anonymous visitor code's variation.
    Variation userVariation = userKameleoonClient.getVariation(FEATURE_KEY);
    boolean isSameVariation = userVariation.getKey().equals(anonymousVariation.getKey()); // true

    // The `userId` and `anonymousVisitorCode` are now linked and tracked as a single visitor.
    kameleoonClient.trackConversion(123, 10.0f);

    // Additionally, the linked visitors will share all fetched remote visitor data.
    kameleoonClient.getRemoteVisitorData(result -> {
        // ...
    });
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    // In this example, `91` represents the Custom Data's index
    // configured as a unique identifier in Kameleoon.
    val MAPPING_INDEX = 91
    val FEATURE_KEY = "ff123"

    // 0. Initializing anonymous KameleoonClient

    // Assume `anonymousVisitorCode` is the randomly generated ID for that visitor.
    val anonymousKameleoonClient = KameleoonClientFactory.create(siteCode, anonymousVisitorCode, applicationContext)
    anonymousKameleoonClient.runWhenReady { result ->
        // ...
    }

    // 1. Before the visitor is authenticated

    // Retrieve the variation for an unauthenticated visitor.
    val anonymousVariation = anonymousKameleoonClient.getVariation(FEATURE_KEY)

    // 2. After the visitor is authenticated

    // Assume `userId` is the authenticated visitor's visitor code.
    anonymousKameleoonClient.addData(CustomData(MAPPING_INDEX, userId))
    anonymousKameleoonClient.flush(true)

    val userKameleoonClient = KameleoonClientFactory.create(
        siteCode, userId,
        KameleoonClientConfig.Builder()
            .isUniqueIdentifier(true) // Indicate that `userId` is a unique identifier
            .build(),
        applicationContext
    )
    userKameleoonClient.runWhenReady { result ->
        // ...
    }

    // 3. After the visitor has been authenticated

    // Retrieve the variation for the `userId`, which will match the anonymous visitor code's variation.
    val userVariation = userKameleoonClient.getVariation(FEATURE_KEY)
    val isSameVariation = userVariation.getKey() == anonymousVariation.getKey() // true

    // The `userId` and `anonymousVisitorCode` are now linked and tracked as a single visitor.
    userKameleoonClient.trackConversion(123, 10.0f)

    // Additionally, the linked visitors will share all fetched remote visitor data.
    userKameleoonClient.getRemoteVisitorData { result ->
        // ...
    }
    ```
  </Tab>

  <Tab title="Kotlin (Coroutines)">
    ```kotlin theme={null}
    // In this example, `91` represents the Custom Data's index
    // configured as a unique identifier in Kameleoon.
    val MAPPING_INDEX = 91
    val FEATURE_KEY = "ff123"

    // 0. Initializing anonymous KameleoonClient

    // Assume `anonymousVisitorCode` is the randomly generated ID for that visitor.
    val anonymousKameleoonClient = KameleoonClientFactory.create(siteCode, anonymousVisitorCode, applicationContext)
    anonymousKameleoonClient.runWhenReady()

    // 1. Before the visitor is authenticated

    // Retrieve the variation for an unauthenticated visitor.
    val anonymousVariation = anonymousKameleoonClient.getVariation(FEATURE_KEY)

    // 2. After the visitor is authenticated

    // Assume `userId` is the authenticated visitor's visitor code.
    anonymousKameleoonClient.addData(CustomData(MAPPING_INDEX, userId))
    anonymousKameleoonClient.flush(true)

    val userKameleoonClient = KameleoonClientFactory.create(
        siteCode, userId,
        KameleoonClientConfig.Builder()
            .isUniqueIdentifier(true) // Indicate that `userId` is a unique identifier
            .build(),
        applicationContext
    )
    userKameleoonClient.runWhenReady()

    // 3. After the visitor has been authenticated

    // Retrieve the variation for the `userId`, which will match the anonymous visitor code's variation.
    val userVariation = userKameleoonClient.getVariation(FEATURE_KEY)
    val isSameVariation = userVariation.getKey() == anonymousVariation.getKey() // true

    // The `userId` and `anonymousVisitorCode` are now linked and tracked as a single visitor.
    userKameleoonClient.trackConversion(123, 10.0f)

    // Additionally, the linked visitors will share all fetched remote visitor data.
    userKameleoonClient.getRemoteVisitorData()
    ```
  </Tab>
</Tabs>

この例では、アプリケーションにログインページがあります。ログイン時にはユーザー ID が不明であるため、SDK によって自動的に生成された匿名訪問者が使用されます。訪問者コードは [`getVisitorCode()`](#getvisitorcode) メソッドで取得できます。ユーザーがログインすると、匿名訪問者はユーザー ID に関連付けられ、訪問者の一意の識別子として使用されます。

### カスタムバケッティングキーの使用

デフォルトでは、Kameleoon は一意の匿名訪問者 ID (`visitorCode`) を使用して、ユーザーをフィーチャーフラグのバリエーションに割り当てます。この ID は通常、ユーザーのデバイス上で生成されて保存されます(クライアントサイドおよびサーバーサイドの SDK ではブラウザクッキー内、モバイル SDK では永続ストレージ内)。ただし、特定のシナリオでは、同じ組織のすべてのユーザーがフィーチャーフラグの同じバリアントを見ることを保証する必要がある場合があります。

**カスタムバケッティングキー** オプションを使用すると、バケッティングに使用する独自のカスタム識別子を提供することで、このデフォルトの動作を上書きできます。このオーバーライドにより、Kameleoon の割り当てロジックがデフォルトの `visitorCode` の代わりに指定したキーを使用することが保証されます。

#### ユースケース

カスタムバケッティングキーを使用することは、特に以下の状況で、フィーチャーフラグの割り当てにおける一貫性と精度を維持するために不可欠です。

* **アカウントレベルまたは組織の実験:** B2B 製品または同じ組織のすべてのユーザーを同じバリエーションに割り当てたいシナリオでは、`accountId` のような識別子を使用できます。チームまたは会社全体に影響を与える機能の A/B テストでは、カスタムバケッティングキーが極めて重要です。

カスタムバケッティングキーを実装することで、実験における一貫性と精度が向上し、信頼性の高い結果とより良いユーザーエクスペリエンスにつながります。

#### 技術的な詳細

フィーチャーフラグにカスタムバケッティングキーを構成する場合、アプリケーションのデータから特定の識別子を Kameleoon に提供します。

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    kameleoonClient.addData(new CustomData(index, "newVisitorCode"));
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    kameleoonClient.addData(CustomData(index, "newVisitorCode"))
    ```
  </Tab>
</Tabs>

* **カスタムキーの提供:** [`addData()`](#adddata) メソッドを使用して、カスタム識別子を Kameleoon SDK に提供します。このメソッドでは、選択したカスタムバケッティングキーを [`CustomData`](#customdata) オブジェクトとして渡します。ここで、`newVisitorCode` は、バケッティングに使用したい識別子(例えば、新しい `userId` または `accountId`)を指します。

<Warning>
  カスタムバケッティングキーが正しく機能するためには、フラグの作成または編集プロセス中にフィーチャーフラグに対して定義および構成する必要があります。この対応する構成がないと、SDK のバケッティングはカスタムキーを適用しません。Kameleoon でこれをセットアップする詳細な手順については、こちらの [記事](/user-manual/experimentation/feature-experimentation/create-and-manage-flags/create-a-feature-flag#Advanced_Flag_Settings) を参照してください。
</Warning>

* **バケッティングロジック:** `addData()` メソッド経由でカスタムバケッティングキーが提供されると、ユーザーをバリエーションに割り当てるためのすべてのハッシュ計算で、デフォルトの `visitorCode` の代わりにこの `newVisitorCode`(カスタムキー)が使用されます。`newVisitorCode` を使用することで、バケッティングの決定がカスタム識別子に紐付けられるため、その識別子が存在する様々なコンテキストで一貫した割り当てが保証されます。
* **データ追跡と分析:** `newVisitorCode`(カスタムキー)はバケッティングの決定に使用される一方、**後続のすべてのデータ(例: トラッキングイベントやコンバージョン)は元の `visitorCode` に関連付けて送信されます。** この分離により、バケッティングが上位レベル(アカウントなど)または複数のデバイス/セッションで実行される場合でも、分析は実験のより広いコンテキスト内での個々のユーザーの旅程やインタラクションを正確に反映します。元の訪問者データは、包括的なレポート用にそのまま保持されます。

#### 技術要件

カスタムバケッティングキーを効果的に使用するには:

* キーは `String` でなければなりません。
* バケットしたいエンティティに対して一意でなければなりません(例えば、`userId` を使用する場合、各ユーザーの ID は一意である必要があります)。
* フィーチャーフラグの決定がそのユーザーまたはリクエストに対して評価される正確な瞬間に、SDK がキーを利用できる必要があります。

### ターゲティング条件

Kameleoon SDK は、キャンペーンでユーザーをターゲットするために使用できる、さまざまな事前定義されたターゲティング条件をサポートしています。この SDK がサポートする条件の一覧については、[訪問履歴を使用してユーザーをターゲットする](/developer-docs/feature-experimentation/targeting-and-segmentation/native-segmentation) を参照してください。

独自の [外部データを使用してユーザーをターゲットする](/developer-docs/apis/data-api-rest/tutorials/storing-and-retrieving-external-data-to-target-users) こともできます。

### エラー処理

**Kameleoon SDK** のすべてのメソッドは、`KameleoonException` または各メソッドの *Exceptions Thrown* セクションで一覧されているドキュメント化された継承例外 **のみ** をスローする可能性があります。
これらの例外は SDK の **予期される動作** です。特定のシナリオを別の方法で処理したい場合は、個別の継承例外をキャッチできます。それ以外の場合、`KameleoonException` をキャッチするとすべての SDK 関連エラーが処理されます。

**ユニットテストおよび統合テスト** で SDK が `Exception` や `RuntimeException` を **決してスローしない** ことを確認していますが、**Android で SDK のバージョンをパッチするのは困難** であり、`RuntimeException` をスローする可能性のある **サードパーティライブラリ** から予期しない問題が発生する可能性があることを理解しています。このようなまれなケースでアプリケーションがクラッシュするのを防ぐために、追加の保護策として **`Exception`(または `RuntimeException`)もキャッチする** ことを推奨します。これは厳密には予防策であり、**SDK の予期される動作ではありません**。

例えば:

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    try {
        // Calling a method of the SDK
    } catch (KameleoonException e) {
        // Handling expected exceptions
    } catch (Exception e) {
        // Recommended (but optional) safeguard for unexpected exceptions from third-party libraries
    }
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    try {
        // Calling a method of the SDK
    } catch (e: KameleoonException) {
        // Handling expected exceptions
    } catch (e: Exception) {
        // Recommended (but optional) safeguard for unexpected exceptions from third-party libraries
    }
    ```
  </Tab>
</Tabs>

### ロギング

SDK は、さまざまな内部プロセスと問題を反映するログを生成します。

#### ログレベル

SDK は、ログレベルによるロギング制限の設定をサポートしています。

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    // The `NONE` log level does not allow logging.
    com.kameleoon.logging.KameleoonLogger.setLogLevel(com.kameleoon.logging.LogLevel.NONE);

    // The `ERROR` log level only allows logging issues that may affect the SDK's main behaviour.
    com.kameleoon.logging.KameleoonLogger.setLogLevel(com.kameleoon.logging.LogLevel.ERROR);

    // The `WARNING` log level allows logging issues which may require additional attention.
    // It extends the `ERROR` log level.
    // The `WARNING` log level is a default log level.
    com.kameleoon.logging.KameleoonLogger.setLogLevel(com.kameleoon.logging.LogLevel.WARNING);

    // The `INFO` log level allows logging general information on the SDK's internal processes.
    // It extends the `WARNING` log level.
    com.kameleoon.logging.KameleoonLogger.setLogLevel(com.kameleoon.logging.LogLevel.INFO);

    // The `DEBUG` level logs additional details about the SDK’s internal processes and extends the `INFO` level
    // with more granular. diagnostic output.
    // This information is not intended for end-user interpretation but can be sent to our support team
    // to assist with internal troubleshooting.
    com.kameleoon.logging.KameleoonLogger.setLogLevel(com.kameleoon.logging.LogLevel.DEBUG);
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    // The `NONE` log level allows no logging.
    com.kameleoon.logging.KameleoonLogger.setLogLevel(com.kameleoon.logging.LogLevel.NONE)

    // The `ERROR` log level allows to log only issues that may affect the SDK's main behaviour.
    com.kameleoon.logging.KameleoonLogger.setLogLevel(com.kameleoon.logging.LogLevel.ERROR)

    // The `WARNING` log level allows to log issues which may require an attention.
    // It extends the `ERROR` log level.
    // The `WARNING` log level is a default log level.
    com.kameleoon.logging.KameleoonLogger.setLogLevel(com.kameleoon.logging.LogLevel.WARNING)

    // The `INFO` log level allows to log general information on the SDK's internal processes.
    // It extends the `WARNING` log level.
    com.kameleoon.logging.KameleoonLogger.setLogLevel(com.kameleoon.logging.LogLevel.INFO)

    // The `DEBUG` log level allows to log extra information on the SDK's internal processes.
    // It extends the `INFO` log level.
    com.kameleoon.logging.KameleoonLogger.setLogLevel(com.kameleoon.logging.LogLevel.DEBUG)
    ```
  </Tab>
</Tabs>

#### ログのカスタム処理

SDK は、デフォルトでログをコンソール出力に書き込みます。この動作はオーバーライドできます。

<Note>
  ログレベルによるロギング制限は、ログ処理ロジックとは別に実行されます。
</Note>

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    public class CustomLogger implements com.kameleoon.logging.Logger {
        // `log` method accepts logs from the SDK
        @Override
        public void log(com.kameleoon.logging.LogLevel level, String message) {
            // Custom log handling logic here. For example:
            switch (level) {
                case ERROR:
                    android.util.Log.e("your-log-tag", message);
                    break;
                case WARNING:
                    android.util.Log.w("your-log-tag", message);
                    break;
                case INFO:
                    android.util.Log.i("your-log-tag", message);
                    break;
                case DEBUG:
                    android.util.Log.d("your-log-tag", message);
                    break;
                default:
            }
        }
    }


    // Log level filtering is applied separately from log handling logic.
    // The custom logger will only accept logs that meet or exceed the specified log level.
    // Ensure the log level is set correctly.
    com.kameleoon.logging.KameleoonLogger.setLogLevel(com.kameleoon.logging.LogLevel.DEBUG); // Optional, defaults to `LogLevel.WARNING`.
    com.kameleoon.logging.KameleoonLogger.setLogger(new CustomLogger());
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    class CustomLogger : com.kameleoon.logging.Logger {

        override fun log(level: com.kameleoon.logging.LogLevel, message: String) {
            // Custom log handling logic here. For example:
            when (level) {
                com.kameleoon.logging.LogLevel.ERROR -> android.util.Log.e("your-log-tag", message)
                com.kameleoon.logging.LogLevel.WARNING -> android.util.Log.w("your-log-tag", message)
                com.kameleoon.logging.LogLevel.INFO -> android.util.Log.i("your-log-tag", message)
                com.kameleoon.logging.LogLevel.DEBUG -> android.util.Log.d("your-log-tag", message)
                else -> {
                    // Optional: handle default case if needed
                }
            }
        }
    }

    // Log level filtering is applied separately from log handling logic.
    // The custom logger will only accept logs that meet or exceed the specified log level.
    // Ensure the log level is set correctly.
    com.kameleoon.logging.KameleoonLogger.setLogLevel(com.kameleoon.logging.LogLevel.DEBUG) // Optional, defaults to `LogLevel.WARNING`.
    com.kameleoon.logging.KameleoonLogger.setLogger(CustomLogger())
    ```
  </Tab>
</Tabs>

### WebView への訪問者コードの受け渡し

場合によっては、ネイティブアプリケーションから [Engine.js](/developer-docs/web-experimentation/implementation-and-deployment/standard-implementation) または Web の [JavaScript](/developer-docs/sdks/web-sdks/js-sdk) または [React](/developer-docs/sdks/web-sdks/react-js-sdk) SDK を使用する WebView に **訪問者コード** を渡す必要があります。次の例は、これを実現するための推奨される方法を示しています。

<Tabs defaultTabIndex={0}>
  <Tab title="Kotlin">
    ```kotlin theme={null}
    class WebViewActivity : AppCompatActivity() {

        private var webView: WebView? = null

        private val DEFAULT_URL = "https://example.com"
        private val COOKIE_NAME = "kameleoonVisitorCode"
        private val COOKIE_DOMAIN = ".example.com"

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)

            webView = WebView(this).also { webView ->
                setContentView(webView)
                configureWebView(DEFAULT_URL, kameleoonClient)
                webView.loadUrl(DEFAULT_URL)
            }
        }

        private fun configureWebView(url: String, kameleoonClient: KameleoonClient) {
            CookieManager.getInstance().apply {
                setCookie(
                    url,
                    "$COOKIE_NAME=${kameleoonClient.visitorCode}; Domain=$COOKIE_DOMAIN; Path=/; Secure"
                )
                flush()
            }
        }
    }
    ```
  </Tab>

  <Tab title="Kotlin (Jetpack Compose)">
    ```kotlin theme={null}
    @Composable
    fun KameleoonCookieWebView(url: String, kameleoonClient: KameleoonClient) {
        AndroidView(
            factory = { context ->
                WebView(context).apply {
                    configureWebView(url, kameleoonClient)
                    loadUrl(url)
                }
            },
        )
    }

    private fun WebView.configureWebView(url: String, kameleoonClient: KameleoonClient) {
        val COOKIE_NAME = "kameleoonVisitorCode"
        val COOKIE_DOMAIN = ".example.com"

        CookieManager.getInstance().apply {
            setCookie(
                url,
                "$COOKIE_NAME=${kameleoonClient.visitorCode}; Domain=$COOKIE_DOMAIN; Path=/; Secure"
            )
            flush()
        }
    }
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    public class WebViewActivity extends AppCompatActivity {

        private WebView webView;

        private static final String DEFAULT_URL = "https://example.com";
        private static final String COOKIE_NAME = "kameleoonVisitorCode";
        private static final String COOKIE_DOMAIN = ".example.com";

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            webView = new WebView(this);
            setContentView(webView);
            configureWebView(webView, DEFAULT_URL, kameleoonClient);
            webView.loadUrl(url);
        }

        private void configureWebView(WebView webView, String url, KameleoonClient kameleoonClient) {
            CookieManager cookieManager = CookieManager.getInstance();
            cookieManager.setCookie(
                    url,
                    COOKIE_NAME + "=" + kameleoonClient.getVisitorCode() + "; Domain=" + COOKIE_DOMAIN + "; Path=/; Secure"
            );
            cookieManager.flush();
        }
    }
    ```
  </Tab>
</Tabs>

## リファレンス

Kameleoon Android SDK の完全なリファレンスドキュメントです。

### 初期化

アプリケーションに [SDK をインストール](#インストール) したら、最初のステップとして Kameleoon を初期化します。実験のトリガーなど、アプリケーションと SDK 間のすべてのインタラクションは、この Kameleoon クライアントオブジェクトを使用して行われます。

#### create()

SDK を初期化するために、他のメソッドの前にこのメソッドを呼び出します。このメソッドは `com.kameleoon.KameleoonClientFactory` にあります。アプリは、このメソッドによって作成された結果の `KameleoonClient` オブジェクトを使用して、SDK とのすべてのインタラクションを行います。

[構成オブジェクト](#追加の設定) を提供することで、SDK の動作(環境、認証情報など)をカスタマイズできます。それ以外の場合、SDK は代わりに構成ファイルを探して使用しようとします。

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    String siteCode = "a8st4f59bj";
    try {
        // pass client configuration and visitorCode as arguments
        KameleoonClientConfig config = new KameleoonClientConfig.Builder()
            .refreshIntervalMinute(15) // in minutes, 1 hour by default, optional
            .defaultTimeoutMillisecond(10_000) // in milliseconds, 10 seconds by default, optional
            .dataExpirationIntervalMinute(1440 * 365) // in minutes, infinity by default, optional
            .isUniqueIdentifier(false) // optional, false by default. Set to true if the visitorCode corresponds to your customer's unique userId.
            .environment("staging") // optional
            .build();
        String visitorCode = "yourVisitorCode";
        KameleoonClient kameleoonClient = KameleoonClientFactory.create(siteCode, visitorCode, config, getApplicationContext());
    } catch (KameleoonException.SiteCodeIsEmpty | KameleoonException.VisitorCodeInvalid exception) {
        // Exception indicates that the provided siteCode is empty or the visitorCode is invalid
    } catch (Exception exception) {
        // Recommended (but optional) safeguard for unexpected exceptions from third-party libraries
    }

    try {
        // generate visitorCode automatically and read client configuration from a file 'kameleoon-client.properties'
        KameleoonClient kameleoonClient = KameleoonClientFactory.create(siteCode, getApplicationContext());
    } catch (KameleoonException.SiteCodeIsEmpty | KameleoonException.VisitorCodeInvalid exception) {
        // Exception indicates that the provided siteCode is empty or the visitorCode is invalid
    } catch (Exception exception) {
        // Recommended (but optional) safeguard for unexpected exceptions from third-party libraries
    }
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    val siteCode = "a8st4f59bj"
    try {
        // pass client configuration and visitor code as arguments
        val config = KameleoonClientConfig.Builder()
            .refreshIntervalMinute(15) // in minutes, 1 hour by default, optional
            .defaultTimeoutMillisecond(10_000) // in milliseconds, 10 seconds by default, optional
            .dataExpirationIntervalMinute(1440 * 365) // in minutes, infinity by default, optional
            .environment("staging") // optional
            .build();
        val visitorCode = "yourVisitorCode"
        val kameleoonClient = KameleoonClientFactory.create(siteCode, visitorCode, config, applicationContext)
    } catch (e: KameleoonException.SiteCodeIsEmpty) {
        // Exception indicating that the provided siteCode is empty
    } catch (e: KameleoonException.VisitorCodeInvalid) {
        // Exception indicating that the provided visitorCode is invalid
    } catch (e: Exception) {
        // Recommended (but optional) safeguard for unexpected exceptions from third-party libraries
    }

    try {
        // generate visitorCode automatically and read client configuration from the 'kameleoon-client.properties' file
        val kameleoonClient = KameleoonClientFactory.create(siteCode, applicationContext)
    } catch (e: KameleoonException.SiteCodeIsEmpty) {
        // Exception indicating that the provided siteCode is empty
    } catch (e: KameleoonException.VisitorCodeInvalid) {
        // Exception indicating that the provided visitorCode is invalid
    } catch (e: Exception) {
        // Recommended (but optional) safeguard for unexpected exceptions from third-party libraries
    }
    ```
  </Tab>
</Tabs>

##### 引数

| 名前                        | 型                       | 説明                                                                                                                             | デフォルト |
| ------------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------ | ----- |
| siteCode (*必須*)           | `String`                | SDK で使用される Kameleoon プロジェクトを識別する [一意のキー](/user-manual/faq#how-do-i-find-my-sitecode)。                                          |       |
| visitorCode (*オプション*)     | `String`                | オプションの訪問者識別子。利用可能であれば、内部の **ユーザー ID** を使用してください。それ以外の場合、SDK が自動的に生成します。                                                        | `nil` |
| config (*オプション*)          | `KameleoonClientConfig` | オプションの SDK 構成。指定された場合、外部 [構成ファイル](#追加の設定) からの読み取りの代わりに使用されます。指定されない場合、SDK はファイルを読み取ろうとしますが、ファイルが見つからない場合は、デフォルトの動作にフォールバックします。 | `nil` |
| applicationContext (*必須*) | `Context`               | アプリケーションの [context](https://developer.android.com/reference/android/content/Context)。                                          |       |

##### 戻り値

| 型                 | 説明                                                          |
| ----------------- | ----------------------------------------------------------- |
| `KameleoonClient` | アプリが実験とフィーチャーフラグを管理するために使用できる `KameleoonClient` クラスのインスタンス。 |

##### スローされる例外

| 型                    | 説明                                                 |
| -------------------- | -------------------------------------------------- |
| `VisitorCodeInvalid` | 提供された訪問者コードが有効でないことを示す例外。空であるか、255 文字より長いかのいずれかです。 |
| `SiteCodeIsEmpty`    | 指定されたサイトコードが空の文字列であり、無効な値であることを示す例外。               |

#### isReady()

モバイル SDK の場合、Kameleoon クライアントはアクティブなフィーチャーフラグの現在の構成を取得するためにサーバーコールを実行する必要があるため、すぐに初期化することはできません。フィーチャーフラグをトリガーする前に `isReady()` を呼び出して、SDK の準備が完了しているかを確認するためにこのメソッドを使用します。

または、コールバックを使用することもできます(詳細は [`runWhenReady()`](#runwhenready) メソッドを参照)。

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    boolean ready = kameleoonClient.isReady();
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    val ready = kameleoonClient.isReady
    ```
  </Tab>
</Tabs>

##### 戻り値

| 型       | 説明                                                                      |
| ------- | ----------------------------------------------------------------------- |
| boolean | SDK のステータスを表すブール値。クライアントが完全に初期化されている場合は `true`、まだ使用できる状態でない場合は `false`。 |

#### runWhenReady()

* 🔄 *非同期リクエストを実行します(設定が古いまたは欠如している場合)*

モバイル SDK では、`KameleoonClient` はすべてのフィーチャーフラグの現在の構成を取得するためにサーバーコールを実行する必要があるため、すぐに初期化することはできません。クライアントが使用できる状態になるまでの時間を処理するには、[`runWhenReady()`](#runwhenready) メソッドを使用します。さらに、クライアントが準備完了するまでの最大タイムアウト期間を設定することもできます。

`result.getOrThrow()=true` の場合、`KameleoonClient` は初期化されて準備完了であり、フィーチャーフラグはそれぞれのバリエーションでトリガーされます。結果が `false` であるか、タイムアウトが発生した場合、初期化は正常に完了しません。

タイムアウトが発生した場合、ユーザーはフィーチャーフラグから除外されるため、コールバックまたはコルーチンベースのコードには、参照バリエーションを適用するロジックを含める必要があります。

<Warning>
  初期構成にはサーバーコールが必要な場合があるため、このメカニズムは非同期です。したがって、次のいずれかを行ってください。

  * メソッドの引数として `completion` コールバックを提供し、`KameleoonClient` が完全に初期化されて使用可能になったときに通知を受け取れるようにします。
  * 非同期操作を処理するためにコルーチンを使用します。
</Warning>

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    kameleoonClient.runWhenReady(1000, result -> {
        int recommendedProductsNumber = 5; // Default control number for recommended products
        try {
            if (result.getOrThrow()) {
                Variation variation = kameleoonClient.getVariation("featureKey");
                recommendedProductsNumber = (int) variation.getVariables().get("recommendedProductsNumber").getValue();
            }
        } catch (Exception ignored) {
            // The user will not be included in the experiment results and should see the control variation
        }

        applyVariation(recommendedProductsNumber);
    });
    ```

    ##### 引数

    | 名前                            | 型                                             | 説明                  | デフォルト                                                                              |
    | ----------------------------- | --------------------------------------------- | ------------------- | ---------------------------------------------------------------------------------- |
    | timeoutMilliseconds (*オプション*) | `int`                                         | 初期化プロセスのタイムアウト      | [`defaultTimeoutMillisecond`](#create) または [`default_timeout_millisecond`](#追加の設定) |
    | completion (*必須*)             | `ResultCompletion<Boolean, TimeoutException>` | 受信したデータを処理するコールバック。 |                                                                                    |
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    kameleoonClient.runWhenReady(1000) { result ->
        val recommendedProductsNumber = runCatching {
            if (result.getOrThrow()) {
                val variation = kameleoonClient.getVariation("featureKey")
                variation.variables["recommendedProductsNumber"]?.value as Int
            } else {
                null // The user will not be included in the experiment results and should see the control variation
            }
        }.getOrDefault(5)  // Default control number for recommended products

        applyVariation(recommendedProductsNumber)
    }
    ```

    ##### 引数

    | 名前                            | 型                                             | 説明                  | デフォルト                                                                              |
    | ----------------------------- | --------------------------------------------- | ------------------- | ---------------------------------------------------------------------------------- |
    | timeoutMilliseconds (*オプション*) | `Int`                                         | 初期化プロセスのタイムアウト      | [`defaultTimeoutMillisecond`](#create) または [`default_timeout_millisecond`](#追加の設定) |
    | completion (*必須*)             | `ResultCompletion<Boolean, TimeoutException>` | 受信したデータを処理するコールバック。 |                                                                                    |
  </Tab>

  <Tab title="Kotlin (Coroutines)">
    <Warning>
      よくある間違いは、`mapCatching`、`runCatching`、または `try-catch` ブロック内で suspend 関数を使用しながら、`CancellationException` を適切に再スローしないことです。これにより、コルーチンのキャンセルが妨げられる可能性があります。正しい動作を保証するため、これらのブロック内で suspend 関数を呼び出すことは避けるようにしてください。
    </Warning>

    ```kotlin theme={null}
    viewModelScope.launch {
        kameleoonClient.runWhenReady(1000).getOrNull() ?: return@launch
        val recommendedProductsNumber = runCatching {
            val variation = kameleoonClient.getVariation("featureKey")
            variation.variables["recommendedProductsNumber"]?.value as? Int
        }.getOrNull() ?: 5 // Default control number for recommended products

        applyVariation(recommendedProductsNumber)
    }
    ```

    ##### 引数

    | 名前                            | 型     | 説明             | デフォルト                                                                              |
    | ----------------------------- | ----- | -------------- | ---------------------------------------------------------------------------------- |
    | timeoutMilliseconds (*オプション*) | `Int` | 初期化プロセスのタイムアウト | [`defaultTimeoutMillisecond`](#create) または [`default_timeout_millisecond`](#追加の設定) |

    ##### 戻り値

    | 型              | 説明                                       |
    | -------------- | ---------------------------------------- |
    | `Result<Unit>` | 成功結果または発生した例外のいずれかを含む Kotlin の `Result`。 |
  </Tab>
</Tabs>

### フィーチャーフラグとバリエーション

#### isFeatureActive()

* 📨 *Kameleoon にトラッキングデータを送信します(`track` パラメータに依存)*

<Note>
  このメソッドは以前は `activateFeature` と呼ばれており、SDK バージョン `4.0.0` で削除されました。
</Note>

フィーチャートグルを有効化するためにこのメソッドを呼び出します。このメソッドは、指定されたフィーチャーが訪問者に対してアクティブになるかどうかをチェックするための必須引数として `featureKey` を受け取ります。

訪問者がこのフィーチャーフラグに以前関連付けられたことがない場合、このメソッドはランダムなブール値を返します(訪問者にこのフィーチャーを表示する場合は `true`、それ以外の場合は `false`)。訪問者がすでにこのフィーチャーフラグに登録されている場合、このメソッドは以前の `featureFlag` 値を返します。

潜在的な例外をキャッチするために、サンプルコードに示されているようにエラー処理を適切に設定してください。

<Note>
  Kameleoon は、`isFeatureActive()`、`getVariation()`、`getVariations()` などの特定のメソッドを呼び出す際に、セッションと訪問者をカウントするためにトラッキングを使用します。

  訪問者をバリエーションに公開し、それらをカウントする必要がある場合は、`track` パラメータにデフォルトの `true` 値を使用してください。訪問者を公開する前にこれらのメソッドを呼び出す場合のみ、`track` パラメータを `false` に設定してください。

  例えば、訪問者を公開する前にすべてのバリエーションを取得するために `getVariations()` を呼び出す場合、`track` パラメータを `false` に設定します。この設定により、Kameleoon がセッションを早期にカウントするのを防ぎます。その後、訪問者を明示的に公開する際にトラッキングをトリガーできます。

  Kameleoon はデフォルトで毎秒トラッキングデータを送信します。トラッキング間隔構成オプションを使用して、この間隔を最大 5 秒まで構成できます。Kameleoon は、イベント間の間隔が 30 分未満であれば、トラッキングイベントを単一のセッションにグループ化します。トラッキングイベント間に 30 分以上経過した場合、Kameleoon はそれらのイベントを別々のセッションとしてカウントします。訪問は、セッション内の最後に記録されたイベントから 30 分後にレポートに表示されます。
</Note>

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    String featureKey = "new_checkout";

    boolean hasNewCheckout = false;
    try {
        hasNewCheckout = kameleoonClient.isFeatureActive(featureKey);
        // disabling tracking
        hasNewCheckout = kameleoonClient.isFeatureActive(featureKey, false);
    } catch (KameleoonException.SDKNotReady e) {
        // Exception indicating that the SDK has not completed its initialization yet.
    } catch (KameleoonException.FeatureNotFound e) {
        // SDK not initialized, or feature toggle not yet activated in Kameleoon - we consider the feature inactive
    } catch (Exception exception) {
        // Recommended (but optional) safeguard for unexpected exceptions from third-party libraries
    }
    if (hasNewCheckout)
    {
        // Implement new checkout code here
    }
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    val featureKey = "new_checkout"
    var hasNewCheckout = false

    try {
        hasNewCheckout = kameleoonClient.isFeatureActive(featureKey)
        // disabling tracking
        hasNewCheckout = kameleoonClient.isFeatureActive(featureKey, false)
    } catch (e: KameleoonException.SDKNotReady) {
        // Exception indicating that the SDK has not completed its initialization yet.
        hasNewCheckout = false
    } catch (e: KameleoonException.FeatureNotFound) {
        // SDK not initialized or feature toggle not yet activated on Kameleoon's side - we consider the feature inactive
        hasNewCheckout = false
    } catch (e: Exception) {
        // Recommended (but optional) safeguard for unexpected exceptions from third-party libraries
        hasNewCheckout = false
    }
    if (hasNewCheckout) {
        // Implement new checkout code here
    }
    ```
  </Tab>
</Tabs>

<Warning>
  `isFeatureActive()` メソッドは、マスターフラグの状態ではなく、提供されたバリアントを評価します。ルールを除外する場合、メソッドは **その他全員に対しては、その後** のデフォルトの状態を使用します。このデフォルトの状態に **Off** を選択した場合、マスターフィーチャーフラグが **On** であっても、メソッドは常に `false` を返します。
</Warning>

##### 引数

| 名前         | 型       | 説明                                                    |
| ---------- | ------- | ----------------------------------------------------- |
| featureKey | String  | ユーザーに公開したいフィーチャーの一意のキー。このフィールドは必須です。                  |
| track      | boolean | フィーチャー評価のトラッキングを有効または無効にするオプションのパラメータ(デフォルトは `true`)。 |

##### 戻り値

| 型       | 説明                 |
| ------- | ------------------ |
| Boolean | 訪問者に登録されたフィーチャーの値。 |

##### スローされる例外

| 型               | 説明                                                                                                                                          |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| SDKNotReady     | SDK が初期化を完了していないことを示す例外。                                                                                                                    |
| FeatureNotFound | リクエストされたフィーチャー ID が SDK の内部構成に見つからなかったことを示す例外。この例外は通常、フィーチャーフラグが Kameleoon 側でアクティブ化されていない(ただし、フィーチャーを実装するコードはアプリケーションで既にデプロイされている)ことを意味します。 |

#### getVariation()

* 📨 *Kameleoon にトラッキングデータを送信します(`track` パラメータに依存)*

特定の訪問者に対して、特定のフィーチャーフラグに割り当てられた [`Variation`](#variation) を取得します。

このメソッドは、必須の引数として `visitorCode` と `featureKey` を受け取ります。`track` 引数はオプションで、デフォルトは `true` です。

訪問者に割り当てられた `Variation` を返します。訪問者がいずれのフィーチャーフラグルールにも関連付けられていない場合、このメソッドは特定のフィーチャーフラグのデフォルトの `Variation` を返します。

潜在的な例外を管理するため、コード内で適切なエラー処理が実装されていることを確認してください。

<Note>
  デフォルトのバリエーションとは、フィーチャーフラグの事前定義された配信ルールに一致しない場合に訪問者に割り当てられるバリエーションを指します。言い換えると、特定のルールでターゲットにされていないすべてのユーザーに適用されるフォールバックバリエーションです。管理インターフェースの「その他全員に対しては...」セクションのバリエーションとして表されます。
</Note>

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    final String featureKey = "featureKey";
    Variation variation = null;

    try {
        variation = kameleoonClient.getVariation(featureKey);
        // disabling tracking
        variation = kameleoonClient.getVariation(featureKey, false);
    } catch (KameleoonException.SDKNotReady ex) {
        // Exception indicating that the SDK has not completed its initialization yet.
    } catch (KameleoonException.FeatureNotFound ex) {
        // The feature key is not in the configuration file that has been fetched by the SDK.
    } catch (KameleoonException.FeatureEnvironmentDisabled ex) {
        // The feature flag is disabled for the environment.
    }

    if (variation != null) {
        String title = (String) variation.getVariables().get("title").getValue();

        switch (variation.getKey()) {
            case "on":
                // Main variation key is selected for visitorCode
                break;
            case "alternative_variation":
                // Alternative variation key
                break;
            default:
                // Default variation key
                break;
        }
    }
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    val featureKey = "featureKey"
    var variation: Variation? = null

    try {
        variation = kameleoonClient.getVariation(featureKey)
        // disabling tracking
        variation = kameleoonClient.getVariation(featureKey, false)
    } catch (e: KameleoonException.SDKNotReady) {
        // Exception indicating that the SDK has not completed its initialization yet.
    } catch (e: KameleoonException.FeatureNotFound) {
        // The feature key is not yet in the configuration file that has been fetched by the SDK.
    } catch (e: KameleoonException.FeatureEnvironmentDisabled) {
        // The feature flag is disabled for the environment
    }

    val title = variation?.variables?.get("title")?.value as? String

    when (variation?.key) {
        "on" -> {
            // Main variation key is selected for visitorCode
        }
        "alternative_variation" -> {
            // Alternative variation key
        }
        else -> {
            // Default variation key
        }
    }
    ```
  </Tab>
</Tabs>

##### 引数

| 名前                 | 型         | 説明                                     | デフォルト  |
| ------------------ | --------- | -------------------------------------- | ------ |
| visitorCode (*必須*) | `String`  | 訪問者の一意の識別子。                            |        |
| featureKey (*必須*)  | `String`  | 訪問者に公開したいフィーチャーのキー。                    |        |
| track (*オプション*)    | `boolean` | フィーチャー評価のトラッキングを有効または無効にするオプションのパラメータ。 | `true` |

##### 戻り値

| 型           | 説明                                                         |
| ----------- | ---------------------------------------------------------- |
| `Variation` | 特定のフィーチャーフラグに対して、特定の訪問者に割り当てられた [`Variation`](#variation)。 |

##### スローされる例外

| 型                            | 説明                                                                                                                                        |
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `VisitorCodeInvalid`         | 提供された訪問者コードが有効でないことを示す例外。空であるか、255 文字より長いかのいずれかです。                                                                                        |
| `FeatureNotFound`            | リクエストされたフィーチャーキーが SDK の内部構成に見つからなかったことを示す例外。これは通常、フィーチャーフラグが Kameleoon アプリでアクティブ化されていない(ただし、フィーチャーを実装するコードはアプリケーションで既にデプロイされている)ことを意味します。 |
| `FeatureEnvironmentDisabled` | 訪問者の現在の環境(例: production、staging、development)でフィーチャーフラグが無効になっていることを示す例外。                                                                   |

#### getVariations()

* 📨 *Kameleoon にトラッキングデータを送信します(`track` パラメータに依存)*

すべてのフィーチャーフラグにわたって特定の訪問者に割り当てられた [`Variation`](#variation) オブジェクトのマップを取得します。

このメソッドは、利用可能なすべてのフィーチャーフラグを反復処理し、指定された訪問者に関連付けられた各フラグに割り当てられた `Variation` を返します。`onlyActive` および `track` をオプションの引数として受け取ります。

* `onlyActive` が `true` に設定されている場合、`getVariations()` メソッドは、ユーザーが `off` バリエーションでバケットされていない限り、フィーチャーフラグのバリエーションを返します。
* `track` パラメータは、メソッドがバリエーションの割り当てを追跡するかどうかを制御します。デフォルトでは `true` に設定されています。`false` に設定すると、トラッキングは無効になります。

返されるマップは、フィーチャーフラグのキーをキー、対応する `Variation` を値として構成されます。フィーチャーフラグに割り当てられたバリエーションがない場合、メソッドはそのフラグのデフォルトの `Variation` を返します。

潜在的な例外を管理するため、適切なエラー処理が実装されているべきです。

<Note>
  デフォルトのバリエーションとは、フィーチャーフラグの事前定義された配信ルールに一致しない場合に訪問者に割り当てられるバリエーションを指します。言い換えると、特定のルールでターゲットにされていないすべてのユーザーに適用されるフォールバックバリエーションです。管理インターフェースの「その他全員に対しては...」セクションのバリエーションとして表されます。
</Note>

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    try {
        Map<String, Variation> variations = kameleoonClient.getVariations();
        // only active variations
        Map<String, Variation> variations = kameleoonClient.getVariations(true);
        // disable tracking
        Map<String, Variation> variations = kameleoonClient.getVariations(false, false);
    } catch (KameleoonException.SDKNotReady ex) {
        // Exception indicating that the SDK has not completed its initialization yet.
    }
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    try {
        val variations = kameleoonClient.getVariations()
        // only active variations
        val variations = kameleoonClient.getVariations(true)
        // disable tracking
        val variations = kameleoonClient.getVariations(false, false)
    } catch (e: KameleoonException.SDKNotReady) {
        // Exception indicating that the SDK has not completed its initialization yet.
    }
    ```
  </Tab>
</Tabs>

##### 引数

| 名前                   | 型         | 説明                                                                                          | デフォルト   |
| -------------------- | --------- | ------------------------------------------------------------------------------------------- | ------- |
| onlyActive (*オプション*) | `boolean` | アクティブな (`true`) フィーチャーフラグのみのバリエーションを返すか、すべての (`false`) フィーチャーフラグのバリエーションを返すかを示すオプションのパラメータ。 | `false` |
| track (*オプション*)      | `boolean` | フィーチャー評価のトラッキングを有効または無効にするオプションのパラメータ。                                                      | `true`  |

##### 戻り値

| 型                        | 説明                                                                           |
| ------------------------ | ---------------------------------------------------------------------------- |
| `Map<String, Variation>` | 対応するフィーチャーのキーを使用して、フィーチャーフラグの割り当てられた [`Variation`](#variation) オブジェクトを含むマップ。 |

##### スローされる例外

| 型             | 説明                          |
| ------------- | --------------------------- |
| `SDKNotReady` | SDK がまだ完全に初期化されていないことを示します。 |

#### setForcedVariation()

このメソッドを使用すると、標準の評価プロセスをバイパスして、特定の [`Variation`](#variation) をユーザーにプログラム的に割り当てることができます。これは、通常の評価ロジックが不要、またはスキップする必要がある制御された実験で特に貴重です。また、デバッグやカスタムテストなどのシナリオでも役立ちます。

**強制** バリエーションが設定されると、Kameleoon のリアルタイム評価ロジックがオーバーライドされます。セグメンテーション、ターゲティング条件、アルゴリズム計算などのプロセスはスキップされます。実験中のセグメンテーションとターゲティング条件を維持するには、代わりに `forceTargeting=false` を設定します。

強制バリエーションは、評価されたバリエーションと同じように扱われます。標準の評価されたバリエーションと同様に分析で追跡され、ユーザーコンテキストに保存されるため、レポートの一貫性が保証されます。

このメソッドは、特定の条件下(例: 無効なパラメータ、ユーザーコンテキスト、内部の問題)で例外をスローする可能性があります。アプリケーションが安定して回復力があることを保証するため、適切な例外処理が不可欠です。

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    final int experimentId = 9516;
    try {
        // Forcing the variation "on" for the experiment 9516 for the visitor
        kameleoonClient.setForcedVariation(experimentId, "on");

        // Forcing the variation "on" while preserving segmentation and targeting conditions during the experiment
        kameleoonClient.setForcedVariation(experimentId, "on", false);

        // Resetting the forced variation for the experiment 9516 for the visitor
        kameleoonClient.setForcedVariation(experimentId, null);
    } catch (KameleoonException e) {
        // Handling the exception
    }
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    val experimentId = 9516
    try {
        // Forcing the variation "on" for the experiment 9516 for the visitor
        kameleoonClient.setForcedVariation(experimentId, "on")

        // Forcing the variation "on" while preserving segmentation and targeting conditions during the experiment
        kameleoonClient.setForcedVariation(experimentId, "on", false)

        // Resetting the forced variation for the experiment 9516 for the visitor
        kameleoonClient.setForcedVariation(experimentId, null)
    } catch (e: KameleoonException) {
        // Handling the exception
    }
    ```
  </Tab>
</Tabs>

##### 引数

| 名前                       | 型         | 説明                                                                               | デフォルト  |
| ------------------------ | --------- | -------------------------------------------------------------------------------- | ------ |
| experimentId (*必須*)      | `int`     | 評価プロセス中にターゲットにされ、選択される **実験 ID**。                                                |        |
| variationKey (*必須*)      | `String`  | 実験の戻り値として強制すべき `Variation` に対応する **バリエーションキー**。値が `null` の場合、強制バリエーションはリセットされます。 |        |
| forceTargeting (*オプション*) | `boolean` | 実験のターゲティングを強制してスキップする (`true`)、または標準の評価プロセスのように適用する (`false`) かを示します。            | `true` |

##### スローされる例外

| 型                           | 説明                                                                                                               |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| `SDKNotReady`               | SDK がまだ完全に初期化されていないことを示します。                                                                                      |
| `FeatureExperimentNotFound` | リクエストされた実験 ID が SDK の内部構成に見つからなかったことを示す例外。これは通常正常であり、ルールの対応する実験が Kameleoon 側でまだアクティブ化されていないことを意味します。             |
| `FeatureVariationNotFound`  | リクエストされたバリエーションキー(ID) が SDK の内部構成に見つからなかったことを示す例外。これは通常正常であり、バリエーションの対応する実験が Kameleoon 側でまだアクティブ化されていないことを意味します。 |

<Info>
  ほとんどの場合、例で示すように、基本のエラーである `KameleoonException` のみを処理すれば十分です。ただし、異なるタイプのエラーに対して応答が必要な場合は、特定の要件に基づいて各々を個別に処理してください。さらに、信頼性を高めるために、一般的な言語エラーを処理するために `Exception` を含めることもできます。
</Info>

#### evaluateAudiences()

* 📨 *Kameleoon にトラッキングデータを送信します*

このメソッドは、利用可能なすべての Audiences Explorer セグメントに対して訪問者を評価し、一致する訪問者を追跡します。

`evaluateAudiences()` は **関連するすべての訪問者データがセットまたは更新された後**、フィーチャーバリエーションを取得するかフィーチャーフラグをチェックする **直前** に呼び出される必要があります。このアプローチにより、訪問者が利用可能な最新のデータに対して評価されることが保証され、すべての基準に基づいて正確なオーディエンス割り当てが可能になります。

このメソッドを呼び出した後、Audiences Explorer でセグメントのパフォーマンスを詳細に分析できます。

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    try {
        kameleoonClient.evaluateAudiences();
    } catch (KameleoonException e) {
        // Handling the exception
    }
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    try {
        kameleoonClient.evaluateAudiences()
    } catch (e: KameleoonException) {
        // Handling the exception
    }
    ```
  </Tab>
</Tabs>

##### スローされる例外

| 型             | 説明                          |
| ------------- | --------------------------- |
| `SDKNotReady` | SDK がまだ完全に初期化されていないことを示します。 |

<Info>
  ほとんどの場合、例で示すように、基本のエラーである `KameleoonException` のみを処理すれば十分です。ただし、異なるタイプのエラーに対して応答が必要な場合は、特定の要件に基づいて各々を個別に処理してください。さらに、信頼性を高めるために、一般的な言語エラーを処理するために `Exception` を含めることもできます。
</Info>

#### getDataFile()

<Tip>
  すべてのフィーチャーフラグを評価するには、[`getVariations()`](#getvariations) を使用します。このメソッドは、`DataFile` を呼び出して [`getVariation()`](#getvariation) でフラグを反復処理するよりも効率的です。
</Tip>

現在の SDK 構成を [`DataFile`](#datafile) オブジェクトとして返します。

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    try {
        DataFile dataFile = kameleoonClient.getDataFile();
    } catch (KameleoonException.SDKNotReady e) {
        // Exception indicates that the SDK has not completed its initialization yet.
    } catch (Exception e) {
        // Recommended (but optional) safeguard for unexpected exceptions from third-party libraries
    }
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    try {
        val dataFile = kameleoonClient.dataFile
        val dateModified = dataFile.dateModified
    } catch (e: KameleoonException.SDKNotReady) {
        // Exception indicates that the SDK has not completed its initialization yet.
    } catch (e: Exception) {
        // Recommended (but optional) safeguard for unexpected exceptions from third-party libraries
    }
    ```
  </Tab>
</Tabs>

##### 戻り値

| 型          | 説明                                 |
| ---------- | ---------------------------------- |
| `DataFile` | SDK 構成を含む [`DataFile`](#datafile)。 |

##### スローされるエラー

| 型             | 説明                          |
| ------------- | --------------------------- |
| `SDKNotReady` | SDK がまだ完全に初期化されていないことを示します。 |

### 目標

#### trackConversion()

* 📨 *Kameleoon にトラッキングデータを送信します*

コンバージョンを追跡するためにこのメソッドを使用します。このメソッドは、この特定の [目標](/user-manual//assets/goals/create-a-goal) でコンバージョンを追跡するために `goalId` を必要とします。さらに、このメソッドは `revenue`、`metadata`、`negative` 引数も受け取ります。

`trackConversion()` メソッドは値を返しません。このメソッドは、サーバーコールが非同期で行われるため非ブロッキングです。

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    final int goalId = 83023;
    kameleoonClient.trackConversion(goalId); // default revenue

    kameleoonClient.trackConversion(goalId, 10); // provided revenue == 10

    kameleoonClient.trackConversion(goalId, new CustomData(1, "metadata")); // Add metadata
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    val goalId = 83023
    kameleoonClient.trackConversion(goalId) // default revenue

    kameleoonClient.trackConversion(goalId, 10f) // provided revenue == 10

    kameleoonClient.trackConversion(goalId, CustomData(1, "metadata")) // Add metadata
    ```
  </Tab>
</Tabs>

##### 引数

| 名前                 | 型               | 説明                                                                                              | デフォルト               |
| ------------------ | --------------- | ----------------------------------------------------------------------------------------------- | ------------------- |
| goalId (*必須*)      | `int`           | 目標の ID。                                                                                         |                     |
| revenue (*オプション*)  | `float`         | コンバージョンの収益。                                                                                     | `0`                 |
| negative (*オプション*) | `boolean`       | 収益が正か負かを定義します。                                                                                  | `false`             |
| metadata (*オプション*) | `CustomData...` | コンバージョンのメタデータ。[Kameleoon アプリで事前に定義する必要があります](/ja/user-manual/assets/goals/create-a-goal#メタデータ)。 | `new CustomData[0]` |

<Note>
  メタデータの値は、[生データのエクスポート](/user-manual/experiment-analytics/analyze-results/results-page/results-page-actions#Export) および [結果ページ](/user-manual/experiment-analytics/analyze-results/data-and-metrics/goal-metadata) からアクセスできます。

  `metadata` パラメータが指定されている場合、Kameleoon は [`addData()`](#adddata) メソッドを使用して以前に収集されたものではなく、現在のコンバージョンにこれらの指定された値を使用します。パラメータが省略された場合、Kameleoon は、コンバージョン前および同じ訪問内で最後に追跡された [`CustomData`](#customdata) の値を使用します。

  Kameleoon は、`trackConversion()` メソッドにパラメータとして明示的に渡されたメタデータ値のみを考慮します。

  以下の例では、Kameleoon は、パラメータとして明示的に提供されたカスタムデータ値(ここではインデックス 5、値 'Amex Credit Card') のみとコンバージョンを関連付けます。

  <Tabs defaultTabIndex={1}>
    <Tab title="Java">
      ```java theme={null}
      kameleoonClient.addData(new CustomData(5, "Credit Card"), new CustomData(9, "Express Delivery"));
      kameleoonClient.trackConversion(1000, new CustomData(5, "Amex Credit Card"));
      ```
    </Tab>

    <Tab title="Kotlin">
      ```kotlin theme={null}
      kameleoonClient.addData(CustomData(5, "Credit Card"), CustomData(9, "Express Delivery"))
      kameleoonClient.trackConversion(1000, CustomData(5, "Amex Credit Card"))
      ```
    </Tab>
  </Tabs>
</Note>

### イベント

#### onUpdateConfiguration()

<Note>
  このメソッドは以前は `updateConfigurationHandler` と呼ばれており、SDK バージョン `4.0.0` リリースで削除されました。
</Note>

`onUpdateConfiguration()` メソッドを使用すると、構成がデータを更新したときのイベントを処理できます。1 つの入力パラメータ **completion** を受け取ります。リアルタイム構成イベントを使用して構成が更新されたときに呼び出される completion です。

<Note>
  このハンドラは、SDK が [ストリーミングモード](/developer-docs/feature-experimentation/technical-reference/technical-considerations#ストリーミング（プレミアムオプション）) (サーバー送信イベント) で実行されている場合にのみ起動します。デフォルトのポーリングモード (`refreshIntervalMinute`) で実行される設定の更新では **呼び出されません**。
</Note>

##### 引数

| 名前         | 型                                   | 説明                                      |
| ---------- | ----------------------------------- | --------------------------------------- |
| completion | `ResultCompletion<Long, Exception>` | リアルタイム構成イベントを使用して構成が更新されたときに呼び出されるハンドラ。 |

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    kameleoonClient.onUpdateConfiguration(result -> {
        if (result.isSuccess()) {
            // result value contains the value of Unix time (number of seconds that have elapsed since January 1, 1970) when configuration was updated
        }
    });
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    kameleoonClient.onUpdateConfiguration { result ->
        if (result.isSuccess) {
            // result value contains the value of Unix time (number of seconds that have elapsed since January 1, 1970) when configuration was updated
        }
    }
    ```
  </Tab>
</Tabs>

### 訪問者データ

#### getVisitorCode()

SDK で使用される一意の訪問者コードを返します。

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    String visitorCode = kameleoonClient.getVisitorCode();
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    val visitorCode = kameleoonClient.visitorCode
    ```
  </Tab>
</Tabs>

##### 戻り値

| 型        | 説明                         |
| -------- | -------------------------- |
| `String` | SDK で使用される一意の訪問者コードを表す文字列。 |

#### addData()

`addData()` メソッドは、[ターゲティングデータ](#データタイプ) をストレージに追加し、他のメソッドがこのデータを使用して現在の訪問者をターゲットにするかどうかを判断できるようにします。

`addData()` メソッドは値を返さず、それ自体では Kameleoon バックエンドサーバーと対話しません。代わりに、すべての宣言されたデータは [`flush()`](#flush) メソッドを使用した将来の送信のために保存されます。このアプローチは、データが通常、`flush()` でトリガーされる単一のサーバーコールにグループ化されるため、サーバーコールの数を削減します。

[`trackConversion()`](#trackconversion) メソッドも、`flush()` と同様に、以前に関連付けられたデータを送信します。実験ルールがトリガーされた場合、[`getVariation()`](#getvariation) および [`getVariations()`](#getvariations) メソッドにも同じことが当てはまります。

<Tip>
  ほとんどのデータタイプについて、各訪問者は関連付けられたデータのインスタンスを 1 つしか持てません。ただし、[`CustomData`](#customdata) は例外です。訪問者はインデックスごとに 1 つの関連付けられた `CustomData` インスタンスを持つことができます。
</Tip>

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    // Add a single data item (tracked by default)
    kameleoonClient.addData(new CustomData(1, "value"));

    // Add multiple data items (tracked by default)
    kameleoonClient.addData(new CustomData(1, "value"), new Geolocation("France"));

    // Add multiple data items stored locally for targeting only (not sent to the Kameleoon Data API)
    kameleoonClient.addData(false, new CustomData(1, "value"), new Geolocation("France"));
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    // Add a single data item (tracked by default)
    kameleoonClient.addData(CustomData(1, "value"))

    // Add multiple data items (tracked by default)
    kameleoonClient.addData(CustomData(1, "value"), Geolocation("France"))

    // Add multiple data items stored locally for targeting only (not sent to the Kameleoon Data API)
    kameleoonClient.addData(false, CustomData(1, "value"), Geolocation("France"))
    ```
  </Tab>
</Tabs>

##### 引数

| 名前              | 型         | 説明                                                                                                            | デフォルト値 |
| --------------- | --------- | ------------------------------------------------------------------------------------------------------------- | ------ |
| track (*オプション*) | `boolean` | 追加されたデータがトラッキング対象かどうかを指定します。`false` に設定されている場合、データはローカルに保存され、ターゲティング評価にのみ使用されます。Kameleoon Data API には送信されません。 | `true` |
| data (*必須*)     | `Data...` | Kameleoon データタイプのコレクション。                                                                                      |        |

#### flush()

* 📨 *Kameleoon にトラッキングデータを送信します*

`flush()` は、訪問者に関連付けられた Kameleoon データを受け取り、まだ送信されていない `addData()` メソッドを使用して以前に追加されたすべてのデータとともにトラッキングリクエストを送信します。これらのメソッドのいずれかを呼び出す際に([こちらのメソッド](/developer-docs/feature-experimentation/technical-reference/faq-global#when-does-the-sdk-send-a-tracking-request-for-analytics) で確認できます)。`flush()` は、サーバーコールが非同期で行われるため非ブロッキングです。

`flush()` は、訪問者に関連付けられたデータがいつサーバーに送信されるかを制御します。たとえば、`addData()` が 12 回呼び出される場合、各 `addData()` 呼び出し後にデータをサーバーに送信するのは非効率です。最後に一度 `flush()` を呼び出します。

`flush()` メソッドは、`visitorCode` を一意の訪問者識別子として使用します。これは [クロスデバイス実験](/developer-docs/cross-device-experimentation) に役立ちます。`isUniqueIdentifier` 構成パラメータを `true` に設定すると、SDK は、フラッシュされたデータを指定された識別子に関連付けられた訪問者にリンクします。

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    kameleoonClient.addData(Device.phone());
    kameleoonClient.addData(new Conversion(32, 10f, false));

    kameleoonClient.flush(); // Interval tracking (most performant tracking method)

    kameleoonClient.flush(true); // Instant tracking
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    kameleoonClient.addData(Device.phone())
    kameleoonClient.addData(Conversion(32, 10f, false))

    kameleoonClient.flush() // Interval tracking (most performant tracking method)

    kameleoonClient.flush(true) // Instant tracking
    ```
  </Tab>
</Tabs>

##### 引数

| 名前      | 型       | 説明                                                                                                       |
| ------- | ------- | -------------------------------------------------------------------------------------------------------- |
| instant | boolean | データを即座に送信するか (`true`)、スケジュールされたトラッキング間隔に従って送信するか (`false`) を示すブールフラグ。このフィールドはオプションです。デフォルト値は `false` です。 |

#### getRemoteData()

* 🔄 *非同期リクエストを実行します*

<Note>
  このメソッドは以前 `retrieveDataFromRemoteSource` と呼ばれており、SDK バージョン `4.0.0` で削除されました。
</Note>

アクティブな `siteCode` と `key` 引数(または `key` が省略された場合はアクティブな `visitorCode`)に基づいて、リモートの Kameleoon サーバーからデータを取得するためにこのメソッドを使用します。`visitorCode` および `siteCode` は `KameleoonClientFactory.create()` で指定されます。Kameleoon Data API を使用して、データを非常にスケーラブルなリモートサーバーに迅速かつ便利に保存できます。アプリケーションは、このメソッドを使用してデータを取得できます。

<Warning>
  サーバーコールが必要なため、このメカニズムは非同期です。したがって、次のいずれかを行ってください。

  * メソッドの引数として `completion` コールバックを提供し、データが正常に取得されたときに通知を受け取れるようにします。
  * 非同期処理のためにコルーチンを使用します。
</Warning>

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    kameleoonClient.getRemoteData("key", result -> {
        try {
            JSONObject jsonObject = result.getOrThrow();
            // jsonObject contains result of request
        } catch (Exception ex) {
            // request failed with an exception
        }
    });
    ```

    ##### 引数

    | 名前                | 型                                         | 説明                   | デフォルト  |
    | ----------------- | ----------------------------------------- | -------------------- | ------ |
    | key (*オプション*)     | `String`                                  | 取得するデータが関連付けられているキー。 | `null` |
    | completion (*必須*) | `ResultCompletion<JSONObject, Exception>` | 受信したデータを処理するコールバック。  |        |
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    kameleoonClient.getRemoteData("key") { result ->
        try {
            val jsonObject: JSONObject = result.getOrThrow()
            // jsonObject contains result of request
        } catch (ex: Exception) {
            // request failed with an exception
        }
    }
    ```

    ##### 引数

    | 名前                | 型                                         | 説明                   | デフォルト  |
    | ----------------- | ----------------------------------------- | -------------------- | ------ |
    | key (*オプション*)     | `String`                                  | 取得するデータが関連付けられているキー。 | `null` |
    | completion (*必須*) | `ResultCompletion<JSONObject, Exception>` | 受信したデータを処理するコールバック。  |        |
  </Tab>

  <Tab title="Kotlin (Coroutines)">
    <Warning>
      よくある間違いは、`mapCatching`、`runCatching`、または `try-catch` ブロック内で suspend 関数を使用しながら、`CancellationException` を適切に再スローしないことです。これにより、コルーチンのキャンセルが妨げられる可能性があります。正しい動作を保証するため、これらのブロック内で suspend 関数を呼び出すことは避けるようにしてください。
    </Warning>

    ```kotlin theme={null}
    viewModelScope.launch {
        val jsonObject = kameleoonClient.getRemoteData("key").getOrNull() ?: return@launch
    }
    ```

    ##### 引数

    | 名前            | 型        | 説明                   | デフォルト  |
    | ------------- | -------- | -------------------- | ------ |
    | key (*オプション*) | `String` | 取得するデータが関連付けられているキー。 | `null` |

    ##### 戻り値

    | 型                    | 説明                                                        |
    | -------------------- | --------------------------------------------------------- |
    | `Result<JSONObject>` | 取得した値 (`JSONObject`) または発生した例外のいずれかを含む Kotlin の `Result`。 |
  </Tab>
</Tabs>

#### getRemoteVisitorData()

* 🔄 *非同期リクエストを実行します*

`getRemoteVisitorData()` は、Kameleoon Data API から訪問者の Kameleoon 訪問データを取得する非同期メソッドです。このメソッドは、他のメソッドがターゲティング決定を行う際に使用するデータをストレージに追加します。

このメソッドで取得したデータは、次のような場合に重要な役割を果たします。

* 他のデバイスから収集されたデータを使用する場合。
* 前回の訪問中に収集されたカスタムデータなど、ユーザーの履歴にアクセスする場合。

可能なユースケースの理解を深めるには、[この記事](/developer-docs/feature-experimentation/targeting-and-segmentation/native-segmentation) を参照してください。

<Info>
  デフォルトでは、`getRemoteVisitorData()` は、`scope=Visitor` で最新に保存されたカスタムデータを自動的に取得し、`addData()` メソッドを呼び出すことなく訪問者にアタッチします。これは特に [複数のデバイス間でカスタムデータを同期する](/developer-docs/sdks/web-sdks/nodejs-sdk#synchronizing-custom-data-across-devices) のに役立ちます。

  失敗した結果のみを確認することが推奨されます。ただし、必要に応じて、データが訪問者に追加され、ターゲティング目的(またはデバッグ用、ただしデバッグには [ロギング](#ロギング) を使用する方が良いです)で利用できることを確認できます。さらに、`shouldAddData=false` パラメータが渡された場合、データを手動で管理できます。
</Info>

<Warning>
  サーバーコールが必要なため、このメカニズムは非同期です。したがって、次のいずれかを行ってください。

  * メソッドの引数として `completion` コールバックを提供し、データが正常に取得されて訪問者に追加されたときに通知を受け取れるようにします。
  * 非同期処理のためにコルーチンを使用します。
</Warning>

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    // Visitor data will be fetched and automatically added for `visitorCode`.
    kameleoonClient.getRemoteVisitorData(result -> {
        if (result.isSuccess()) {
            // Data was successfully retrieved from the Kameleoon servers and added to the visitor.
        } else {
            // The request failed due to an exception.
        }
    });

    // If you only want to fetch data and add it yourself manually, set shouldAddData == `false`.
    kameleoonClient.getRemoteVisitorData(false, result -> {
        try {
            List<Data> visitorData = result.getOrThrow();
            // visitorData contains the fetched visitor data from Kameleoon servers, which can be manually added.
        } catch (Exception ex) {
            // The request failed due to an exception.
        }
    });

    // If you want to fetch custom list of data types
    RemoteVisitorDataFilter filter = RemoteVisitorDataFilter.builder()
            .previousVisitAmount(25)
            .experiments(true)
            .conversion(true)
            .build();
    kameleoonClient.getRemoteVisitorData(filter, result -> {
        if (result.isSuccess()) {
            // Data was successfully retrieved from the Kameleoon servers and added to the visitor.
        } else {
            // The request failed due to an exception.
        }
    });
    ```

    ##### 引数

    | 名前                      | 型                                         | 説明                                                                         | デフォルト  |
    | ----------------------- | ----------------------------------------- | -------------------------------------------------------------------------- | ------ |
    | filter (*オプション*)        | `RemoteVisitorDataFilter`                 | 訪問履歴から取得するデータを選択するフィルター。デフォルトでは、このメソッドは現在および最新の前の訪問から `CustomData` を取得します。 | `null` |
    | shouldAddData (*オプション*) | `boolean`                                 | メソッドが取得したデータを自動的に訪問者に追加するかどうかを示すブール値。                                      | `true` |
    | completion (*必須*)       | `ResultCompletion<List<Data>, Exception>` | 受信した訪問者データを処理するコールバック。                                                     |        |
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    // Visitor data will be fetched and automatically added to the visitor.
    kameleoonClient.getRemoteVisitorData { result ->
        if (result.isSuccess) {
            // Data was successfully retrieved from the Kameleoon servers and added to the visitor.
        } else {
            // The request failed due to an exception.
        }
    }

    // If you only want to fetch data and add it yourself manually, set shouldAddData == `false`
    kameleoonClient.getRemoteVisitorData(false) { result ->
        try {
            val visitorData = result.getOrThrow()
            // visitorData contains the fetched visitor data from Kameleoon servers, which can be manually added.
        } catch (e: Exception) {
            // The request failed due to an exception.
        }
    }

    val filter = RemoteVisitorDataFilter.builder()
        .previousVisitAmount(25)
        .experiments(true)
        .conversion(true)
        .build()
    kameleoonClient.getRemoteVisitorData(filter) { result ->
        if (result.isSuccess) {
            // Data was successfully retrieved from the Kameleoon servers and added to the visitor.
        } else {
            // The request failed due to an exception.
        }
    }
    ```

    ##### 引数

    | 名前                      | 型                                         | 説明                                                                         | デフォルト  |
    | ----------------------- | ----------------------------------------- | -------------------------------------------------------------------------- | ------ |
    | filter (*オプション*)        | `RemoteVisitorDataFilter`                 | 訪問履歴から取得するデータを選択するフィルター。デフォルトでは、このメソッドは現在および最新の前の訪問から `CustomData` を取得します。 | `null` |
    | shouldAddData (*オプション*) | `Boolean`                                 | メソッドが取得したデータを自動的に訪問者に追加するかどうかを示すブール値。                                      | `true` |
    | completion (*必須*)       | `ResultCompletion<List<Data>, Exception>` | 受信した訪問者データを処理するコールバック。                                                     |        |
  </Tab>

  <Tab title="Kotlin (Coroutines)">
    <Warning>
      よくある間違いは、`mapCatching`、`runCatching`、または `try-catch` ブロック内で suspend 関数を使用しながら、`CancellationException` を適切に再スローしないことです。これにより、コルーチンのキャンセルが妨げられる可能性があります。正しい動作を保証するため、これらのブロック内で suspend 関数を呼び出すことは避けるようにしてください。
    </Warning>

    ```kotlin theme={null}
    // Visitor data will be fetched and automatically added for `visitorCode`
    viewModelScope.launch {
        kameleoonClient.getRemoteVisitorData() ?: return@launch
    }

    // If you only want to fetch data and add it yourself manually, set shouldAddData == `false`
    viewModelScope.launch {
        kameleoonClient.getRemoteVisitorData(shouldAddData = false)
            .onSuccess { visitorData ->
                // visitorData contains the fetched visitor data from Kameleoon servers, which can be manually added.
            }.onFailure { ex ->
                // request failed with exception
            }
    }

    viewModelScope.launch {
        val filter = RemoteVisitorDataFilter.builder()
            .previousVisitAmount(25)
            .experiments(true)
            .conversion(true)
            .build()
        // In general, we recommend checking only if the request fails.
        kameleoonClient.getRemoteVisitorData(filter) ?: return@launch
    }
    ```

    ##### 引数

    | 名前                      | 型                         | 説明                                                                         | デフォルト  |
    | ----------------------- | ------------------------- | -------------------------------------------------------------------------- | ------ |
    | filter (*オプション*)        | `RemoteVisitorDataFilter` | 訪問履歴から取得するデータを選択するフィルター。デフォルトでは、このメソッドは現在および最新の前の訪問から `CustomData` を取得します。 | `null` |
    | shouldAddData (*オプション*) | `Boolean`                 | メソッドが取得したデータを自動的に訪問者に追加するかどうかを示すブール値。                                      | `true` |

    ##### 戻り値

    | 型                    | 説明                                                        |
    | -------------------- | --------------------------------------------------------- |
    | `Result<List<Data>>` | 取得した値 (`List<Data>`) または発生した例外のいずれかを含む Kotlin の `Result`。 |
  </Tab>
</Tabs>

##### `RemoteVisitorDataFilter` のパラメータの使用

`getRemoteVisitorData()` メソッドは、訪問者のデータを取得する際にさまざまなパラメータを定義できる柔軟性を提供します。目標、実験、またはバリエーションに基づいてターゲティングする場合でも、同じアプローチがすべてのデータタイプに適用されます。

たとえば、「注文取引」という目標を完了した訪問者のデータを取得したいとします。`getRemoteVisitorData()` メソッド内でパラメータを指定して、ターゲティングを絞り込むことができます。例えば、最近の 5 回の訪問で目標に変換したユーザーのみをターゲットにしたい場合は、`previousVisitAmount` パラメータを `5` に、`conversions` を `true` に設定できます。

この例で示される柔軟性は、目標データに限定されません。`getRemoteVisitorData()` メソッド内のパラメータを使用して、さまざまな訪問者の行動に関するデータを取得できます。

<Note>
  利用可能な `RemoteVisitorDataFilter` オプションの一覧は次のとおりです。

  | 名前                            | 型         | 説明                                                                                                                                                                                      | デフォルト   |
  | ----------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
  | previousVisitAmount (*オプション*) | `int`     | データを取得する前回の訪問回数。`1` から `25` の間の数                                                                                                                                                        | `1`     |
  | currentVisit (*オプション*)        | `boolean` | true の場合、現在の訪問データが取得されます                                                                                                                                                                | `true`  |
  | customData (*オプション*)          | `boolean` | true の場合、カスタムデータが取得されます。                                                                                                                                                                | `true`  |
  | geolocation (*オプション*)         | `boolean` | true の場合、ジオロケーションデータが取得されます。                                                                                                                                                            | `false` |
  | conversions (*オプション*)         | `boolean` | true の場合、コンバージョンデータが取得されます。                                                                                                                                                             | `false` |
  | experiments (*オプション*)         | `boolean` | true の場合、実験データが取得されます。                                                                                                                                                                  | `false` |
  | kcs (*オプション*)                 | `boolean` | true の場合、Kameleoon Conversion Score (KCS) が取得されます。[AI Predictive Targeting アドオン](/user-manual/ai-predictive-targeting/target-users-based-on-likelihood-to-convert) が必要です                | `false` |
  | visitorCode (*オプション*)         | `boolean` | true の場合、Kameleoon は最近の訪問から `visitorCode` を取得し、現在の訪問に使用します。これは、`visitorCode` で識別される訪問者が、[クロスデバイス実験](/developer-docs/cross-device-experimentation) のために訪問間で常に同じバリエーションを受けるようにしたい場合に必要です。 | `true`  |
  | personalization (*オプション*)     | `boolean` | true の場合、パーソナライゼーションデータが取得されます。これはパーソナライゼーション条件に必要です。                                                                                                                                   | `false` |
  | cbs (*オプション*)                 | `boolean` | true の場合、Contextual Bandit スコアデータが取得されます。                                                                                                                                               | `false` |
</Note>

#### getVisitorWarehouseAudience()

* 🔄 *非同期リクエストを実行します*

データウェアハウスで訪問者に関連付けられているすべてのオーディエンスデータを取得します。オプションの `warehouseKey` パラメータは通常、内部のユーザー ID です。`customDataIndex` パラメータは、Kameleoon が訪問者をターゲットにするために使用する Kameleoon カスタムデータに対応しています。詳細については、[ウェアハウスターゲティングドキュメント](/user-manual/integrations/data-warehouses/bigquery/use-bigquery-as-a-source-audience-targeting) を参照してください。

<Warning>
  サーバーコールが必要なため、このメカニズムは非同期です。したがって、次のいずれかを行ってください。

  * メソッドの引数として `completion` コールバックを提供し、データが正常に取得されて訪問者に追加されたときに通知を受け取れるようにします。
  * 非同期処理のためにコルーチンを使用します。

  失敗した結果のみを確認することが推奨されます。ただし、必要に応じて、データが訪問者に追加され、ターゲティング目的(またはデバッグ用、ただしデバッグには [ロギング](#ロギング) を使用する方が良いです)で利用できることを確認できます。
</Warning>

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    // Visitor data will be fetched and automatically added for the visitor
    kameleoonClient.getVisitorWarehouseAudience(customDataIndex, result -> {
        if (result.isSuccess()) {
            // Due to method called before this callback, data was automatically added to the visitor.
        } else {
            Exception exception = result.failure();
            // The request failed due to an exception.
        }
    });

    // If you need to specify warehouse key
    kameleoonClient.getVisitorWarehouseAudience("warehouseKey", customDataIndex, result -> {
        // Due to method called before this callback, data was automatically added to the visitor,
        // but you can evaluate the added data if necessary.
        try {
            CustomData data = result.getOrThrow();
        } catch (Exception exception) {
            // The request failed due to an exception.
        }
    });
    ```

    ##### 引数

    | 名前                     | 型                                         | 説明                                                      | デフォルト  |
    | ---------------------- | ----------------------------------------- | ------------------------------------------------------- | ------ |
    | warehouseKey (*オプション*) | `String`                                  | ウェアハウスデータを識別するための一意のキー(通常は内部のユーザー ID)。                  | `null` |
    | customDataIndex (*必須*) | `int`                                     | BigQuery Audiences をターゲットにするために使用したいカスタムデータインデックスを表す整数。 |        |
    | completion (*必須*)      | `ResultCompletion<CustomData, Exception>` | 受信したデータを処理するコールバック。                                     |        |
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    // Visitor data will be fetched and automatically added for the visitor
    kameleoonClient.getVisitorWarehouseAudience(customDataIndex) { result ->
        if (result.isSuccess) {
            // Due to method called before this callback, data was automatically added to the visitor.
        } else {
            val exception = result.failure()
            // The request failed due to an exception.
        }
    }

    // If you need to specify warehouse key
    kameleoonClient.getVisitorWarehouseAudience("warehouseKey", customDataIndex) { result ->
        // As a result of the method before this callback is called, data was automatically added to the visitor
        // but you can evaluate the added data if you need to check it.
        try {
            val data = result.getOrThrow()
        } catch (e: Exception) {
            // The request failed due to an exception.
        }
    }
    ```

    ##### 引数

    | 名前                     | 型                                         | 説明                                                      | デフォルト  |
    | ---------------------- | ----------------------------------------- | ------------------------------------------------------- | ------ |
    | warehouseKey (*オプション*) | `String`                                  | ウェアハウスデータを識別するための一意のキー(通常は内部のユーザー ID)。                  | `null` |
    | customDataIndex (*必須*) | `Int`                                     | BigQuery Audiences をターゲットにするために使用したいカスタムデータインデックスを表す整数。 |        |
    | completion (*必須*)      | `ResultCompletion<CustomData, Exception>` | 受信したデータを処理するコールバック。                                     |        |
  </Tab>

  <Tab title="Kotlin (Coroutines)">
    <Warning>
      よくある間違いは、`mapCatching`、`runCatching`、または `try-catch` ブロック内で suspend 関数を使用しながら、`CancellationException` を適切に再スローしないことです。これにより、コルーチンのキャンセルが妨げられる可能性があります。正しい動作を保証するため、これらのブロック内で suspend 関数を呼び出すことは避けるようにしてください。
    </Warning>

    ```kotlin theme={null}
    // Visitor data will be fetched and automatically added for the visitor
    viewModelScope.launch {
        // As a result of the method call, the data was automatically added to the visitor.
        kameleoonClient.getVisitorWarehouseAudience(customDataIndex = customDataIndex) ?: return@launch
    }

    // If you need to specify warehouse key
    viewModelScope.launch {
        // As a result of the method call, the data was automatically added to the visitor.
        kameleoonClient.getVisitorWarehouseAudience("warehouseKey", customDataIndex)
            .onSuccess { customData ->
                // But you can evaluate the added data if you need to check it.
            }
            .onFailure { ex ->
                // The request failed due to an exception.
            }
    }
    ```

    ##### 引数

    | 名前                     | 型        | 説明                                                      | デフォルト  |
    | ---------------------- | -------- | ------------------------------------------------------- | ------ |
    | warehouseKey (*オプション*) | `String` | ウェアハウスデータを識別する一意のキー(通常は内部のユーザー ID)。                     | `null` |
    | customDataIndex (*必須*) | `Int`    | BigQuery Audiences をターゲットにするために使用したいカスタムデータインデックスを表す整数。 |        |

    ##### 戻り値

    | 型                    | 説明                                                        |
    | -------------------- | --------------------------------------------------------- |
    | `Result<CustomData>` | 取得した値 (`CustomData`) または発生した例外のいずれかを含む Kotlin の `Result`。 |
  </Tab>
</Tabs>

#### setLegalConsent()

訪問者が個人データの使用について法的同意を提供したかどうかを指定するために、このメソッドを使用する必要があります。`legalConsent` パラメータを `false` に設定すると、トラッキングリクエストに含めることができるデータタイプが制限されます。このメソッドは、訪問者データを責任を持って管理しながら、法的および規制要件に準拠するのに役立ちます。個人データの詳細については、[同意管理ポリシー](/user-manual/project-management/consent-management-policy) を参照してください。

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    kameleoonClient.setLegalConsent(true);
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    kameleoonClient.setLegalConsent(true)
    ```
  </Tab>
</Tabs>

##### 引数

| 名前           | 型       | 説明                                                                                                  |
| ------------ | ------- | --------------------------------------------------------------------------------------------------- |
| legalConsent | boolean | 法的同意のステータスを表すブール値。`true` は訪問者が法的同意を提供したことを示し、`false` は訪問者が法的同意を提供していない、または撤回したことを示します。このフィールドは必須です。 |

### データタイプ

このセクションでは、Kameleoon でサポートされている `com.Kameleoon.Data` 型を一覧表示します。複数の標準データタイプと、カスタムデータタイプを定義するための `CustomData` タイプが提供されています。

#### Conversion

ここに保存される `Conversion` データセットは、それに関連付けられた任意の目標で実験およびパーソナライゼーションレポートをフィルタリングするために使用できます。

<Tip>
  * 各訪問者は複数の `Conversion` オブジェクトを持つことができます。
  * `goalId` は Kameleoon アプリで見つけることができます。
</Tip>

| 名前                 | 型               | 説明             | デフォルト               |
| ------------------ | --------------- | -------------- | ------------------- |
| goalId (*必須*)      | `int`           | 目標の ID。        |                     |
| revenue (*オプション*)  | `float`         | コンバージョンの収益     | `0`                 |
| negative (*オプション*) | `boolean`       | 収益が正か負かを定義します。 | `false`             |
| metadata (*オプション*) | `CustomData...` | コンバージョンのメタデータ。 | `new CustomData[0]` |

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    kameleoonClient.addData(new Conversion(32, 10f));

    kameleoonClient.addData(new Conversion(33, 0f, true));

    kameleoonClient.addData(
        new Conversion(34, 5f, new CustomData(3, "metadata1", "md2"), new CustomData(5, "md3"))
    );
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    kameleoonClient.addData(Conversion(32, 10f))

    kameleoonClient.addData(Conversion(33, 0f, true))

    kameleoonClient.addData(
        Conversion(34, 5f, CustomData(3, "metadata1", "md2"), CustomData(5, "md3"))
    )
    ```
  </Tab>
</Tabs>

#### Device

<Note>
  Android SDK `4.13.0` 以降、`Device` は [`android.content.Context`](https://developer.android.com/reference/android/content/Context) に基づいて自動的に検出されます。ただし、必要に応じて手動でオーバーライドすることもできます。
</Note>

ユーザーのデバイスに関する情報を保存します。

| 名前            | 型         | 説明                                          |
| ------------- | --------- | ------------------------------------------- |
| device (*必須*) | `Devices` | デバイスのリスト: **phone**、**tablet**、**desktop**。 |

<Tabs defaultTabIndex={0}>
  <Tab title="Java">
    ```java theme={null}
    kameleoonClient.addData(Device.tablet());
    ```
  </Tab>
</Tabs>

#### Geolocation

`Geolocation` には訪問者のジオロケーション詳細が含まれます。

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    kameleoonClient.addData(new Geolocation("France", "Île-de-France", "Paris"));
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    kameleoonClient.addData(Geolocation("France", "Île-de-France", "Paris"))
    ```
  </Tab>
</Tabs>

| 名前                   | 型                     | 説明                           |
| -------------------- | --------------------- | ---------------------------- |
| country (*必須*)       | `String`              | 訪問者の国。                       |
| region (*オプション*)     | <nobr>`String`</nobr> | 訪問者の地域。                      |
| city (*オプション*)       | <nobr>`String`</nobr> | 訪問者の都市。                      |
| postalCode (*オプション*) | <nobr>`String`</nobr> | 訪問者の郵便番号。                    |
| latitude (*オプション*)   | `float`               | 訪問者の位置を表す緯度座標。座標番号は十進度を表します。 |
| longitude (*オプション*)  | `float`               | 訪問者の位置を表す経度座標。座標番号は十進度を表します。 |

<Tip>
  * 各訪問者は `Geolocation` を 1 つしか持てません。2 つ目の `Geolocation` を追加すると、最初のものが上書きされます。
</Tip>

#### CustomData

Kameleoon アプリまたは Data API で独自のカスタムデータタイプを定義し、SDK から使用します。

| 名前                  | 型                                | 説明                                                                                                                                        | デフォルト  |
| ------------------- | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ------ |
| index/name (*必須*)   | `int`/`String`                   | カスタムデータのインデックスまたは名前。データを識別するには、**`index` または `name` のいずれかを指定する必要があります**。                                                                  |        |
| values (*必須*)       | `String...`/`Collection<String>` | 保存するカスタムデータの値。                                                                                                                            |        |
| overwrite (*オプション*) | `boolean`                        | 値がどのように保存され、レポートにどのように表示されるかを明示的に制御するフラグ。[詳細はこちら](/developer-docs/custom-data#default-logic-when-overwrite-parameter-is-false-or-omitted) | `true` |

<Note>
  * カスタムデータのインデックスは、Kameleoon アプリの **カスタムデータ構成** ページで利用可能です。注意: このインデックスは 0 から始まるため、特定のサイトで作成する最初のカスタムデータのインデックスは 1 ではなく 0 になります。
  * SDK インスタンス構成が最新でない、または名前が登録されていない場合に、名前で作成された `CustomData` インスタンスを追加すると、データは無視されます。
</Note>

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    kameleoonClient.addData(new CustomData(1, "value"));

    // With several values
    kameleoonClient.addData(new CustomData(1, "value1", "value2"));

    // To set the 'overwrite' flag to false
    kameleoonClient.addData(new CustomData(1, false, "value"));

    // To use a name instead of the index
    kameleoonClient.addData(new CustomData("my-custom-data", "value"));
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    kameleoonClient.addData(CustomData(1, "value"))

    // With several values
    kameleoonClient.addData(CustomData(1, "value1", "value2"))

    // To set the 'overwrite' flag to false
    kameleoonClient.addData(CustomData(1, false, "value"))

    // To use a name instead of the index
    kameleoonClient.addData(CustomData("my-custom-data", "value"))
    ```
  </Tab>
</Tabs>

### 戻り値型

#### DataFile

`DataFile` には SDK 構成の詳細が含まれています。

クライアントが必要とする場合は、追加情報で拡張できます。詳細が必要な場合は、カスタマーサクセスマネージャーにお問い合わせください。

| 名前           | 型                          | 説明                                                          |
| ------------ | -------------------------- | ----------------------------------------------------------- |
| featureFlags | `Map<String, FeatureFlag>` | フィーチャーフラグキーをキーとする [`FeatureFlag`](#featureflag) オブジェクトのマップ。 |
| dateModified | `long`                     | `DataFile` が最後に変更された時刻を示すタイムスタンプ(ミリ秒)。                      |

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    // Retrieves the map of feature flags from the DataFile.
    // The map is keyed by feature flag identifiers, with each value being a FeatureFlag object.
    Map<String, FeatureFlag> featureFlags = dataFile.getFeatureFlags();

    // Retrieves the last modification timestamp of the DataFile.
    // The value is a long representing milliseconds since the Unix epoch.
    long dateModified = dataFile.getDateModified();
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    // Retrieves the map of feature flags from the DataFile.
    // The map is keyed by feature flag identifiers, with each value being a FeatureFlag object.
    val featureFlags = dataFile.featureFlags

    // Retrieves the last modification timestamp of the DataFile.
    // The value is a long representing milliseconds since the Unix epoch.
    val dateModified = dataFile.dateModified
    ```
  </Tab>
</Tabs>

#### FeatureFlag

`FeatureFlag` は、フィーチャーフラグ自体を定義するプロパティのセットを表します。例えば、その [`Variations`](#variation)、[`Rules`](#rule)、環境ステータス、その他の関連詳細などです。

クライアントが必要とする場合は、追加情報で拡張できます。詳細が必要な場合は、カスタマーサクセスマネージャーにお問い合わせください。

| 名前                  | 型                        | 説明                                      |
| ------------------- | ------------------------ | --------------------------------------- |
| environmentEnabled  | `boolean`                | フィーチャーフラグが現在の環境で有効になっているかどうかを示します。      |
| defaultVariationKey | `String`                 | フィーチャーフラグに関連付けられたデフォルトのバリエーションのキー。      |
| variations          | `Map<String, Variation>` | バリエーションキーをキーとする `Variation` オブジェクトのマップ。 |
| rules               | `List<Rule>`             | `Rule` オブジェクトのリスト                       |

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    // Check whether the feature flag is enabled in the current environment
    boolean isEnvironmentEnabled = featureFlag.isEnvironmentEnabled();

    // Retrieve the key of the default variation
    String defaultVariationKey = featureFlag.getDefaultVariationKey();

    // Retrieve the default variation object
    Variation defaultVariation = featureFlag.getDefaultVariation();

    // Retrieve all variations of the feature flag as a map (key = variation key, value = Variation object)
    Map<String, Variation> variations = featureFlag.getVariations();

    // Retrieve all targeting rules associated with the feature flag
    List<Rule> rules = featureFlag.getRules();
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    // Check whether the feature flag is enabled in the current environment
    val isEnvironmentEnabled = featureFlag.isEnvironmentEnabled

    // Retrieve the key of the default variation
    val defaultVariationKey = featureFlag.defaultVariationKey

    // Retrieve the default variation object
    val defaultVariation = featureFlag.defaultVariation

    // Retrieve all variations of the feature flag as a map (key = variation key, value = Variation object)
    val variations = featureFlag.variations

    // Retrieve all targeting rules associated with the feature flag
    val rules = featureFlag.rules
    ```
  </Tab>
</Tabs>

#### Rule

`Rule` は、ルール自体を定義するプロパティのセットを表します。例えば、その [`Variations`](#variation) です。

クライアントが必要とする場合は、追加情報で拡張できます。詳細が必要な場合は、カスタマーサクセスマネージャーにお問い合わせください。

| 名前         | 型                        | 説明                                      |
| ---------- | ------------------------ | --------------------------------------- |
| variations | `Map<String, Variation>` | バリエーションキーをキーとする `Variation` オブジェクトのマップ。 |

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    // Retrieve all variations of the rule as a map (key = variation key, value = Variation object)
    Map<String, Variation> variations = rule.getVariations();
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    // Retrieve all variations of the rule as a map (key = variation key, value = Variation object)
    val variations = rule.variations
    ```
  </Tab>
</Tabs>

#### Variation

`Variation` には、訪問者に割り当てられたバリエーション(または特定の割り当てが存在しない場合はデフォルトのバリエーション)に関する情報が含まれています。

| 名前           | 型                       | 説明                                                                     |
| ------------ | ----------------------- | ---------------------------------------------------------------------- |
| name         | `String`                | バリエーションの名前。                                                            |
| key          | `String`                | バリエーションを識別する一意のキー。                                                     |
| id           | `Integer`               | 割り当てられたバリエーションの ID(デフォルトのバリエーションの場合は `null`)。                          |
| experimentId | `Integer`               | バリエーションに関連付けられた実験の ID(デフォルトの場合は `null`)。                               |
| variables    | `Map<String, Variable>` | 変数名をキーとして、割り当てられたバリエーションの変数を含むマップ。変数が関連付けられていない場合は空のコレクションになる可能性があります。 |

<Note>
  * `Variation` オブジェクトは、割り当てられたバリエーションとその関連実験に関する詳細を提供し、[`Variable`](#variable) オブジェクトはバリエーション内の各変数に関する特定の詳細を含みます。
  * `id` または `experimentId` が `null` である場合(これはデフォルトのバリエーションを示します)をコードで処理することを確認してください。
  * バリエーションに変数が関連付けられていない場合、`variables` マップは空である可能性があります。
</Note>

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    // Retrieving the variation name
    String variationName = variation.getName();

    // Retrieving the variation key
    String variationKey = variation.getKey();

    // Retrieving the variation id
    Integer variationId = variation.getId();

    // Retrieving the experiment id
    Integer experimentId = variation.getExperimentId();

    // Retrieving the variables map
    Map<String, Variable> variables = variation.getVariables();
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    // Retrieving the variation name
    val variationName = variation.name

    // Retrieving the variation key
    val variationKey = variation.key

    // Retrieving the variation id
    val variationId = variation.id

    // Retrieving the experiment id
    val experimentId = variation.experimentId

    // Retrieving the variables map
    val variables = variation.variables
    ```
  </Tab>
</Tabs>

#### Variable

`Variable` には、割り当てられたバリエーションに関連付けられた変数に関する情報が含まれています。

| 名前    | 型        | 説明                                                                                                            |
| ----- | -------- | ------------------------------------------------------------------------------------------------------------- |
| key   | `String` | 変数を識別する一意のキー。                                                                                                 |
| type  | `String` | 変数の型。可能な値: **BOOLEAN**、**NUMBER**、**STRING**、**JSON**。                                                        |
| value | `Object` | 変数の値。次の型のいずれかになります: **boolean**、**int**、**long**、**double**、**String**、**JSONObject**、**JSONArray**、**null**。 |

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    // Retrieving the variables map
    Map<String, Variable> variables = variation.getVariables();

    // Variable type can be retrieved for further processing
    String type = variables.get("isDiscount").getType();

    // Get the Boolean value of "isDiscount"
    Boolean isDiscount = (Boolean) variables.get("isDiscount").getValue();

    // Get the numeric value of "number" as an Integer
    Integer number = (Integer) variables.get("number").getValue();

    // Get the String value of "title"
    String title = (String) variables.get("title").getValue();
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    // Retrieving the variables map
    val variables = variation.variables

    // Variable type can be retrieved for further processing
    val type = variables["isDiscount"]?.type

    // Get the Boolean value of "isDiscount"
    val isDiscount = variables["isDiscount"]?.value as? Boolean

    // Get the numeric value of "number" as an Integer
    val number = variables.get("number").value as? Int

    // Get the String value of "title"
    val title = variables["title"]?.value as? String
    ```
  </Tab>
</Tabs>

### 非推奨のメソッド

<Warning>
  これらのメソッドは非推奨で、SDK バージョン `5.0.0` で削除されます。
</Warning>

#### getFeatureVariationKey()

* 📨 *Kameleoon にトラッキングデータを送信します*

<Note>
  代わりに [`getVariation()`](#getvariation) を使用してください。
</Note>

訪問者のフィーチャーバリエーションキーを取得するには、このメソッドを使用します。このメソッドは、指定されたユーザーのバリエーションキーを取得するために、必須引数として `featureKey` を受け取ります。

訪問者がこのフィーチャーフラグに以前関連付けられたことがない場合、SDK は(フィーチャーフラグルールに従って)ランダムに割り当てられたバリエーションキーを返します。訪問者がすでにこのフィーチャーフラグに登録されている場合、このメソッドは以前のバリエーションキーを返します。ユーザーがどのルールにも一致しない場合は、お客様のアカウントで定義されているデフォルト値が返されます。

潜在的な例外をキャッチするために、サンプルコードに示されているようにエラー処理を適切に設定してください。

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    String featureKey = "new_checkout";
    String variationKey = "";

    try {
        variationKey = kameleoonClient.getFeatureVariationKey(featureKey);
    } catch (KameleoonException.SDKNotReady e) {
        // Exception indicates that the SDK has not completed its initialization yet.
    } catch (KameleoonException.FeatureNotFound e) {
        // The error has occurred; feature flag isn't found in current configuration.
    } catch (KameleoonException.FeatureEnvironmentDisabled e) {
        // The feature flag is disabled for the environment
    } catch (Exception e) {
        // Recommended (but optional) safeguard for unexpected exceptions from third-party libraries
    }

    switch (variationKey) {
        case "on":
            //main variation key is selected for visitorCode
            break;
        case "alternative_variation":
            //alternative variation key
            break;
        default:
            //default variation key
            break;
    }
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    val featureKey = "new_checkout"
    var variationKey = ""

    try {
        variationKey = kameleoonClient.getFeatureVariationKey(featureKey)
    } catch (e: KameleoonException.SDKNotReady) {
        // Exception indicates that the SDK has not completed its initialization yet.
    } catch (e: KameleoonException.FeatureNotFound) {
        // Exception indicates that the SDK not initialized or the feature toggle is not yet activated on Kameleoon's side. We consider the feature inactive.
    } catch (e: KameleoonException.FeatureEnvironmentDisabled) {
        // The feature flag is disabled for the environment
    } catch (e: Exception) {
        // Recommended (but optional) safeguard for unexpected exceptions from third-party libraries
    }

    when (variationKey) {
        "on" -> {}
        "alternative_variation" -> {}
        else -> {}
    }
    ```
  </Tab>
</Tabs>

#### getFeatureVariationKey()

* 📨 *Kameleoon にトラッキングデータを送信します*

<Note>
  代わりに [`getVariation()`](#getvariation) を使用してください。
</Note>

訪問者のフィーチャーバリエーションキーを取得するには、このメソッドを使用します。このメソッドは、指定されたユーザーのバリエーションキーを取得するために、必須引数として `featureKey` を受け取ります。

訪問者がこのフィーチャーフラグに以前関連付けられたことがない場合、SDK は(フィーチャーフラグルールに従って)ランダムに割り当てられたバリエーションキーを返します。訪問者がすでにこのフィーチャーフラグに登録されている場合、このメソッドは以前のバリエーションキーを返します。ユーザーがどのルールにも一致しない場合は、お客様のアカウントで定義されているデフォルト値が返されます。

潜在的な例外をキャッチするために、サンプルコードに示されているようにエラー処理を適切に設定してください。

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    String featureKey = "new_checkout";
    String variationKey = "";

    try {
        variationKey = kameleoonClient.getFeatureVariationKey(featureKey);
    } catch (KameleoonException.SDKNotReady e) {
        // Exception indicates that the SDK has not completed its initialization yet.
    } catch (KameleoonException.FeatureNotFound e) {
        // The error has occurred; feature flag isn't found in current configuration.
    } catch (KameleoonException.FeatureEnvironmentDisabled e) {
        // The feature flag is disabled for the environment
    } catch (Exception e) {
        // Recommended (but optional) safeguard for unexpected exceptions from third-party libraries
    }

    switch (variationKey) {
        case "on":
            //main variation key is selected for visitorCode
            break;
        case "alternative_variation":
            //alternative variation key
            break;
        default:
            //default variation key
            break;
    }
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    val featureKey = "new_checkout"
    var variationKey = ""

    try {
        variationKey = kameleoonClient.getFeatureVariationKey(featureKey)
    } catch (e: KameleoonException.SDKNotReady) {
        // Exception indicates that the SDK has not completed its initialization yet.
    } catch (e: KameleoonException.FeatureNotFound) {
        // Exception indicates that the SDK not initialized or the feature toggle is not yet activated on Kameleoon's side. We consider the feature inactive.
    } catch (e: KameleoonException.FeatureEnvironmentDisabled) {
        // The feature flag is disabled for the environment
    } catch (e: Exception) {
        // Recommended (but optional) safeguard for unexpected exceptions from third-party libraries
    }

    when (variationKey) {
        "on" -> {}
        "alternative_variation" -> {}
        else -> {}
    }
    ```
  </Tab>
</Tabs>

#### getActiveFeatures()

<Note>
  * 代わりに [`getVariations()`](#getvariations) を使用してください。
  * 以前は `getFeatureListForVisitorCode` と呼ばれていました。これは SDK バージョン `4.0.0` リリースで削除されました。
</Note>

`getActiveFeatures` メソッドは、訪問者に利用可能なアクティブなフィーチャーフラグに関する情報を取得します。

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    Map<String, Variation> listActiveFeatureFlags = kameleoonClient.getActiveFeatures();
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    val listActiveFeatureFlags = kameleoonClient.getActiveFeatures()
    ```
  </Tab>
</Tabs>

##### 戻り値

| 型                        | 説明                                                         |
| ------------------------ | ---------------------------------------------------------- |
| `Map<String, Variation>` | 対応するアクティブなフィーチャーのキーを使用して、アクティブなフィーチャーの割り当てられたバリエーションを含む辞書。 |

#### getFeatureVariable()

* 📨 *Kameleoon にトラッキングデータを送信します*

<Note>
  代わりに [`getVariation()`](#getvariation) を使用してください。
</Note>

このメソッドは、特定のユーザーのバリエーションキーの変数値を取得します。`featureKey` および `variableKey` を必須引数として受け取ります。

訪問者が `featureKey` に以前関連付けられたことがない場合、SDK は(フィーチャーフラグルールに従って)指定されたバリエーションキーに対してランダムに割り当てられた変数値を返します。訪問者がすでにこのフィーチャーフラグに登録されている場合、このメソッドは以前に登録されたバリエーションの変数値を返します。ユーザーがどのルールにも一致しない場合は、デフォルトの変数値が返されます。

潜在的な例外をキャッチするために、サンプルコードに示されているようにエラー処理を適切に設定してください。

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    String featureKey = "feature_key";
    String variableKey = "variableKey";

    try {
        Object variableValue = kameleoonClient.getFeatureVariable(featureKey, variableKey);
        // your custom code, depending on variableValue
    } catch (KameleoonException.SDKNotReady e) {
        // Exception indicates that the SDK has not completed its initialization yet.
    } catch (KameleoonException.FeatureNotFound e) {
        // The error has occurred; feature flag isn't found in current configuration.
    } catch (KameleoonException.FeatureVariableNotFound e) {
        // Requested variable not defined in Kameleoon
    } catch (KameleoonException.FeatureEnvironmentDisabled e) {
        // The feature flag is disabled for the environment.
    } catch (Exception e) {
        // Recommended (but optional) safeguard for unexpected exceptions from third-party libraries
    }
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    val featureKey = "new_checkout"
    val variableKey = "var"

    try {
        val variableValue = kameleoonClient.getFeatureVariable(featureKey, variableKey)
        // your custom code depending of variableValue
    } catch (e: KameleoonException.SDKNotReady) {
        // Exception indicating that the SDK has not completed its initialization yet.
    } catch (e: KameleoonException.FeatureNotFound) {
        // The error is happened, feature flag isn't found in current configuraiton
    } catch (e: KameleoonException.FeatureVariableNotFound) {
        // Requested variable not defined on Kameleoon's side
    } catch (e: KameleoonException.FeatureEnvironmentDisabled) {
        // The feature flag is disabled for the environment
    } catch (e: Exception) {
        // Recommended (but optional) safeguard for unexpected exceptions from third-party libraries
    }
    ```
  </Tab>
</Tabs>

##### 引数

| 名前           | 型      | 説明                                |
| ------------ | ------ | --------------------------------- |
| featureKey   | String | ユーザーに表示したいフィーチャーのキー。このフィールドは必須です。 |
| variableName | String | 値を取得したい変数の名前。このフィールドは必須です。        |

##### 戻り値

| 型      | 説明                                                                                                                    |
| ------ | --------------------------------------------------------------------------------------------------------------------- |
| object | このフィーチャーフラグに対して指定された `visitorCode` に登録されたバリエーション変数の値。有効な型: `boolean`、`int`、`double`、`String`、`JSONObject`、`JSONArray` |

##### スローされる例外

| 型                          | 説明                                                                                                                                        |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| SDKNotReady                | SDK が初期化を完了していないことを示す例外。                                                                                                                  |
| FeatureNotFound            | リクエストされたフィーチャーキーが SDK の内部構成で見つからなかったことを示す例外。この例外は通常、フィーチャーフラグが Kameleoon 側でアクティブ化されていない(ただし、フィーチャーを実装するコードはアプリケーションで既にデプロイされている)ことを意味します。 |
| FeatureVariableNotFound    | 指定された変数が見つからなかったことを示す例外。Kameleoon アプリの変数キーがコード内のキーと一致することを確認してください。                                                                       |
| FeatureEnvironmentDisabled | 訪問者の現在の環境(例: production、staging、development)でフィーチャーフラグが無効になっていることを示す例外。                                                                   |

#### getFeatureVariationVariables()

<Note>
  * 代わりに [`getVariation()`](#getvariation) を使用してください。
  * このメソッドは以前 `getFeatureAllVariables` と呼ばれており、SDK バージョン `4.0.0` リリースで削除されました。
</Note>

フィーチャーのすべての変数を取得するには、このメソッドを呼び出します。Kameleoon アプリでフィーチャー変数を変更できます。

このメソッドは 1 つの入力パラメータ: `featureKey` を受け取ります。Kameleoon アプリで定義されているとおり、`Map<String, Object>` 型としてデータを返します。リクエストされたフィーチャーが SDK の内部構成で見つからなかった場合、例外 (`FeatureNotFound`) をスローします。

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    String featureKey = "myFeature";
    String variationKey = "variation1";

    try {
        Map<String, Object> variables = kameleoonClient.getFeatureVariationVariables(featureKey, variationKey);
    } catch (KameleoonException.SDKNotReady e) {
        // Exception indicating that the SDK has not completed its initialization yet.
    } catch (KameleoonException.FeatureNotFound e) {
        // The feature is not yet activated on Kameleoon's side
    } catch (KameleoonException.FeatureEnvironmentDisabled e) {
        // The feature flag is disabled for the environment
    } catch (Exception e) {
        // This is a generic Exception handler which will handle all exceptions.
        System.out.println("Exception occurred");
    }
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    val featureKey = "myFeature"
    val variationKey = "variation1"

    try {
        val variables = kameleoonClient.getFeatureVariationVariables(featureKey, variationKey)
    } catch (e: KameleoonException.SDKNotReady) {
        // Exception indicating that the SDK has not completed its initialization yet.
    } catch (e: KameleoonException.FeatureNotFound) {
        // The feature is not yet activated on Kameleoon's side
    } catch (e: KameleoonException.FeatureEnvironmentDisabled) {
        // The feature flag is disabled for the environment
    } catch (e: Exception) {
        // This is a generic Exception handler which will handle all exceptions.
        println("Exception occurred")
    }
    ```
  </Tab>
</Tabs>

##### 引数

| 名前         | 型      | 説明                                   |
| ---------- | ------ | ------------------------------------ |
| featureKey | String | 取得する必要があるフィーチャーの一意の識別子。このフィールドは必須です。 |

##### 戻り値

| 型                    | 説明                                                                                                                    |
| -------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `Map<String,Object>` | このフィーチャーフラグに関連付けられた変数を表すデータ。値は `int`、`String`、`boolean`、`JSONObject`、または `JSONArray` のいずれかです(Web インターフェースで定義された型に依存)。 |

##### スローされる例外

| 型                          | 説明                                                                                               |
| -------------------------- | ------------------------------------------------------------------------------------------------ |
| SDKNotReady                | SDK が初期化を完了していないことを示す例外。                                                                         |
| FeatureNotFound            | リクエストされたフィーチャーが SDK の内部構成で見つからなかったことを示す例外。この例外は通常、フィーチャーフラグが Kameleoon 側でまだアクティブ化されていないことを意味します。 |
| FeatureVariableNotFound    | 指定された変数が見つからなかったことを示す例外。Kameleoon アプリの変数キーがコード内のキーと一致することを確認してください。                              |
| FeatureEnvironmentDisabled | 訪問者の現在の環境(例: production、staging、development)でフィーチャーフラグが無効になっていることを示す例外。                          |

#### getFeatureList()

<Tip>
  すべてのフィーチャーフラグを反復処理して各々に対して [`getVariation()`](#getvariation) を呼び出したい場合は、代わりに [`getVariations()`](#getvariations) メソッドを使用してください。
</Tip>

SDK で現在利用可能なフィーチャーフラグキーのリストを返します。

<Tabs defaultTabIndex={1}>
  <Tab title="Java">
    ```java theme={null}
    List<String> allFeatureFlagListId = kameleoonClient.getFeatureList();
    ```
  </Tab>

  <Tab title="Kotlin">
    ```kotlin theme={null}
    val allFeatureFlagListId = kameleoonClient.getFeatureList()
    ```
  </Tab>
</Tabs>

##### 戻り値

| 型              | 説明              |
| -------------- | --------------- |
| `List<String>` | フィーチャーフラグキーのリスト |
