Skip to main content

Event Tracking

GameAnalytics features the following event types:

EventDescription
AdAds shown and clicked, fill rate.
BusinessIn-App Purchases supporting receipt validation on GA servers.
DesignSubmit custom event id’s. Useful for tracking metrics specifically needed for your game.
ErrorSubmit exception stack traces or custom error messages.
HealthAutomatically submits health metrics related to your game such as FPS.
ImpressionImpression data from different ad networks
ProgressionLevel attempts with Start, Fail & Complete event.
ResourceManaging the flow of virtual currencies - like gems or lives
tip

Read more about events here

Business Events​

Used for tracking real-money in-app purchases (IAP).

info

Some configuration is needed before receipt validation will be active. Read information about validation and requirements for different platforms here.

There are two ways to send a validated business event:

  • IAP Validation (SDK 7.2.0 and later): pass the store, product ID and purchase token in a ReceiptInfo object.
  • Legacy: pass the raw receipt and its signature.
FieldTypeDescriptionExample
currencystringCurrency code in ISO 4217 formatUSD
amountintegerAmount in cents99 is $0.99
itemTypestringThe type/category of the itemGoldPacks
itemIdstringSpecific item bought1000GoldPack
cartTypestringThe game location of the purchase. Max 10 unique valuesEndOfLevel
receiptInfoReceiptInfoReceipt of the store purchase. Cannot be nullReceiptInfo.googlePlay(productId, purchaseToken)

Create the ReceiptInfo with ReceiptInfo.googlePlay(productId, purchaseToken):

FieldTypeDescription
productIdstringThe product ID of the purchased item. Cannot be empty
purchaseTokenstringThe purchase token returned by Google Play for this purchase. Cannot be empty

Add a business event when an in-app purchase is completed:

import com.gameanalytics.sdk.events.ReceiptInfo;

ReceiptInfo receiptInfo = ReceiptInfo.googlePlay("[productId]", "[purchaseToken]");

GameAnalytics.addBusinessEvent("USD", 1000, "item", "id", "cart", receiptInfo);
caution

The SDK validates receiptInfo before sending the event. If it is null, or the product ID or purchase token is empty, the event is not sent. To track a purchase without a receipt, use GameAnalytics.addBusinessEvent("USD", 1000, "item", "id", "cart");.

Custom Event Fields​

HashMap<String, Object> fields = new HashMap<>();
fields.put("test", 100);
fields.put("test_2", "hello_world");

ReceiptInfo receiptInfo = ReceiptInfo.googlePlay("[productId]", "[purchaseToken]");

GameAnalytics.addBusinessEvent("USD", 1000, "item", "id", "cart", receiptInfo, fields);
tip

Find more information on Custom Event Fields and Data Export following the links.

tip

For more information on Business Events go here.

Ad Events​

The GameAnalytics ad event should be called when certain ad SDK events occur (show, click, reward, fail).

The ad SDK name argument must be all lower-case with no spaces or underscores. Examples of valid values:

  • admob
  • unityads
  • ironsource
  • applovin

Rewarded Video​

Showing a Rewarded Video​

Track if an ad fails to show:

if (rewardedVideoAd != null && rewardedVideoAd.isLoaded()) {
rewardedVideoAd.show();
}
else
{
GameAnalytics.addAdEvent(GAAdAction.FailedShow, GAAdType.RewardedVideo, "admob", "[AD_PLACEMENT_OR_UNIT_ID]");
}

Track Time Spent​

Track how long the user watched by starting a timer when the ad opens:

@Override
public void onRewardedVideoAdOpened() {
currentRewardedVideoPlacement = "[AD_PLACEMENT_OR_UNIT_ID]";
GameAnalytics.startTimer(currentRewardedVideoPlacement);
}

@Override
public void onPause() {
if(currentRewardedVideoPlacement != null)
{
GameAnalytics.pauseTimer(currentRewardedVideoPlacement);
}
}

@Override
public void onResume() {
if(currentRewardedVideoPlacement != null)
{
GameAnalytics.resumeTimer(currentRewardedVideoPlacement);
}
}

Tracking Ad Rewards​

