# モバイルIn-AppメッセージングのAndroid SDK連携

プレビュー版Engage Mobile SDKを使用すると、AndroidアプリをEngage StudioのモバイルIn-Appメッセージングに接続できます。アプリが`trackImmediately`でトリガーイベントを送ると、SDKがRealtime Personalizationからオファーを取得し、SDKが管理するWebViewに対応するメッセージを表示します。

プレビュー
ネイティブSDK連携はプレビューです。一般提供前に、API、アーティファクトの配布方法、メッセージペイロード、表示動作が変更される場合があります。SDKアーティファクトに付属するリリース別の配布手順を使用してください。

## SDKが担当する処理

Android SDKはThin Clientとして動作します。Realtime Personalizationが返すかどうかを決定し、SDKは返された判定を実行します。

| 責務 | 担当 |
|  --- | --- |
| オーディエンスの適格性と配信判定 | Realtime Personalization |
| トリガーイベントとアプリのライフサイクルタイミング | お客様のアプリ |
| レスポンスからのメッセージ選択 | SDK |
| ModalとBannerのWebView表示 | SDK |
| Hosted Pages URLの表示 | SDK |
| アプリ固有のDeep Link処理 | お客様のアプリ |
| アプリ固有のカスタムアクション | お客様のアプリ |
| キャンペーンのImpression、Click、Dismiss計測 | SDK |


## 事前準備

次の値を用意してください。

- Treasure AIアカウント用の書き込み専用APIキー。
- アカウントリージョンのRecordsエンドポイント。
- Personalizationエンドポイント。
- Personalizationトークン。
- トリガーイベント用のデータベースとテーブル。
- メッセージを表示する画面や操作を識別するイベントスキーマ。


プレビューアーティファクトのバージョンと最小Androidバージョンは、受け取るSDKビルドによって異なります。使用するプレビューアーティファクトに付属するリリース情報を確認してください。

## SDKモジュールの導入

プレビュー版Android SDKは単一のアーティファクトとして提供されます。

- `com.treasuredata:td-android-sdk` — イベント収集、バッファリング、アップロード、Personalizationリクエスト、メッセージモデル、およびモバイルIn-AppメッセージとHosted Pagesを表示するWebViewレンダリングレイヤー。


モバイルIn-Appのレンダリングは`td-android-sdk`に内包されています。別のレンダリング用アーティファクトやレンダリングのインストール手順は不要です。

プレビューアーティファクトは、SDKチームの社内配布ワークフローを通じて開発用に配布されます。お客様のアプリへ追加する前に、リポジトリとバージョンを確認してください。

## クイックスタート

`Application`クラスでCore SDKを初期化します。モバイルIn-Appのレンダリングは`td-android-sdk`に内包されているため、別途レンダリングのインストール手順は不要です。

```java
import com.treasuredata.android.TreasureData;

public final class App extends Application {
    @Override
    public void onCreate() {
        super.onCreate();

        TreasureData.initializeSharedInstance(
            this,
            "<WRITE_ONLY_API_KEY>",
            "https://<region>.records.in.treasuredata.com"
        );

        TreasureData td = TreasureData.sharedInstance();
        td.setDefaultDatabase("<DATABASE>");
        td.setDefaultTable("<EVENT_TABLE>");
        td.setPersonalizationEndpoint(
            "https://p13n-api.treasuredata.com"
        );
        td.setPersonalizationToken("<PERSONALIZATION_TOKEN>");
        td.enableAutoAppendUniqId();
    }
}
```

メッセージをトリガーできる画面またはイベントで、`trackImmediately`を呼び出します。

```java
Map<String, Object> event = new HashMap<>();
event.put("event", "pageview");
event.put("screen_name", "home");

TreasureData.sharedInstance().trackImmediately(event);
```

`addEvent`と`uploadEvents`は通常のイベント送信に引き続き使用できます。これらのAPIはMobile In-Appメッセージをトリガーしません。

## Core APIの設定

