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
bonuseslist is an error. All three transaction methods (trackIncomeTransaction,trackExpenseTransaction, andtrackCorrectionTransaction) log an error and return immediately (no-op) whenbonusesis 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
syncIntervalInSecondsis 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.