Skip to main content

Android Analytics

Attribution tracking (Adjust or AppsFlyer) is configured automatically via the Alogame backend. No local setup required in the SDK.

Adjust or AppsFlyer — never both

A game uses one attribution provider, selected by your operator in the Console (attribution_provider: "adjust" or "appsflyer"). The two are mutually exclusive per game. Everything below that says "Adjust" applies identically to AppsFlyer when it's the active provider — the SDK routes to whichever one is configured, using the same APIs and the same event names. See Privacy Disclosure Requirements below for what changes when AppsFlyer is selected.

Event names, their provider-specific tokens (Adjust) or allow-list membership (AppsFlyer), and the provider app/dev key are managed by your game operator on the backend — you do not configure them in the app. As a developer you only call the logging APIs below with the event name agreed with your operator.

Auto-Tracked Events​

The SDK automatically tracks the following lifecycle events when configured in the backend:

Event NameDescriptionTrigger
sdk_show_loginLogin screen displayedUser opens login UI
sdk_register_successRegistration completedUser successfully registers
sdk_login_successLogin completedUser successfully logs in (manual login only)
sdk_logoutUser logged outUser logs out or session expires
sdk_rechargeIn-app purchase completedIAP verification succeeds
sdk_switch_roleCharacter/server switch, same accountsetGameRole() called while a different role was already active
sdk_logout_game_roleActive role cleared, no logoutlogoutGameRole() called while a role was active

These events are tracked automatically once your operator has set them up on the backend. No game code required.

Set Game Role​

To enable role-specific tracking data (used in sdk_recharge and other events), call setGameRole() after the player enters the game:

Kotlin
import vn.oeg.sdk.v2.core.auth.OEGAuthCore

OEGAuthCore.setGameRole(
serverId = "server_01",
serverName = "Server 1", // optional
roleId = "character_123",
roleName = "DragonSlayer", // optional
level = 50 // optional
)
Java
import vn.oeg.sdk.v2.core.auth.OEGAuthCore;

// serverId, serverName (null = omit), roleId, roleName (null = omit), level (0 = default)
OEGAuthCore.INSTANCE.setGameRole("server_01", "Server 1", "character_123", "DragonSlayer", 50);

This information is used to enrich tracking events with player context. Calling setGameRole() again for a different server/role fires sdk_switch_role automatically — no separate call needed for a direct switch.

For games with multiple servers where the player returns to a select screen with no role picked yet, call OEGAuthCore.logoutGameRole() to clear the stale role (fires sdk_logout_game_role). The SDK also clears this data silently (no event) on logout.

See also: Game Role API for detailed documentation and usage examples.

Log an event​

The SDK can log any event — there is no fixed list. An event is just a name plus optional string parameters. Which events exist, and how each name is routed to the active provider — an Adjust event token, or membership in the AppsFlyer allow-list — is defined by your game operator (in Adjust/AppsFlyer + the Alogame backend); the SDK resolves the routing at runtime. You only need the event name agreed with your operator.

An event that isn't configured for the active provider (no Adjust token mapped; not in the AppsFlyer allow-list) is silently skipped (no tracking, no error).

Kotlin
import vn.oeg.sdk.v2.core.analytics.OEGAnalytics

OEGAnalytics.logEvent("tutorial_complete")

OEGAnalytics.logEvent("level_up", mapOf(
"level" to "10",
"score" to "15000"
))
Java
import vn.oeg.sdk.v2.core.analytics.OEGAnalytics;
import java.util.HashMap;
import java.util.Map;

OEGAnalytics.INSTANCE.logEvent("tutorial_complete");

Map<String, String> params = new HashMap<>();
params.put("level", "10");
params.put("score", "15000");
OEGAnalytics.INSTANCE.logEvent("level_up", params);

Log a revenue event​

Events that carry money — Recharge (web_store / WebPay top-ups), first_recharge, or any custom revenue event — must set the real revenue with logRevenue. Sending the amount only as a plain parameter (e.g. charged_value) is not counted by either provider — the dashboard would show 0.

Native IAP is automatic

The native Google Play IAP flow fires sdk_recharge with revenue already set — no game code needed. Use logRevenue only for events the game pushes itself (web_store / WebPay recharges and custom revenue events).

For Adjust, the revenue is attached to the event's own token, so that event must be set up as a revenue event by your game operator. For AppsFlyer, sdk_recharge additionally and automatically derives AppsFlyer's predefined purchase event from the same call — no separate setup step. orderId deduplicates against double-counting for both providers.

Kotlin
import vn.oeg.sdk.v2.core.analytics.OEGAnalytics

OEGAnalytics.logRevenue(
"Recharge", // event name set up as a revenue event by your operator
revenue = 99000.0, // real amount paid (must be > 0)
currency = "VND", // ISO 4217
orderId = "order_12345", // dedup id
parameters = mapOf("payment_channel" to "web_store", "product_id" to "vip_pack_1")
)
Java
import vn.oeg.sdk.v2.core.analytics.OEGAnalytics;
import java.util.HashMap;
import java.util.Map;