| APIまたはメソッド | 用途 |
|  --- | --- |
| `setPersonalizationEndpoint` | メッセージオファーを取得するエンドポイント。 |
| `setPersonalizationToken` | Personalizationの読み取りに使用する認証情報。書き込み用APIキーとは分けて管理します。 |
| `setDefaultDatabase` / `setDefaultTable` | トリガーリクエストと通常イベントのデフォルト送信先。 |
| `trackImmediately` | トリガーイベントを送信し、メッセージを取得します。 |
| `setProfileContext` / `setProfileValue` | `window.TDContext`として公開するJSON化可能な値を設定します。 |
| `TreasureData.setBridgeListener` | アプリ固有の`invoke`コールバックを受け取ります。 |
| `openUrl` | Push payloadなど、アプリがすでに持っているURLを表示します。 |


## メッセージ配信フロー

1. アプリが`trackImmediately(event)`を呼び出します。
2. Treasure Data Android SDKがPersonalizationへトリガーイベントを送信します。
3. Realtime Personalizationがオファーまたは該当なしを返します。
4. Engage Androidモジュールが表示可能なメッセージを1件選択します。
5. SDKが同時表示ガードを確認します。
6. SDKがModal、Banner、またはHosted Pagesを表示します。
7. アプリとメッセージコンテンツが結果の操作を処理します。


キャンペーンに一致しなければ、SDKは何も表示しません。これはエラーではなく、通常の結果です。

SDKはレスポンスから表示可能なメッセージを1件だけ選択します。別のメッセージが表示中の場合、新しいメッセージは表示されません。

## Hosted Pages

Hosted Pagesは、URLからコンテンツを読み込むキャンペーンメッセージです。Android EngageモジュールはURLをフルスクリーンWebViewで表示し、設定されたプロフィールコンテキストを注入します。

次のような用途に使用できます。

- クーポンページ
- スタンプカード
- 抽選やインタラクティブなプロモーション
- アンケートやフォーム
- パーソナライズされたキャンペーンページ


Hosted PagesにはModalやBannerの表示設定は適用されません。ホストされたページ側で、エクスペリエンスを終了するための導線を提供してください。

### キャンペーン配信のHosted Pages

アプリが`trackImmediately`を呼び出し、Realtime PersonalizationがHosted Pagesオファーを返した場合、SDKはキャンペーン計測に必要なキャンペーンIDを持って表示します。

### URLを直接表示する場合

アプリがすでにURLを持っている場合は、`openUrl`を呼び出します。

```java
Map<String, Object> context = new HashMap<>();
context.put("coupon_id", "abc123");

TreasureData.sharedInstance().openUrl(
    "https://example.com/coupon",
    context
);
```

これはPush通知のタップ後の処理に使用できます。URLはSDKのWebViewに表示されますが、キャンペーンオファーを経由していないため、キャンペーンの`impression`、`click`、`dismiss`は記録されません。

## リンクとカスタムアクション

メッセージコンテンツから`invoke`アクションを受け取るには、`TDEngageBridgeListener`を実装します。アプリ所有URLの遷移にはCore SDKのLink Handlerを使用します。

```java
public final class EngageClient implements TDEngageBridgeListener {
    @Override
    public void handleTDBridgeInvoke(
        @NonNull String name,
        @NonNull Map<String, Object> params
    ) {
        if ("grantPoints".equals(name)) {
            // 認証、認可、パラメーターの上限を確認します。
        }
    }
}

TreasureData td = TreasureData.sharedInstance();
td.setBridgeListener(new EngageClient());
td.setLinkHandler(url -> {
    // アプリ所有のSchemeを検証して処理します。
    return false;
});
```

SDKはアクション名を解釈せず、要求を認可もしません。メッセージコンテンツとすべてのパラメーターを信頼できない入力として扱ってください。コールバックを受け取り続ける必要がある期間、Listenerを保持してください。フックの正確なシグネチャは、使用するプレビューアーティファクトのAPI契約を確認してください。

## メッセージコンテンツへプロフィールコンテキストを渡す

