Android SDK Analytics

The SDK provides APIs for tracking application-level analytics events.

Custom Events

Custom events let you track app-specific user actions and use them in Magify logic.

You can track a custom event with only an event name:

magify.trackCustomEvent("start_coins")

You can also pass custom parameters:

magify.trackCustomEvent(
    "start_coins",
    mapOf(
        "source" to "shop",
        "coins" to 100
    )
)

Event Name Rules

Custom event names must follow these rules:

  • The name is required.
  • The name must be from 1 to 90 characters long.
  • The name must start with a lowercase letter.
  • The name must end with a lowercase letter or a digit.
  • The name can contain lowercase letters, digits, and underscores.
  • Spaces, uppercase letters, dots, dashes, and special characters are not allowed.

Custom Parameters

Custom parameters are optional.

If no parameters are passed, the event is sent without the custom_params field:

magify.trackCustomEvent("start_coins")

If an empty map is passed, the event is sent with an empty custom_params object:

magify.trackCustomEvent("start_coins", emptyMap())

Campaign impression and click tracking

Track when a campaign is shown or tapped by the user.

// Record that a campaign was displayed
magify.trackImpression(CampaignType.SUBSCRIPTION)

// Record that the user tapped a campaign
magify.trackClick(CampaignType.SUBSCRIPTION)

// Record that the user tapped a specific product inside a campaign
magify.trackProductClick(
    CampaignType.SUBSCRIPTION,
    productId = "product_001"
)

// Record a failed impression with a reason string
magify.trackImpressionFail(
    CampaignType.SUBSCRIPTION,
    reason = "no_fill"
)

Virtual-economy transactions

Use transactions to record changes to the user's in-game virtual currency or resources.

BonusInfo

Every transaction requires at least one BonusInfo entry describing the resource affected.

import com.magify.sdk.analytics.model.BonusInfo

val bonus = BonusInfo(
    name = "coins",          // resource name
    quantity = 500,          // amount added or removed
    finalBalance = 1500,     // balance after the transaction
    group = "currency"       // optional grouping label
)

ProductInfo

Optionally attach product metadata to an income transaction.

import com.magify.sdk.analytics.model.ProductInfo

val product = ProductInfo(
    productId = "offer_pack_001",
    price = "4.99",   // optional
    currency = "USD"  // optional
)

Income transaction

Call trackIncomeTransaction(source, bonuses, product?) when the user gains resources:

Note

Passing an empty bonuses list is an error. All three transaction methods (trackIncomeTransaction, trackExpenseTransaction, and trackCorrectionTransaction) log an error and return immediately (no-op) when bonuses is empty — no data is recorded.

magify.trackIncomeTransaction(
    source = "iap_purchase",
    bonuses = listOf(
        BonusInfo(
            name = "coins",
            quantity = 500,
            finalBalance = 1500,
            group = "currency"
        )
    ),
    product = ProductInfo(
        productId = "offer_pack_001",
        price = "4.99",
        currency = "USD"
    )
)

Expense transaction

Call trackExpenseTransaction(bonuses) when the user spends resources:

magify.trackExpenseTransaction(
    bonuses = listOf(
        BonusInfo(
            name = "coins",
            quantity = 100,
            finalBalance = 1400
        )
    )
)

Correction transaction

Call trackCorrectionTransaction(bonuses) to record a balance correction:

magify.trackCorrectionTransaction(
    bonuses = listOf(
        BonusInfo(
            name = "coins",
            quantity = 50,
            finalBalance = 1450
        )
    )
)

Product usage events

Track how rewarded, free-bonus, and ordinary products are consumed after the user receives them.

// User received a rewarded-video reward
magify.trackRewardGranted(productId = "video_reward_001")

// User received a free bonus product
magify.trackFreeBonusGranted(productId = "daily_bonus_001")

// User consumed a regular (non-reward, non-bonus) product
magify.trackOrdinaryProductUsed(productId = "consumable_pack_001")

Game state context

Attach game-state metadata to all subsequent analytics events. Call these methods whenever the values change.

// Current game mode (e.g. "pvp", "story")
magify.setGameMode("story")

// Current level the user is on
magify.setGameLevel(12)

// Highest level the user has reached
magify.setGameMaxLevel(15)

Pass null to any setter to clear the value:

magify.setGameMode(null)

User email

Associate a user email address with analytics events for mailing-status mapping:

magify.setUserEmail("user@example.com")

The SDK validates the address format. If the email is invalid, an error is logged and the event is not sent.

Observing state changes

The SDK exposes RxJava2 (io.reactivex.Observable) streams for reacting to state changes in your UI layer.

// Emits whenever the subscription status changes
magify.observeSubscriptionStatusChanged()
    .subscribe { /* update UI */ }

// Emits the new session number (Int) whenever the session counter increments
magify.observeSessionNumberChanged()
    .subscribe { sessionNumber -> /* log or display */ }

All observe* methods return io.reactivex.Observable.

Batching configuration

By default, the SDK uses built-in thresholds for how many events to accumulate before flushing (groupSize) and how often to flush on a timer (syncIntervalInSeconds).

You can override these with tweakAnalyticsConfig and restore the defaults with resetAnalyticsConfig.

import com.magify.sdk.model.AnalyticsConfiguration

// Flush after every 5 events, or every 30 s — whichever comes first
magify.tweakAnalyticsConfig(
    AnalyticsConfiguration(
        groupSize = 5,               // events per flush batch
        syncIntervalInSeconds = 30   // flush timer interval, in seconds
    )
)

// Restore SDK defaults
magify.resetAnalyticsConfig()

Note

syncIntervalInSeconds is specified in seconds. The SDK multiplies it by 1000 internally when scheduling the timer — do not pass milliseconds here.

Next step

To synchronize subscription and in-app purchase status, track purchases, and configure purchase verification, see the Purchases section.

Related articles

Adjust

Flutter SDK Installation

Validation

Adjust

Analytics

UnityPurchasing