Android UX Helper
Rokt UX Helperは、サーバー間環境で美しいカスタマーエクスペリエンスをレンダリングするのを助けるオープンソースプロジェクトです。Githubページでプロジェクトを見つけたり、貢献したりすることができます。
このドキュメントでは、Rokt UX HelperをAndroidアプリに統合するプロセスを説明します。これはサーバー間統合(S2S)と連携して、チェックアウト時にお客様に関連するエクスペリエンスを提供します。
| システム | バージョン |
|---|---|
| UX Helper | 0.4.0 |
| Androidバージョン/APIレベル | 5.0+ (APIレベル21) |
| パッケージマネージャー | Maven / Gradle |
| Compose BOM | 2024.09.02 |
インストールガイドインストールガイド への直接リンク
モジュール(アプリレベル)の Gradle ファイル(通常は <project>/<app-module>/build.gradle.kts または <project>/<app-module>/build.gradle)に、Rokt UX Helper の依存関係を追加します。
- Kotlin
- Groovy
implementation("com.rokt:roktux:0.1.0")
implementation 'com.rokt:roktux:0.1.0'
RoktLayoutの初期化RoktLayoutの初期化 への直接リンク
ComposeビューにRoktLayoutを追加
// Retrieve the experience response from your server
val experienceResponse = viewModel.experienceResponse.collectAsState()
experienceResponse.value?.let { experienceResponse ->
RoktLayout(
experienceResponse = experienceResponse,
location = "RoktEmbedded1",
onUxEvent = { println("RoktEvent: UxEvent Received $it") },
onPlatformEvent = { println("RoktEvent: onPlatformEvent received $it") },
roktUxConfig = RoktUxConfig.builder()
.imageHandlingStrategy(NetworkStrategy())
.build(),
)
}
UXイベントUXイベント への直接リンク
onUXEventハンドラーを使用して、ユーザーのインタラクションに関するリアルタイムのフィードバックを受け取ります。
最低限、RoktUXEvent.OpenUrlイベントがトリガーされたときに、それを処理して以下の例を使用してリンクを開く必要があります。
OpenUrl - onCloseOpenUrl - onClose への直接リンク
OpenUrlタイプのイベントを処理する際には、onCloseコールバックを呼び出すことが重要です。これにより、RoktUXHelperに次のオファーに移動するなどのロジックを実行させることができます。
- Kotlin
- Java
openUrlEvent.onClose.invoke(openUrlEvent.id)
openUrlEvent.getOnClose().invoke(openUrlEvent.getId());
- Kotlin
- Java
onUxEvent = { event ->
println("RoktEvent: onUxEvent received $event")
if (event is RoktUxEvent.OpenUrl) {
val openUrlEvent = event as RoktUxEvent.OpenUrl
when (openUrlEvent.type) {
OpenLinks.Internally -> {
// Open AndroidX browser or similar functionality to keep the user in app
val customTabsIntent = CustomTabsIntent.Builder().build()
customTabsIntent.launchUrl(context, Uri.parse(openUrlEvent.url))
openUrlEvent.onClose.invoke(openUrlEvent.id) // This must be called when the user is ready for the next offer
}
OpenLinks.Externally, OpenLinks.Passthrough -> {
// Open external browser allowing user to leave the app
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(openUrlEvent.url))
context.startActivity(intent)
openUrlEvent.onClose.invoke(openUrlEvent.id) // This must be called when the user is ready for the next offer
}
}
}
}
roktUxEvent -> {
// Handle open URL event
// Here is a sample how to open different types of URLs
if (roktUxEvent instanceof RoktUxEvent.OpenUrl openUrlEvent) {
if (openUrlEvent.getType() == OpenLinks.Internally) {
// Open AndroidX browser or similar functionality to keep the user in app
CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder().build();
customTabsIntent.launchUrl(context, Uri.parse(openUrlEvent.getUrl()));
openUrlEvent.getOnClose().invoke(openUrlEvent.getId()); // This must be called when the user is ready for the next offer
} else {
// Open external browser allowing user to leave the app
final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(openUrlEvent.getUrl()));
context.startActivity(intent);
openUrlEvent.getOnClose().invoke(openUrlEvent.getId()); // This must be called when the user is ready for the next offer
}
}
return null;
}
すべてのイベント
UXイベントUXイベント への直接リンク
| イベント | 説明 | パラメータ |
|---|---|---|
| OfferEngagement | ユーザーがオファーに関与したときにトリガーされます | layoutId: String |
| PositiveEngagement | ユーザーがオファーに積極的に関与したときにトリガーされます | layoutId: String |
| LayoutInteractive | レイアウトがレンダリングされ、インタラクション可能になったときにトリガーされます | layoutId: String |
| LayoutReady | レイアウトが表示準備が整ったが、まだコンテンツがレンダリングされていないときにトリガーされます | layoutId: String |
| LayoutClosed | ユーザーによってレイアウトが閉じられたときにトリガーされます | layoutId: String |
| LayoutCompleted | オファーの進行が終了し、表示可能なオファーがもうないときにトリガーされます | layoutId: String |
| LayoutFailure | 何らかの失敗によりレイアウトが表示できなかったときにトリガーされます | layoutId: String (optional) |
| OpenUrl | リンクを開く必要があるときにトリガーされます | url: String, id: String, type: OpenLinks (internally/externally/Passthrough), onClose: (id: String) -> Unit, onError: (id: String, throwable: Throwable) |
PlatformEventsPlatformEvents への直接リンク
プラットフォームイベントは統合の重要な部分であり、あなたのバックエンドを通じてRoktに送信する必要があります。統合を容易にするために、オブジェクトはRoktPlatformEventsWrapper型であり、@Serializableを実装し、toJsonString関数を提供します。
- Kotlin
- Java
onPlatformEvent = { events ->
// Send these platform events to Rokt API including the event body
}
roktPlatformEvents -> {
// Send these platform events to Rokt API including the event body
return null;
}
イベントの完全なリストはこちらで確認できます。
オプション: アプリ設定オプション: アプリ設定 への直接リンク
カラーモードカラーモード への直接リンク
カラーモードを使用すると、Roktレイアウトを表示する際に使用するテーマを固定できます。デフォルトでは、Roktは現在のシステムテーマに一致します。
- Kotlin
- Java
val config = RoktUxConfig.builder()
.colorMode(ColorMode.DARK)
.build()
final RoktUxConfig build = new RoktUxConfig.builder()
.colorMode(ColorMode.DARK)
.build();
RoktUxColorMode オブジェクトRoktUxColorMode オブジェクト への直接リンク
| 値 | 説明 |
|---|---|
| LIGHT | アプリケーションはライトモードです |
| DARK | アプリケーションはダークモードです |
| SYSTEM | アプリケーションはシステムカラーモードをデフォルトにします |
ImageLoaderImageLoader への直接リンク
Rokt UX Helperでは、画像を読み込むためにcoilが使用されており、UX Helperにはアプリで利用できるいくつかの組み込みイメージローダーがあります。最も簡単で推奨される実装方法はNetworkStrategyですが、ネットワーキングライブラリや好みに応じてカスタムの画像読み込み戦略を作成することもできます。
- Kotlin
- Java
val roktUxConfig = RoktUxConfig.builder()
.imageHandlingStrategy(NetworkStrategy())
.build()
final roktUxConfig = new RoktUxConfig.builder()
.imageHandlingStrategy(new NetworkStrategy())
.build();
フォントフォント への直接リンク
val fontFamily = remember {
val robotoLight = Font(resId = R.font.roboto_light, weight = FontWeight.W100)
val robotoItalic = Font(resId = R.font.roboto_italic, weight = FontWeight.W400)
FontFamily(robotoLight, robotoItalic)
}
RoktUxConfig.builder()
.composeFontMap(mapOf("roboto" to fontFamily))
.build()
インストールガイドインストールガイド への直接リンク
モジュール(アプリレベル)の Gradle ファイル(通常は <project>/<app-module>/build.gradle.kts または <project>/<app-module>/build.gradle)に、Rokt UX Helper の依存関係を追加します。
- Kotlin
- Groovy
implementation("com.rokt:roktux:0.1.0")
implementation 'com.rokt:roktux:0.1.0'
RoktLayoutの初期化RoktLayoutの初期化 への直接リンク
Rokt UX Helperを使用するには、アプリの関連するXMLにレイアウトを追加する必要があります。この例では、どのレイアウトがこのビューにロードされているかを示すためにRoktEmbedded1を使用しています。これはページの設定と一致する必要があります。
<com.rokt.roktux.RoktLayoutView
android:id="@+id/roktLayoutView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:location="RoktEmbedded1" />
- Kotlin
- Java
val roktLayoutView: RoktLayoutView = findViewById(R.id.roktLayoutView)
val experienceResponse: String = // Retrieve the experience response from your server
val roktUxConfig = RoktUxConfig.builder()
.build()
roktLayoutView.loadLayout(
experienceResponse = experienceResponse,
roktUxConfig,
onUxEvent = { event ->
// Handle UX events here
},
onPlatformEvent = { platformEvent ->
// Send these platform events to Rokt API
},
)
final RoktLayoutView roktLayoutView = findViewById(R.id.roktLayoutView);
final String experienceResponse = "";
final RoktUxConfig roktUxConfig = RoktUxConfig.builder()
.build()
roktLayoutView.loadLayout(
experienceResponse,
roktUxConfig,
roktUxEvent -> {
// Handle UX events here
return null;
},
roktPlatformEvent -> {
// Send these platform events to Rokt API
return null;
}
);
UXイベントUXイベント への直接リンク
onUXEventハンドラーを使用して、ユーザーのインタラクションに関するリアルタイムのフィードバックを受け取ります。
最低限、RoktUXEvent.OpenUrlイベントがトリガーされたときに、それを処理して以下の例を使用してリンクを開く必要があります。
OpenUrl - onCloseOpenUrl - onClose への直接リンク
OpenUrlタイプのイベントを処理する際には、onCloseコールバックを呼び出すことが重要です。これにより、RoktUXHelperに次のオファーに移動するなどのロジックを実行させることができます。
- Kotlin
- Java
openUrlEvent.onClose.invoke(openUrlEvent.id)
openUrlEvent.getOnClose().invoke(openUrlEvent.getId());
- Kotlin
- Java
onUxEvent = { event ->
println("RoktEvent: onUxEvent received $event")
if (event is RoktUxEvent.OpenUrl) {
val openUrlEvent = event as RoktUxEvent.OpenUrl
when (openUrlEvent.type) {
OpenLinks.Internally -> {
// Open AndroidX browser or similar functionality to keep the user in app
val customTabsIntent = CustomTabsIntent.Builder().build()
customTabsIntent.launchUrl(context, Uri.parse(openUrlEvent.url))
openUrlEvent.onClose.invoke(openUrlEvent.id) // This must be called when the user is ready for the next offer
}
OpenLinks.Externally, OpenLinks.Passthrough -> {
// Open external browser allowing user to leave the app
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(openUrlEvent.url))
context.startActivity(intent)
openUrlEvent.onClose.invoke(openUrlEvent.id) // This must be called when the user is ready for the next offer
}
}
}
}
roktUxEvent -> {
// Handle open URL event
// Here is a sample how to open different types of URLs
if (roktUxEvent instanceof RoktUxEvent.OpenUrl openUrlEvent) {
if (openUrlEvent.getType() == OpenLinks.Internally) {
// Open AndroidX browser or similar functionality to keep the user in app
CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder().build();
customTabsIntent.launchUrl(context, Uri.parse(openUrlEvent.getUrl()));
openUrlEvent.getOnClose().invoke(openUrlEvent.getId()); // This must be called when the user is ready for the next offer
} else {
// Open external browser allowing user to leave the app
final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(openUrlEvent.getUrl()));
context.startActivity(intent);
openUrlEvent.getOnClose().invoke(openUrlEvent.getId()); // This must be called when the user is ready for the next offer
}
}
return null;
}
すべてのイベント
UXイベントUXイベント への直接リンク
| イベント | 説明 | パラメータ |
|---|---|---|
| OfferEngagement | ユーザーがオファーに関与したときにトリガーされます | layoutId: String |
| PositiveEngagement | ユーザーがオファーに積極的に関与したときにトリガーされます | layoutId: String |
| LayoutInteractive | レイアウトがレンダリングされ、インタラクション可能になったときにトリガーされます | layoutId: String |
| LayoutReady | レイアウトが表示準備が整ったが、まだコンテンツがレンダリングされていないときにトリガーされます | layoutId: String |
| LayoutClosed | ユーザーによってレイアウトが閉じられたときにトリガーされます | layoutId: String |
| LayoutCompleted | オファーの進行が終了し、表示可能なオファーがもうないときにトリガーされます | layoutId: String |
| LayoutFailure | 何らかの失敗によりレイアウトが表示できなかったときにトリガーされます | layoutId: String (optional) |
| OpenUrl | リンクを開く必要があるときにトリガーされます | url: String, id: String, type: OpenLinks (internally/externally/Passthrough), onClose: (id: String) -> Unit, onError: (id: String, throwable: Throwable) |
PlatformEventsPlatformEvents への直接リンク
プラットフォームイベントは統合の重要な部分であり、あなたのバックエンドを通じてRoktに送信する必要があります。統合を容易にするために、オブジェクトはRoktPlatformEventsWrapper型であり、@Serializableを実装し、toJsonString関数を提供します。
- Kotlin
- Java
onPlatformEvent = { events ->
// Send these platform events to Rokt API including the event body
}
roktPlatformEvents -> {
// Send these platform events to Rokt API including the event body
return null;
}
イベントの完全なリストはこちらで確認できます。
オプション: アプリの設定オプション: アプリの設定 への直接リンク
カラーモードカラーモード への直接リンク
カラーモードを使用すると、Roktレイアウトを表示する際に使用するテーマを固定できます。デフォルトでは、Roktは現在のシステムテーマに一致します。
- Kotlin
- Java
val config = RoktUxConfig.builder()
.colorMode(ColorMode.DARK)
.build()
final RoktUxConfig build = new RoktUxConfig.builder()
.colorMode(ColorMode.DARK)
.build();
RoktUxColorMode オブジェクトRoktUxColorMode オブジェクト への直接リンク
| 値 | 説明 |
|---|---|
| LIGHT | アプリケーションはライトモードです |
| DARK | アプリケーションはダークモードです |
| SYSTEM | アプリケーションはシステムカラーモードをデフォルトにします |
ImageLoaderImageLoader への直接リンク
Rokt UX Helperでは、画像を読み込むためにcoilが使用されており、UX Helperにはアプリで利用できるいくつかの組み込みイメージローダーがあります。最も簡単で推奨される実装方法はNetworkStrategyですが、ネットワーキングライブラリや好みに応じてカスタムの画像読み込み戦略を作成することもできます。
- Kotlin
- Java
val roktUxConfig = RoktUxConfig.builder()
.imageHandlingStrategy(NetworkStrategy())
.build()
final roktUxConfig = new RoktUxConfig.builder()
.imageHandlingStrategy(new NetworkStrategy())
.build();
フォントフォント への直接リンク
まず、フォントファイル、例えばroboto_light.ttfをAndroidのリソースフォルダに追加し、UX Helperを使用してRoktUxConfigでそれらを設定します。以下の例はリソースに設定されたフォント用ですが、AssetFontItemを使用してアセット内のフォントもサポートしています。
- Kotlin
- Java
val robotoFonts: List<ResourceFontItem> = listOf(
ResourceFontItem(R.font.roboto_light, FontItemWeight.W100, FontItemStyle.Normal),
ResourceFontItem(R.font.roboto_light, FontItemWeight.W300, FontItemStyle.Normal),
ResourceFontItem(R.font.roboto_italic, FontItemWeight.W400, FontItemStyle.Italic),
ResourceFontItem(R.font.roboto_bold, FontItemWeight.W700, FontItemStyle.Normal),
ResourceFontItem(R.font.roboto_black, FontItemWeight.W900, FontItemStyle.Normal),
// Add any relevant fonts
)
// If you have multiple fonts create them here and add them to the fontFamilyMap
val config = RoktUxConfig.builder()
.xmlFontFamilyMap(mapOf("roboto" to robotoFonts))
.build()
final List<ResourceFontItem> fontItems = Arrays.asList(
new ResourceFontItem(R.font.roboto_light, FontItemWeight.W100, FontItemStyle.Normal),
new ResourceFontItem(R.font.roboto_light, FontItemWeight.W300, FontItemStyle.Normal),
new ResourceFontItem(R.font.roboto_italic, FontItemWeight.W400, FontItemStyle.Italic),
new ResourceFontItem(R.font.roboto_bold, FontItemWeight.W700, FontItemStyle.Normal),
new ResourceFontItem(R.font.roboto_black, FontItemWeight.W900, FontItemStyle.Normal)
// Add any relevant fonts
);
// If you have multiple fonts create them here and add them to the fontFamilyMap
final Map<String, List<ResourceFontItem>> fontFamilyMap = new HashMap<>();
fontFamilyMap.put("roboto", fontItems);
final RoktUxConfig config = new RoktUxConfig.builder()
.xmlFontFamilyMap(fontFamilyMap)
.build();