Map<String, String> params = new HashMap<>();
params.put("payment_channel", "web_store");
params.put("product_id", "vip_pack_1");

// logRevenue(eventNameOrToken, revenue, currency, orderId, parameters)
OEGAnalytics.INSTANCE.logRevenue("Recharge", 99000.0, "VND", "order_12345", params);

A recharge is a revenue event — always send it via logRevenue, not the plain logEvent, otherwise the active provider records no revenue.

Enable / disable tracking​

setTrackingEnabled(false) stops tracking with whichever provider is active (Adjust's or AppsFlyer's own opt-out mechanism); true resumes it.

Kotlin
OEGAnalytics.setTrackingEnabled(false)
OEGAnalytics.setTrackingEnabled(true)
Java
OEGAnalytics.INSTANCE.setTrackingEnabled(false);
OEGAnalytics.INSTANCE.setTrackingEnabled(true);

Uninstall Tracking​

Uninstall tracking is automatic — no game code required. When the FCM token is obtained or rotated, the SDK forwards it to whichever attribution provider is active (Adjust or AppsFlyer). That provider then periodically sends a silent push to each device; if delivery fails, the device is counted as an uninstall.

Requirements:

  • FCM must be configured (see Push Notifications)
  • OEGNotificationService declared in AndroidManifest.xml
  • Provider app token / dev key configured by your operator

Android has no App Tracking Transparency equivalent — there is no prompt to wait for, and the AppsFlyer tracker starts as soon as it is configured (unlike iOS, see iOS: App Tracking Transparency).

To attribute re-engagement campaigns (user taps an attribution link while the app is already installed), call OEGAnalytics.processDeeplink() from your main Activity — the same call for either provider, no new API. Install attribution works regardless — this is only needed to credit campaigns that bring back existing users. The SDK logs AppsFlyer's conversion/deep-link callback internally; it does not navigate anywhere in your game — routing a link to in-game content is your game's responsibility.

Kotlin
import android.content.Intent
import vn.oeg.sdk.v2.core.analytics.OEGAnalytics

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
intent?.data?.let { OEGAnalytics.processDeeplink(it, this) }
}

override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
intent.data?.let { OEGAnalytics.processDeeplink(it, this) }
}
}
Java
import android.content.Intent;
import vn.oeg.sdk.v2.core.analytics.OEGAnalytics;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getIntent() != null && getIntent().getData() != null) {
OEGAnalytics.INSTANCE.processDeeplink(getIntent().getData(), this);
}
}

@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (intent != null && intent.getData() != null) {
OEGAnalytics.INSTANCE.processDeeplink(intent.getData(), this);
}
}

Lifecycle​

Call in your main game Activity:

Kotlin
override fun onResume() {
super.onResume()
OEGAnalytics.onResume()
}

override fun onPause() {
super.onPause()
OEGAnalytics.onPause()
}
Java
@Override
public void onResume() {
super.onResume();
OEGAnalytics.INSTANCE.onResume();
}

@Override
public void onPause() {
super.onPause();
OEGAnalytics.INSTANCE.onPause();
}

Privacy Disclosure Requirements​

This section applies only when AppsFlyer is the selected attribution provider for your game. If your game uses Adjust, nothing here changes what you already declare.

Adding AppsFlyer to your app is a data-collection change, not just a code change — it changes what you owe in your Google Play Data Safety form, and it changes what your game's own privacy policy needs to say. This is on your game's Play Console listing; the SDK cannot fill it in for you.

Identifiers AppsFlyer collects, consistent with what the SDK already sends to Adjust today (no new category of data is introduced — same class of identifiers, different vendor):

  • Advertising / device identifiers used for attribution — the Google Advertising ID (or AppsFlyer's own SDK-generated install identifier where GAID is unavailable).
  • Your app's own user id, when you have one — the SDK sets AppsFlyer's customer user id from the same account_id your game already sends to Adjust and to the Alogame backend. No new identifier is introduced; it is the same value routed to one more place.
  • Push token — the FCM token, forwarded for uninstall measurement (see Uninstall Tracking above), the same token already sent to Adjust today for the same purpose.
  • Standard network/request metadata (IP address, device model, OS version) inherent to any SDK that makes HTTP calls — the same category Adjust already collects.

The SDK never sends email, phone number, or other direct PII to AppsFlyer — nothing beyond what it already sends to your existing providers.

Verify against AppsFlyer's current official guidance before submitting

The exact checkbox-level categories Google Play's Data Safety form expects are AppsFlyer's to define and can change as Google's own taxonomy evolves. Do not fill in your app's form from this page alone — cross-check against AppsFlyer's own current guidance:

Whoever owns your Play Console listing (not necessarily the SDK integrator) should complete this before the release that adds AppsFlyer ships — an inaccurate Data Safety declaration is a policy violation independent of whether the SDK code is correct.