Android
AdStage アプリ内イベント統合ガイド(Android)
目次
概要
AdStage のアプリ内イベントは、ユーザーの行動とアプリのイベントをトラッキングし、マーケティング分析と最適化を支援します。
主な機能
- 柔軟なイベント送信:シンプルな呼び出しから詳細なコンテキストまで
- コンテキストの自動収集:デバイス情報・ユーザー属性を自動で付与
- セッション管理:セッションを自動でトラッキング・管理
- Builder パターン:可読性の高い DSL スタイルに対応
- 非同期処理:Coroutine ベースの suspend 関数
- オフライン対応:ネットワーク再接続時に自動で再送信
基本設定
1. Gradle 依存関係の追加
settings.gradle.kts
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { url = uri("https://repo.nbase.io/repository/nbase-releases") }
}
}build.gradle.kts (Module: app)
dependencies {
implementation("io.nbase:nbase-adapter-adstage:3.0.9")
// 必須の依存関係
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
implementation("com.squareup.okhttp3:okhttp:4.11.0")
}2. SDK の初期化
import io.nbase.adapter.adstage.AdStage
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
// AdStage の初期化
AdStage.initialize(
context = this,
apiKey = "your-api-key-here",
serverUrl = "https://api.adstage.app" // 任意。デフォルト値を使用可能
)
Log.d("AdStage", "✅ SDK の初期化が完了しました")
}
}3. AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 必須の権限 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:name=".MyApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name">
<!-- ... -->
</application>
</manifest>型安全なイベント送信
1. 最もシンプルな方法
trackEvent は suspend 関数とコールバックのオーバーロードをあわせて提供します。
suspend 関数はコルーチンスコープの中で呼び出し、コルーチンの外ではコールバック版を使います。
import io.nbase.adapter.adstage.AdStage
import io.nbase.adapter.adstage.models.AdStageEvent
import io.nbase.adapter.adstage.models.SignUpMethod
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
CoroutineScope(Dispatchers.IO).launch {
// パラメータのないイベント(suspend)
AdStage.trackEvent(AdStageEvent.FirstOpen())
// ログインイベント(method は文字列。SignUpMethod enum の value を使用)
AdStage.trackEvent(
AdStageEvent.Login(method = SignUpMethod.EMAIL.value)
)
}
// コールバック版(コルーチンなしで呼び出し)
AdStage.trackEvent(AdStageEvent.Login(method = SignUpMethod.EMAIL.value)) { result ->
when (result) {
is TrackEventResult.Success -> Log.d("AdStage", "送信に成功しました")
is TrackEventResult.Failure -> Log.e("AdStage", "送信に失敗しました: ${result.error}")
}
}2. 購入イベント(検証の例)
value がある場合、currency は必須です。指定しないと、イベントオブジェクトの作成時点で
IllegalArgumentException が発生します(ランタイム検証)。
// ✅ GOOD: value と currency をあわせて指定
AdStage.trackEvent(
AdStageEvent.Purchase(
value = 29.99,
currency = "USD",
transactionId = "TXN_123456"
)
)
// ❌ BAD: value だけを指定するとランタイム例外 (IllegalArgumentException)
AdStage.trackEvent(
AdStageEvent.Purchase(
value = 29.99 // ❌ 例外:value がある場合は currency が必須!
)
)
// ✅ GOOD: currency なしで transactionId のみ
AdStage.trackEvent(
AdStageEvent.Purchase(
transactionId = "TXN_123456"
)
)3. 商品の閲覧
// パラメータあり
AdStage.trackEvent(
AdStageEvent.ProductDetailsView(
itemId = "PROD_123",
itemName = "Wireless Earbuds"
)
)
// パラメータなし
AdStage.trackEvent(AdStageEvent.ProductListView())4. カスタムイベント(event_name の自動昇格)
標準イベント以外のアプリ固有のイベントを送信するときは、AdStageEvent.Custom を使います。
パラメータに event_name キーを含めると、その値が実際のイベント名に自動で昇格され、ダッシュボードに保存されます。
// 例:'promotion_click' というカスタムイベントを送信
AdStage.trackEvent(
AdStageEvent.Custom(
params = mapOf(
"event_name" to "promotion_click",
"promotion_id" to "summer_sale_2025",
"screen" to "home_banner"
)
)
)
// ダッシュボードには "promotion_click" イベントとして収集される
// event_name なしの一般的なカスタムイベント
AdStage.trackEvent(
AdStageEvent.Custom(
params = mapOf(
"action" to "button_click",
"button_id" to "promo_banner",
"screen" to "home",
"timestamp" to System.currentTimeMillis()
)
)
)
// ダッシュボードには "custom" イベントとして収集される
// Click、View も自由なパラメータに対応
AdStage.trackEvent(
AdStageEvent.Click(
params = mapOf(
"campaign_id" to "SUMMER2025",
"ad_group" to "electronics"
)
)
)標準イベントカタログ
AdStage SDK は 46 個の標準イベントを提供します。
📌 広告トラッキング(4 個)
// 1. 広告のクリック
AdStage.trackEvent(
AdStageEvent.Click(
params = mapOf("campaign_id" to "CAMP_123")
)
)
// 2. 広告のインプレッション
AdStage.trackEvent(
AdStageEvent.View(
params = mapOf("impression_id" to "IMP_456")
)
)
// 3. アプリのインストール
AdStage.trackEvent(AdStageEvent.Install())
// 4. カスタムイベント(event_name でイベント名を指定)
AdStage.trackEvent(
AdStageEvent.Custom(
params = mapOf(
"event_name" to "promotion_click",
"promotion_id" to "summer_sale_2025"
)
)
)👤 ユーザーライフサイクル(5 個)
SignUp と Login の method は文字列(String?)のパラメータです。文字列を直接
指定するか、SDK が提供する SignUpMethod enum の .value を使います。
// SDK が提供する SignUpMethod enum(参考用)
enum class SignUpMethod(val value: String) {
EMAIL("email"),
GOOGLE("google"),
APPLE("apple"),
FACEBOOK("facebook"),
KAKAO("kakao"),
NAVER("naver")
}
// 1. 会員登録の完了
AdStage.trackEvent(
AdStageEvent.SignUp(method = SignUpMethod.GOOGLE.value)
)
// 2. 会員登録の開始
AdStage.trackEvent(AdStageEvent.SignUpStart())
// 3. ログイン(文字列を直接使うことも可能: method = "email")
AdStage.trackEvent(
AdStageEvent.Login(method = SignUpMethod.EMAIL.value)
)
// 4. ログアウト
AdStage.trackEvent(AdStageEvent.Logout())
// 5. アプリの初回起動
AdStage.trackEvent(AdStageEvent.FirstOpen())📄 コンテンツの閲覧(6 個)
// 1. ホーム画面
AdStage.trackEvent(AdStageEvent.HomeView())
// 2. 商品一覧
AdStage.trackEvent(
AdStageEvent.ProductListView(itemCategory = "electronics")
)
// 3. 検索結果
AdStage.trackEvent(
AdStageEvent.SearchResultView(searchTerm = "wireless headphones")
)
// 4. 商品詳細
AdStage.trackEvent(
AdStageEvent.ProductDetailsView(
itemId = "PROD_123",
itemName = "Wireless Earbuds"
)
)
// 5. ページビュー(ウェブ)
AdStage.trackEvent(
AdStageEvent.PageView(
pageUrl = "https://example.com/products",
pageTitle = "Products"
)
)
// 6. 画面ビュー(アプリ)
AdStage.trackEvent(
AdStageEvent.ScreenView(
screenName = "product_detail",
screenClass = "ProductDetailActivity"
)
)🛒 EC(7 個)
EcommerceItem が持つフィールドは itemId、itemName、price、quantity の 4 つだけです。
// 1. カートに追加
AdStage.trackEvent(
AdStageEvent.AddToCart(
value = 99000.0,
currency = "KRW",
items = listOf(
EcommerceItem(
itemId = "PROD_123",
itemName = "Wireless Earbuds",
price = 99000.0,
quantity = 1
)
)
)
)
// 2. カートから削除
AdStage.trackEvent(
AdStageEvent.RemoveFromCart(
value = 50000.0,
currency = "KRW"
)
)
// 3. ウィッシュリストに追加
AdStage.trackEvent(
AdStageEvent.AddToWishlist(
itemId = "PROD_456",
itemName = "Smart Watch"
)
)
// 4. 支払い情報の入力
AdStage.trackEvent(
AdStageEvent.AddPaymentInfo(paymentType = "credit_card")
)
// 5. 決済の開始
AdStage.trackEvent(
AdStageEvent.BeginCheckout(
value = 150000.0,
currency = "KRW"
)
)
// 6. 購入の完了 ⭐⭐⭐
AdStage.trackEvent(
AdStageEvent.Purchase(
value = 129000.0,
currency = "KRW",
transactionId = "ORDER_20250105_001",
tax = 12900.0,
shipping = 3000.0,
coupon = "SUMMER2025",
items = listOf(
EcommerceItem(
itemId = "PROD_123",
itemName = "Wireless Earbuds",
price = 126000.0,
quantity = 1
)
)
)
)
// 7. 返金
AdStage.trackEvent(
AdStageEvent.Refund(
transactionId = "ORDER_20250105_001",
value = 129000.0,
currency = "KRW"
)
)🎮 進行・達成(4 個)
// 1. チュートリアルの開始
AdStage.trackEvent(
AdStageEvent.TutorialBegin(
params = mapOf("tutorial_id" to "intro")
)
)
// 2. チュートリアルの完了
AdStage.trackEvent(
AdStageEvent.TutorialComplete(
params = mapOf("duration_seconds" to 120)
)
)
// 3. レベルアップ
AdStage.trackEvent(
AdStageEvent.LevelUp(
level = 25,
character = "warrior"
)
)
// 4. 実績の達成
AdStage.trackEvent(
AdStageEvent.Achievement(achievementId = "first_win")
)💬 インタラクション(7 個)
// 1. 検索
AdStage.trackEvent(
AdStageEvent.Search(searchTerm = "gaming laptop")
)
// 2. コンテンツの選択
AdStage.trackEvent(
AdStageEvent.SelectContent(
contentType = "product",
contentId = "PROD_789"
)
)
// 3. 共有
AdStage.trackEvent(
AdStageEvent.Share(
contentType = "product",
method = "kakao"
)
)
// 4. いいね
AdStage.trackEvent(
AdStageEvent.Like(
contentType = "product",
contentId = "PROD_789"
)
)
// 5. 評価
AdStage.trackEvent(
AdStageEvent.Rate(
contentType = "product",
contentId = "PROD_789",
score = 4.5
)
)
// 6. 予定の登録
AdStage.trackEvent(
AdStageEvent.Schedule(
params = mapOf("event_type" to "appointment")
)
)
// 7. クレジットの使用
AdStage.trackEvent(
AdStageEvent.SpendCredits(
value = 10.0,
itemName = "premium_feature"
)
)📢 アプリ内広告(2 個)
// 1. アプリ内広告のインプレッション
AdStage.trackEvent(
AdStageEvent.AdImpression(
adPlatform = "admob",
adFormat = "rewarded_video",
adUnitName = "main_reward"
)
)
// 2. アプリ内広告のクリック
AdStage.trackEvent(
AdStageEvent.AdClick(
adPlatform = "admob",
adFormat = "banner",
adUnitName = "home_bottom"
)
)🎮 ゲーム向け(4 個)
// 1. ゲームプレイ
AdStage.trackEvent(
AdStageEvent.GamePlay(
level = 10,
levelName = "Dragon's Lair",
character = "mage",
contentType = "dungeon"
)
)
// 2. ボーナスの獲得
AdStage.trackEvent(
AdStageEvent.AcquireBonus(
contentType = "reward",
itemId = "ITEM_123",
itemName = "Gold Chest",
quantity = 1
)
)
// 3. ゲームサーバーの選択
AdStage.trackEvent(
AdStageEvent.SelectGameServer(
contentId = "SERVER_01",
contentType = "pvp",
itemName = "Asia Server"
)
)
// 4. パッチの完了
AdStage.trackEvent(
AdStageEvent.CompletePatch(
contentId = "PATCH_2.1.0",
contentType = "update"
)
)📅 サブスクリプション・トライアル(3 個)
// 1. 無料トライアルの開始
AdStage.trackEvent(
AdStageEvent.StartTrial(
value = 9900.0,
currency = "KRW",
trialDays = 14
)
)
// 2. サブスクリプションの開始
AdStage.trackEvent(
AdStageEvent.Subscribe(
value = 9900.0,
currency = "KRW",
subscriptionId = "premium_monthly"
)
)
// 3. サブスクリプションの解約
AdStage.trackEvent(
AdStageEvent.Unsubscribe(subscriptionId = "premium_monthly")
)💰 金融向け(4 個)
// 1. 株式の買い付け
AdStage.trackEvent(
AdStageEvent.BuyStock(
itemId = "005930",
itemName = "サムスン電子",
quantity = 10,
price = 70000.0,
value = 700000.0,
currency = "KRW"
)
)
// 2. 株式の売却
AdStage.trackEvent(
AdStageEvent.SellStock(
itemId = "005930",
itemName = "サムスン電子",
quantity = 5,
price = 72000.0,
value = 360000.0,
currency = "KRW"
)
)
// 3. 口座開設の完了
AdStage.trackEvent(
AdStageEvent.CompleteOpenAccount(
contentType = "証券口座",
contentId = "ACC_123",
method = "mobile"
)
)
// 4. カードの申し込み
AdStage.trackEvent(
AdStageEvent.ApplyCard(
contentType = "クレジットカード",
itemName = "プレミアムカード",
itemId = "CARD_001"
)
)イベントタイプ別の例
1. アプリのライフサイクル
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
// SDK の初期化
AdStage.initialize(this, apiKey, serverUrl)
// 初回起動イベントは SDK が自動で送信
Log.d("App", "✅ アプリを起動しました")
}
}2. ユーザー認証
class AuthManager {
// 会員登録(method は文字列のパラメータ)
fun onSignUpComplete(method: String) {
AdStage.trackEvent(
AdStageEvent.SignUp(method = method)
)
Log.d("Auth", "✅ 会員登録が完了しました: $method")
}
// ログイン
fun onLoginSuccess(userId: String, method: String) {
AdStage.trackEvent(
AdStageEvent.Login(method = method)
)
Log.d("Auth", "✅ ログイン: $userId")
}
// ログアウト
fun onLogout() {
AdStage.trackEvent(AdStageEvent.Logout())
Log.d("Auth", "🚪 ログアウト")
}
}3. 画面トラッキング(BaseActivity パターン)
abstract class BaseActivity : AppCompatActivity() {
override fun onResume() {
super.onResume()
trackScreenView()
}
abstract fun getScreenName(): String
private fun trackScreenView() {
AdStage.trackEvent(
AdStageEvent.ScreenView(
screenName = getScreenName(),
screenClass = this::class.java.simpleName
)
)
Log.d("Screen", "📺 ${getScreenName()}")
}
}
// 使用例
class HomeActivity : BaseActivity() {
override fun getScreenName() = "home"
}
class ProductDetailActivity : BaseActivity() {
override fun getScreenName() = "product_detail"
private fun loadProduct(productId: String) {
// 商品データを読み込み中...
// 商品詳細の閲覧イベント
AdStage.trackEvent(
AdStageEvent.ProductDetailsView(
itemId = productId,
itemName = product.name
)
)
}
}4. EC の一連のフロー
class EcommerceManager {
// 1. 商品一覧の閲覧
fun trackProductList(category: String) {
AdStage.trackEvent(
AdStageEvent.ProductListView(itemCategory = category)
)
}
// 2. 検索
fun trackSearch(query: String) {
AdStage.trackEvent(
AdStageEvent.Search(searchTerm = query)
)
}
// 3. 検索結果の閲覧
fun trackSearchResults(query: String) {
AdStage.trackEvent(
AdStageEvent.SearchResultView(searchTerm = query)
)
}
// 4. 商品詳細の閲覧
fun trackProductView(product: Product) {
AdStage.trackEvent(
AdStageEvent.ProductDetailsView(
itemId = product.id,
itemName = product.name
)
)
}
// 5. カートに追加
fun trackAddToCart(product: Product, quantity: Int) {
val item = EcommerceItem(
itemId = product.id,
itemName = product.name,
price = product.price,
quantity = quantity
)
AdStage.trackEvent(
AdStageEvent.AddToCart(
value = product.price * quantity,
currency = "KRW",
items = listOf(item)
)
)
}
// 6. ウィッシュリストに追加
fun trackAddToWishlist(product: Product) {
AdStage.trackEvent(
AdStageEvent.AddToWishlist(
itemId = product.id,
itemName = product.name
)
)
}
// 7. 決済の開始
fun trackBeginCheckout(cart: Cart) {
val items = cart.items.map { cartItem ->
EcommerceItem(
itemId = cartItem.product.id,
itemName = cartItem.product.name,
price = cartItem.product.price,
quantity = cartItem.quantity
)
}
AdStage.trackEvent(
AdStageEvent.BeginCheckout(
value = cart.totalAmount,
currency = "KRW",
items = items
)
)
}
// 8. 支払い情報の入力
fun trackAddPaymentInfo(paymentMethod: String) {
AdStage.trackEvent(
AdStageEvent.AddPaymentInfo(paymentType = paymentMethod)
)
}
// 9. 購入の完了 ⭐⭐⭐
fun trackPurchase(order: Order) {
val items = order.items.map { orderItem ->
EcommerceItem(
itemId = orderItem.product.id,
itemName = orderItem.product.name,
price = orderItem.product.price,
quantity = orderItem.quantity
)
}
AdStage.trackEvent(
AdStageEvent.Purchase(
value = order.totalAmount,
currency = "KRW",
transactionId = order.id,
tax = order.tax,
shipping = order.shippingFee,
coupon = order.couponCode,
items = items
)
)
Log.d("Ecommerce", "✅ 購入が完了しました: ${order.id}, ${order.totalAmount}ウォン")
}
// 10. 返金
fun trackRefund(order: Order) {
AdStage.trackEvent(
AdStageEvent.Refund(
transactionId = order.id,
value = order.totalAmount,
currency = "KRW"
)
)
}
// 11. 共有
fun trackShare(product: Product, method: String) {
AdStage.trackEvent(
AdStageEvent.Share(
contentType = "product",
method = method
)
)
}
}5. ゲームイベント
class GameEventManager {
// チュートリアル
fun trackTutorialBegin(tutorialId: String) {
AdStage.trackEvent(
AdStageEvent.TutorialBegin(
params = mapOf("tutorial_id" to tutorialId)
)
)
}
fun trackTutorialComplete(tutorialId: String, duration: Long) {
AdStage.trackEvent(
AdStageEvent.TutorialComplete(
params = mapOf(
"tutorial_id" to tutorialId,
"duration_seconds" to duration / 1000
)
)
)
}
// レベル
fun trackLevelUp(level: Int, character: String) {
AdStage.trackEvent(
AdStageEvent.LevelUp(
level = level,
character = character
)
)
}
// 実績
fun trackAchievement(achievementId: String) {
AdStage.trackEvent(
AdStageEvent.Achievement(achievementId = achievementId)
)
}
// ゲームプレイ
fun trackGameStart(level: Int, levelName: String, character: String) {
AdStage.trackEvent(
AdStageEvent.GamePlay(
level = level,
levelName = levelName,
character = character,
contentType = "pvp"
)
)
}
// ボーナスの獲得
fun trackBonusAcquired(itemId: String, itemName: String, quantity: Int) {
AdStage.trackEvent(
AdStageEvent.AcquireBonus(
contentType = "reward",
itemId = itemId,
itemName = itemName,
quantity = quantity
)
)
}
// クレジット(通貨)の使用
fun trackSpendCredits(amount: Double, itemName: String) {
AdStage.trackEvent(
AdStageEvent.SpendCredits(
value = amount,
itemName = itemName
)
)
}
}ベストプラクティス
1. Extension 関数の活用
// ActivityExtensions.kt
fun Activity.trackScreen() {
val screenName = this::class.java.simpleName
.removeSuffix("Activity")
.lowercase()
AdStage.trackEvent(
AdStageEvent.ScreenView(
screenName = screenName,
screenClass = this::class.java.simpleName
)
)
}
// 使用
class ProfileActivity : AppCompatActivity() {
override fun onResume() {
super.onResume()
trackScreen() // ✅ シンプル!
}
}2. ViewModel でのイベントトラッキング
class ProductViewModel : ViewModel() {
private val _productState = MutableLiveData<Product>()
val productState: LiveData<Product> = _productState
fun loadProduct(productId: String) {
viewModelScope.launch {
try {
val product = repository.getProduct(productId)
_productState.value = product
// 商品閲覧イベント
AdStage.trackEvent(
AdStageEvent.ProductDetailsView(
itemId = product.id,
itemName = product.name
)
)
} catch (e: Exception) {
Log.e("ProductVM", "Failed to load product", e)
}
}
}
fun addToCart(product: Product, quantity: Int) {
viewModelScope.launch {
try {
repository.addToCart(product, quantity)
val item = EcommerceItem(
itemId = product.id,
itemName = product.name,
price = product.price,
quantity = quantity
)
AdStage.trackEvent(
AdStageEvent.AddToCart(
value = product.price * quantity,
currency = "KRW",
items = listOf(item)
)
)
} catch (e: Exception) {
Log.e("ProductVM", "Failed to add to cart", e)
}
}
}
}3. Compose UI での使用
@Composable
fun ProductDetailScreen(
productId: String,
viewModel: ProductViewModel = hiltViewModel()
) {
val product by viewModel.productState.collectAsState()
// 画面表示時のイベント
LaunchedEffect(productId) {
viewModel.loadProduct(productId)
AdStage.trackEvent(
AdStageEvent.ScreenView(
screenName = "product_detail",
screenClass = "ProductDetailScreen"
)
)
}
Column {
// UI...
Button(
onClick = {
viewModel.addToCart(product, 1)
AdStage.trackEvent(
AdStageEvent.Custom(
params = mapOf(
"action" to "add_to_cart_button",
"product_id" to product.id
)
)
)
}
) {
Text("カートに追加")
}
}
}4. イベントラッパークラス
object AnalyticsManager {
private const val TAG = "Analytics"
fun trackScreen(screenName: String, screenClass: String? = null) {
AdStage.trackEvent(
AdStageEvent.ScreenView(
screenName = screenName,
screenClass = screenClass
)
)
Log.d(TAG, "📺 Screen: $screenName")
}
fun trackPurchase(order: Order) {
val items = order.items.map {
EcommerceItem(
itemId = it.product.id,
itemName = it.product.name,
price = it.product.price,
quantity = it.quantity
)
}
AdStage.trackEvent(
AdStageEvent.Purchase(
value = order.totalAmount,
currency = "KRW",
transactionId = order.id,
items = items
)
)
Log.d(TAG, "💰 Purchase: ${order.id}")
}
fun trackError(error: Throwable, context: String) {
AdStage.trackEvent(
AdStageEvent.Custom(
params = mapOf(
"event_type" to "error",
"error_message" to (error.message ?: "unknown"),
"context" to context
)
)
)
Log.e(TAG, "❌ Error: $context", error)
}
}5. パフォーマンス最適化:Throttling
class ThrottledEventTracker {
private val lastTrackTimes = mutableMapOf<String, Long>()
private val throttleInterval = 2000L // 2 秒
fun trackEvent(event: AdStageEvent) {
val eventKey = event.eventName
val now = System.currentTimeMillis()
val lastTime = lastTrackTimes[eventKey] ?: 0L
if (now - lastTime >= throttleInterval) {
AdStage.trackEvent(event)
lastTrackTimes[eventKey] = now
} else {
Log.d("AdStage", "⏱️ Throttled: $eventKey")
}
}
}
// 使用(スクロールイベントなど)
val throttledTracker = ThrottledEventTracker()
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
throttledTracker.trackEvent(
AdStageEvent.Custom(
params = mapOf(
"action" to "scroll",
"delta_y" to dy
)
)
)
}
})変換の例(文字列ベース → 型安全 API)
現在の SDK は、AdStageEvent の型安全なイベントのみに対応しています。以下は、文字列ベースの
イベント名を型安全なイベントに変換する例です(矢印の右側が実際の使用形式)。
// 1. 基本イベント
"first_open"
→ AdStage.trackEvent(AdStageEvent.FirstOpen())
// 2. ログイン(method は文字列のパラメータ)
"login", method = "email"
→ AdStage.trackEvent(AdStageEvent.Login(method = "email"))
// 3. 画面ビュー
"screen_view", screen_name = "home"
→ AdStage.trackEvent(AdStageEvent.ScreenView(screenName = "home"))
// 4. カスタム
"custom", action = "click"
→ AdStage.trackEvent(AdStageEvent.Custom(params = mapOf("action" to "click")))トラブルシューティング
1. ランタイム例外:「value がある場合、currency は必須です」
問題:
// ❌ IllegalArgumentException (イベントオブジェクトの作成時点)
AdStage.trackEvent(
AdStageEvent.Purchase(value = 9900.0)
)解決:
// ✅ currency を追加(ISO 4217、3 文字)
AdStage.trackEvent(
AdStageEvent.Purchase(
value = 9900.0,
currency = "KRW"
)
)2. IDE の自動補完が機能しない
解決:
- Gradle Sync:
File → Sync Project with Gradle Files - Invalidate Caches:
File → Invalidate Caches / Restart... - Import を確認:
import io.nbase.adapter.adstage.models.AdStageEvent.*
// これで自動補完が機能します
AdStage.trackEvent(Purchase(...))3. ProGuard/R8 の難読化の問題
# proguard-rules.pro
# AdStage イベントモデルを保持
-keep class io.nbase.adapter.adstage.models.** { *; }
-keepclassmembers class io.nbase.adapter.adstage.models.** { *; }
# AdStageEvent sealed class
-keep class io.nbase.adapter.adstage.models.AdStageEvent { *; }
-keep class io.nbase.adapter.adstage.models.AdStageEvent$* { *; }
# Kotlin Metadata
-keep class kotlin.Metadata { *; }
4. 通貨コードの検証エラー
// ❌ 2 文字のコード
AdStageEvent.Purchase(value = 100.0, currency = "KR")
// IllegalArgumentException: "currency は ISO 4217 の 3 文字コードである必要があります(例: USD, KRW)"
// ✅ 3 文字の ISO 4217 コード
AdStageEvent.Purchase(value = 100.0, currency = "KRW") // 韓国ウォン
AdStageEvent.Purchase(value = 100.0, currency = "USD") // 米ドル
AdStageEvent.Purchase(value = 100.0, currency = "JPY") // 日本円主な通貨コード:
| 国 | 通貨 | コード |
|---|---|---|
| 韓国 | ウォン | KRW |
| 米国 | ドル | USD |
| 日本 | 円 | JPY |
| 欧州連合 | ユーロ | EUR |
| 英国 | ポンド | GBP |
5. デバッグログの確認
SDK は AdStage / AdapterAdStage タグでログを出力します。以下のフィルターを使うと、Logcat で
イベント送信の流れを確認できます。
Logcat フィルター:
# Android Studio
tag:AdStage OR tag:AdapterAdStage
# adb
adb logcat | grep -i adstage参考資料
標準リファレンス
FAQ
Q: カスタムイベントはどのように送信しますか?
A: AdStageEvent.Custom(params = mapOf(...)) を使います
Q: value なしで currency だけを使えますか?
A: いいえ。value を使う場合、currency は必須です。
Q: オフラインでも動作しますか?
A: はい。SDK がイベントを自動でキューに保存し、ネットワークの復旧時に送信します。
サポート
お問い合わせ先:
- メール:support@nbase.io
© 2025 NBase. All rights reserved.