@Override
public void onRewarded(RewardItem reward) {
GameAnalytics.addAdEvent(GAAdAction.RewardReceived, GAAdType.RewardedVideo, "admob", "[AD_PLACEMENT_OR_UNIT_ID]");
}

Tracking Successful Ads​

@Override
public void onRewardedVideoAdClosed() {
if(currentRewardedVideoPlacement != null)
{
long elapsedTime = GameAnalytics.stopTimer(currentRewardedVideoPlacement);
GameAnalytics.addAdEvent(GAAdAction.Show, GAAdType.RewardedVideo, "admob", "[AD_PLACEMENT_OR_UNIT_ID]", elapsedTime);
currentRewardedVideoPlacement = null;
}
}

Interstitial​

if (interstitialAd != null && interstitialAd.isLoaded()) {
interstitialAd.show();
GameAnalytics.addAdEvent(GAAdAction.Show, GAAdType.Interstitial,"admob", "[AD_PLACEMENT_OR_UNIT_ID]");
}
else
{
GameAnalytics.addAdEvent(GAAdAction.FailedShow, GAAdType.Interstitial, "admob", "[AD_PLACEMENT_OR_UNIT_ID]");
}
if (bannerAd != null && bannerAd.isLoaded()) {
bannerAd.show();
GameAnalytics.addAdEvent(GAAdAction.Show, GAAdType.Banner,"admob", "[AD_PLACEMENT_OR_UNIT_ID]");
}
else
{
GameAnalytics.addAdEvent(GAAdAction.FailedShow, GAAdType.Banner, "admob", "[AD_PLACEMENT_OR_UNIT_ID]");
}

Ad Event Fields​

FieldTypeDescriptionExample
adActionenumA defined enum for ad actionGAAdAction.Clicked
GAAdAction.Show
GAAdAction.FailedShow
GAAdAction.RewardReceived
adTypeenumA defined enum for ad typeGAAdType.Video
GAAdType.RewardedVideo
GAAdType.Playable
GAAdType.Interstitial
GAAdType.OfferWall
GAAdType.Banner
adSdkNamestringName of the Ad/Ad mediation SDKadmob
adPlacementstringIdentifier of ad placement in the gamelevel_complete_ad
durationintOptional. Only used for video ads to track watch time10
noAdReasonenumOptional. Reason for not being able to show an adGAAdError.Unknown
GAAdError.Offline
GAAdError.NoFill
GAAdError.InternalError
tip

For more information on Ad Events go here.

Impression Events​

Impression events capture ad impression data from ad networks. Supported networks:

  • Fyber
  • IronSource
  • TopOn
  • MAX
  • Aequus
  • AdMob

IronSource​

protected void onCreate(Bundle savedInstanceState)
{
IronSource.setImpressionDataListener(new ImpressionDataListener()
{
@Override
public void onImpressionSuccess(ImpressionData impressionData)
{
GameAnalytics.addImpressionIronSourceEvent(IronSourceUtils.getSDKVersion(), impressionData.getAllData());
}
});
}

MAX​

protected void onCreate(Bundle savedInstanceState)
{
maxInterstitial.setAdListener(new MaxAdListener()
{
@Override
public void onAdDisplayed(MaxAd ad)
{
JSONObject json = new JSONObject();
try
{
json.put("country", AppLovinSdk.getInstance(referenceToActivity).getConfiguration().getCountryCode());
json.put("network_name", ad.getNetworkName());
json.put("adunit_id", ad.getAdUnitId());
json.put("adunit_format", ad.getFormat().getLabel());
json.put("placement", ad.getPlacement());
json.put("creative_id", ad.getCreativeId());
json.put("revenue", ad.getRevenue());
}
catch(JSONException e)
{
}
GameAnalytics.addImpressionMaxEvent( AppLovinSdk.VERSION, json);
}
});
}

Custom Impression Event Fields​

HashMap<String, Object> fields = new HashMap<>();
fields.put("test", 100);
fields.put("test_2", "hello_world");

GameAnalytics.addImpressionEvent([adNetworkName], [adNetworkVersion], [impressionData], fields);
tip

Find more information on Custom Event Fields and Data Export following the links.

tip

For more information on Impression Events go here.

Resource Events​