`setProfileContext`でJSON化可能な値を設定すると、SDKはModal、Banner、Hosted Pagesのコンテンツへ`window.TDContext`として注入します。

```java
Map<String, Object> context = new HashMap<>();
context.put("member_tier", "gold");
context.put("points", 1200);

TreasureData.sharedInstance().setProfileContext(context);
```

次のルールに従ってください。

- JSON化できる値だけを使用します。
- SDKはコンテキストを永続化しないため、アプリ起動ごとに設定します。
- サインイン中のユーザーが変わったら、値をクリアまたは置き換えます。
- APIキー、トークン、パスワード、ホストされたHosted Pagesページに見せるべきでない値を含めないでください。
- JavaScriptの数値精度の問題を避けるため、大きな数値のIDは文字列で渡します。


## 画面遷移を処理する

Personalizationリクエストは非同期です。レスポンスが到着する前に、ユーザーがトリガー元の画面を離れる場合があります。ホストアプリの画面状態を確認し、リクエストを開始した画面でなくなった場合は、返されたオファーを表示しないでください。

表示ゲートの正確なAPIはプレビュー契約の一部であり、一般提供前に変更される場合があります。

## Pushトークンを登録する

プレビュー版Android SDKには`registerDeviceToken`が含まれています。FCMトークンの取得、通知権限、通知の受信は引き続きアプリが担当します。

```java
@Override
public void onNewToken(String token) {
    TreasureData.sharedInstance().registerDeviceToken(
        token,
        TDPushProvider.FCM,
        "device_tokens"
    );
}
```

SDKはデバイストークンのレコードを送信し、即時にフラッシュします。プレビュー版では、次のSDKフィールドを使用します。

```json
{
  "td_device_token": "<FCM_TOKEN>",
  "td_push_provider": "fcm"
}
```

このプレビュー用レコードは、既存のMobile Pushドキュメントにある`token_register`イベントのサンプルスキーマとは別です。標準Pushイベント契約が確定するまでは、2つのスキーマを同一のものとして扱わないでください。

アプリは引き続き次の処理を担当します。

- FCMトークンの取得。
- 通知権限のリクエスト。
- 通知の受信と表示。
- 通知タップの処理。
- Push payloadからURLを取り出し、Hosted Pagesを開く場合の`openUrl`呼び出し。


## 計測

プレビューSDKの連携では、キャンペーン配信されたメッセージの計測を自動的に記録します。

- `impression` — エクスペリエンスを表示したとき。
- `click` — 対応するリンクまたはBridgeアクションを使用したとき。
- `dismiss` — エクスペリエンスを閉じたとき。


計測データをインストールに関連付ける場合、`enableAutoAppendUniqId()`が実質的に必要です。計測先とスキーマは一般提供前に変更される場合があります。

トラブルシューティングについては、[モバイルIn-Appのトラブルシューティング](/ja/products/marketing-cloud/engage-studio/channels/mobile-inapp/troubleshooting)を参照してください。

## 最小連携チェックリスト

サンプルアプリのリポジトリを使用せずに、プレビューSDKを連携できます。

- 付属する配布手順に従って、プレビュー版`td-android-sdk`アーティファクトを追加します。
- アプリのライフサイクルでCore SDKを一度初期化します。
- Personalizationエンドポイント、トークン、データベース、イベントテーブルを設定します。
- コンテンツで必要な場合だけProfile ContextとBridge Listenerを設定します。
- 対象画面またはイベントで`trackImmediately`を呼び出します。
- 対応するAndroidデバイスでModal、Banner、Hosted Pagesをテストします。
- Mobile Pushを使用する場合は、FCMトークンを別途登録します。
- リリース前にImpression、Click、Dismiss、Deep Link、Hosted Pagesを確認します。


プレビューアーティファクトの名前、バージョン、最小Androidバージョン、配布URLはリリースごとに異なります。ソースリポジトリURLではなく、アーティファクトに付属するインストール手順を使用してください。