Used to track the flow of virtual currencies — the sink (subtract) and source (add) for each currency.

caution

Before calling the resource event, specify what currencies and item types can be used in the Configuration phase.

FieldTypeRequiredDescription
flowTypeenumyesAdd (source) or subtract (sink) resource
currencystringyesOne of the available currencies set in configuration. This string can only contain [A-Za-z] characters.
amountfloatyesAmount sourced or sunk
itemTypestringyesOne of the available item types
itemIdstringyesItem id (string max length = 32)
GameAnalytics.addResourceEventWithFlowType(GAResourceFlowType.Source, "Gems", 400, "IAP", "Coins400");

// sink (subtract) Gem currency to buy an item.

GameAnalytics.addResourceEventWithFlowType(GAResourceFlowType.Sink, "Gems", 400, "Weapons", "SwordOfFire");

Custom Resource Event Fields​

HashMap<String, Object> fields = new HashMap<>();
fields.put("test", 100);
fields.put("test_2", "hello_world");

GameAnalytics.addResourceEventWithFlowType(GAResourceFlowType.Sink, "BeamBooster", 3, "Gameplay", "BeamBooster5Pack", fields);
danger

Be careful to not call the resource event too often! Count collected resources and send a single Source event when the level completes or fails.

tip

For more information on Resource Events go here.

Progression Events​

Used to track player progression through a 3-tier hierarchy (e.g. world:stage:level).

FieldTypeRequiredDescription
progressionStatusenumyesStart, Complete or Fail
progression01stringyes1st progression (e.g. world01)
progression02stringno2nd progression (e.g. level01)
progression03stringno3rd progression (e.g. phase01)
scoreintnoThe player's score

Add a progression start event:

GameAnalytics.addProgressionEventWithProgressionStatus(GAProgressionStatus.Start, "world01", "stage01", "level01");

Not all 3 tiers are required:

  • progression01 only
  • progression01 and progression02
  • progression01, progression02, and progression03

Custom Progression Event Fields​

HashMap<String, Object> fields = new HashMap<>();
fields.put("test", 100);
fields.put("test_2", "hello_world");

GameAnalytics.addResourceEventWithFlowType(GAResourceFlowType.Sink, "BeamBooster", 3, "Gameplay", "BeamBooster5Pack", fields);
tip

For more information on Progression Events go here.

Error Events​

Used to send manual error reports to GameAnalytics.

FieldTypeRequiredDescription
severityenumyesGAErrorSeverity.GAErrorSeverityDebug
GAErrorSeverity.GAErrorSeverityInfo
GAErrorSeverity.GAErrorSeverityWarning
GAErrorSeverity.GAErrorSeverityError
GAErrorSeverity.GAErrorSeverityCritical
messagestringnoCustom error message
GameAnalytics.addErrorEventWithSeverity(GAErrorSeverity.GAErrorSeverityDebug, "Something went bad in some of the smelly code!");

Custom Error Event Fields​

HashMap<String, Object> fields = new HashMap<>();
fields.put("test", 100);
fields.put("test_2", "hello_world");

GameAnalytics.addErrorEventWithSeverity(GAErrorSeverity.GAErrorSeverityDebug, "Something went bad in some of the smelly code!", fields);

Design Events​

Custom events that allow for a 5-part event ID hierarchy separated by colons.

FieldTypeRequiredDescription
eventIdstringyesEvent ID (up to 5 parts separated by :, max 64 chars each)
valuefloatnoOptional numeric value
GameAnalytics.addDesignEventWithEventId("Kill:Sword:Robot");

Optionally attach a float value:

GameAnalytics.addDesignEventWithEventId("BossFights:FireLord:KillTimeUsed", 234);

Custom Design Event Fields​

HashMap<String, Object> fields = new HashMap<>();
fields.put("test", 100);
fields.put("test_2", "hello_world");

GameAnalytics.addDesignEventWithEventId("BossFights:FireLord:KillTimeUsed", 234, fields);
caution

Do not generate an excessive number of unique event hierarchy nodes. A maximum of around 10k unique nodes should be the limit. Use the value field for numeric data rather than embedding it in the event string.

tip

For more information on Design Events go here.