Working with Teak on Android
Identify User
This tells Teak how the user should be referenced in the Teak system.
All Teak events will be delayed until identifyUser is called.
void io.teak.sdk.Teak.identifyUser(final String userIdentifier,
final UserConfiguration userConfiguration);
| This should be the same way that you identify the user in your system, so that when you export data from Teak, it will be easy for you to associate with your own data. |
Player Configuration
Pass a Teak.UserConfiguration to identifyUser to provide additional player data and to control what Teak collects:
-
email— the player’s email address, used for sending email. -
facebookId— the player’s Facebook ID, used for templating their name into content. -
optOutIDFA— settrueto opt the player out of advertising-identifier collection. -
optOutPushKey— settrueto opt the player out of push-token collection. -
optOutFacebook— deprecated; see SDK 5 Behaviors. Don’t pass afacebookIdinstead.
// email, facebookId, optOutFacebook (deprecated, always false), optOutIDFA, optOutPushKey
Teak.UserConfiguration userConfiguration =
new Teak.UserConfiguration(YOUR_USER_EMAIL, YOUR_USER_FACEBOOK_ID, false, true, false);
Teak.identifyUser(YOUR_USER_ID, userConfiguration);
If a player has opted out of all data collection, don’t call identifyUser at all, and Teak won’t track them.
Logout
When a player logs out of your game, tell Teak with logout. This is a client-side call: it doesn’t clear the device’s association with the player, but it does stop Teak from associating any further events — like a notification click — with that player until you call identifyUser again.
void io.teak.sdk.Teak.logout();
If a player asks you to remove the email address you’ve collected for them, use:
void io.teak.sdk.Teak.deleteEmail();
User Attributes
Teak allows you to add a limited number of attributes to users. A maximum of 16 string and 16 numeric attributes can be used.
void io.teak.sdk.Teak.setNumericAttribute(final String attributeName,
final double attributeValue);
void io.teak.sdk.Teak.setStringAttribute(final String attributeName,
final String attributeValue);
Custom Analytics Events
You can send custom analytics events to Teak to track player behavior. Teak models an event as an action taken on a type of object, optionally with a specific instance of that object.
void io.teak.sdk.Teak.trackEvent(final String actionId,
final String objectTypeId,
final String objectInstanceId);
For example, to track that a player completed level 10:
Teak.trackEvent("level_complete", "level", "10");
To keep a running count for an event, use incrementEvent:
void io.teak.sdk.Teak.incrementEvent(final String actionId,
final String objectTypeId,
final String objectInstanceId,
final long count);
Teak.incrementEvent("coins_spent", "store", "gems", 50);
Notification Permissions
On Android 13 (API level 33) and newer, you must ask the player before you can send them push notifications, using Android’s standard runtime permission APIs. On older versions, permission is granted automatically.
The quickstart shows requesting permission at launch to get you up and running. In production, ask at a moment that makes sense for your game; being strategic about when you ask improves your opt-in rates.
To find out whether notifications are currently enabled, check the status:
int io.teak.sdk.Teak.getNotificationStatus();
It returns one of Teak.TEAK_NOTIFICATIONS_ENABLED, Teak.TEAK_NOTIFICATIONS_DISABLED, or Teak.TEAK_NOTIFICATIONS_UNKNOWN.
Prompting a Player to Re-enable Notifications
If a player has turned notifications off, you can no longer prompt them from within the app. Instead, you can send them to the system settings, where they can turn notifications back on.
boolean io.teak.sdk.Teak.canOpenNotificationSettings();
boolean io.teak.sdk.Teak.openNotificationSettings();
Application Badge Count
A dashboard notification can only set your app icon’s badge to no badge or 1. To show your own count — for example, an in-game unread count — call setApplicationBadgeNumber yourself.
boolean io.teak.sdk.Teak.setApplicationBadgeNumber(int count);
Badge support depends on the device’s launcher. The call returns false if the current launcher does not support badges. On Android, a badge is fundamentally set-or-not-set rather than numbered — most launchers show only a dot regardless of the count you pass, though some show the number.
|
Deep Links
Teak can open your game from a URL, whether the link comes from a notification or from a link you created on the Teak dashboard. To enable this, register Teak’s URL schemes in your Android manifest.
Add the following to the <activity> section of your AndroidManifest.xml:
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" android:host="YOUR_SHORTLINK_DOMAIN.jckpt.me" />
<data android:scheme="https" android:host="YOUR_SHORTLINK_DOMAIN.jckpt.me" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="teakYOUR_TEAK_APP_ID" android:host="*" />
</intent-filter>
Replace YOUR_TEAK_APP_ID with your Teak App Id and YOUR_SHORTLINK_DOMAIN with your Teak ShortLink Domain. Both are found in the Settings for your app on the Teak dashboard.
|
This tells Android to look for deep link URLs created by Teak.
Subscribing to Events
Teak uses EventBus to send events to your game.
Register an Object to Handle Events
You can register any object to handle events posted by Teak. A quick way to get started is to register your main activity as a handler:
import androidx.appcompat.app.AppCompatActivity;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Register with EventBus
EventBus.getDefault().register(this);
}
To receive events, declare methods with the @Subscribe annotation that take the type of event the method should handle.
Events
- Teak.NotificationEvent
-
A notification has been received.
- Teak.RewardClaimEvent
-
A reward claim has been processed. See Rewards.
- Teak.LaunchFromLinkEvent
-
The app was launched from a URL created on the Teak dashboard.
- Teak.PostLaunchSummaryEvent
-
Attribution data for the launch is available. See Session Attribution.
- Teak.UserDataEvent
-
Data about the user has become available, or has been updated.
Rewards
Teak notifications and links can grant rewards to your players. When a player opens your game from a rewarded notification or link, Teak validates the claim with the server and posts a Teak.RewardClaimEvent with the result.
Subscribe to it the same way as any other event (see Subscribing to Events), then grant the reward in your game when the claim succeeds.
@Subscribe
public void onRewardClaim(Teak.RewardClaimEvent event) {
TeakNotification.Reward rewardInfo = event.reward;
String rewardId = rewardInfo.json.getString("teakRewardId");
switch(rewardInfo.status) {
case TeakNotification.Reward.GRANT_REWARD: {
Map<String, Object> reward = rewardInfo.json.getJSONObject("reward").toMap();
Log.d("TeakExample.Reward", "Reward with id " + rewardId + "Granted! " + reward.toString());
} break;
case TeakNotification.Reward.ALREADY_CLICKED: {
Log.d("TeakExample.Reward", "You already claimed this reward!");
} break;
case TeakNotification.Reward.EXPIRED: {
Log.d("TeakExample.Reward", "The reward has expired");
} break;
case TeakNotification.Reward.TOO_MANY_CLICKS: {
Log.d("TeakExample.Reward", "Too many other players already claimed this reward");
} break;
case TeakNotification.Reward.EXCEED_MAX_CLICKS_FOR_DAY: {
Log.d("TeakExample.Reward", "You've already claimed too many rewards today");
} break;
default: {
Log.d("TeakExample.Reward", "The reward was rejected for a different reason: " + rewardInfo.json.getString("status"));
}
}
}
The status field reports the outcome of the claim:
| Status | Meaning |
|---|---|
|
The reward was granted. Apply it in your game. |
|
The player clicked their own shared link, so no reward was granted. |
|
The player already claimed this reward. |
|
The reward’s click limit has been reached. |
|
The player has already claimed the maximum number of rewards for the day. |
|
The reward has expired. |
|
The claim was invalid. |
Session Attribution
Each time your game launches, Teak posts a Teak.PostLaunchSummaryEvent with all the attribution data it has for that launch. This fires after you call identifyUser, and is primarily intended to help you report session attribution to other analytics systems.
Subscribe to it like any other event (see Subscribing to Events). The event’s launchData is a Teak.LaunchData. When the launch is attributed to a Teak source, it is a Teak.AttributedLaunchData carrying the channel, creative, schedule, reward, and deep link details.
@Subscribe
public void onPostLaunchSummary(Teak.PostLaunchSummaryEvent event) {
Teak.LaunchData launchData = event.launchData;
if (launchData instanceof Teak.AttributedLaunchData) {
Teak.AttributedLaunchData attributed = (Teak.AttributedLaunchData) launchData;
Log.d("Teak.Attribution", "Launch attributed to channel: " + attributed.channelName);
Log.d("Teak.Attribution", "From creative: " + attributed.creativeName);
Log.d("Teak.Attribution", "Rewarded: " + attributed.isIncentivized());
} else {
Log.d("Teak.Attribution", "Launch was not attributed to a Teak source.");
}
}
Local Notifications
Local Notifications let you schedule push notifications directly from your game code for the current player. This differs from standard notifications, which your marketing team schedules for delivery from the Teak dashboard.
Use Local Notifications when the timing or personalization is something your game code is best positioned to determine. The notification’s content is still created on the Teak dashboard, so coordinate with your marketing team and document when your game schedules them.
| Don’t use Local Notifications for new-player or lapsing-player flows. Your marketing team should create Triggered Schedules for those instead. |
Schedule a Notification
Schedule a notification by the identifier of a creative on the Teak dashboard and a delay in seconds. The call returns a Future carrying a Teak.Notification.Reply, whose scheduleIds you can keep if you later want to cancel it.
import io.teak.sdk.Teak;
import java.util.concurrent.Future;
// Schedule the "daily_bonus" creative to fire one hour from now.
Future<Teak.Notification.Reply> scheduled =
Teak.Notification.schedule("daily_bonus", 3600);
To template custom data into the notification, pass a personalizationData map. Tell your marketing team which keys you send so they can configure the matching Local Notification Tags.
Map<String, Object> personalizationData = new HashMap<>();
personalizationData.put("coins", 100);
Future<Teak.Notification.Reply> scheduled =
Teak.Notification.schedule("daily_bonus", 3600, personalizationData);
Cancel a Scheduled Notification
Cancel a single scheduled notification with a schedule id from the reply, or cancel all of the current player’s scheduled notifications. Note that cancellation is on TeakNotification, not Teak.Notification.
FutureTask<String> io.teak.sdk.TeakNotification.cancelNotification(final String scheduleId);
FutureTask<String> io.teak.sdk.TeakNotification.cancelAll();
Notification Channels and Opt-Out Preferences
Teak can reach players over several channels: mobile push, desktop push, email, and SMS. Each channel, and each category within a channel, has an opt-in state. You can read a player’s current preferences and update them from your game, for example to build an in-game notification-settings screen.
Reading Opt-Out Preferences
A player’s channel preferences arrive in the Teak.UserDataEvent, which Teak posts when player data becomes available or changes. Subscribe to it (see Subscribing to Events) and read the per-channel status.
@Subscribe
public void onUserData(Teak.UserDataEvent event) {
Teak.Channel.State pushState = event.pushStatus.state;
Teak.Channel.State emailState = event.emailStatus.state;
Teak.Channel.State smsState = event.smsStatus.state;
Log.d("Teak.Channels", "Push opt-in state: " + pushState);
}
Each status’s state is one of OptOut, Available, OptIn, Absent, or Unknown.
Updating Opt-Out Preferences
Update an entire channel with setChannelState, or a single category within a channel with setCategoryState.
Future<Channel.Reply> io.teak.sdk.Teak.setChannelState(final Channel.Type channel,
final Channel.State state);
Future<Channel.Reply> io.teak.sdk.Teak.setCategoryState(final Channel.Type channel,
final String category,
final Channel.State state);
The channel is one of Teak.Channel.Type.MobilePush, DesktopPush, PlatformPush, Email, or SMS, and the state is typically OptIn or OptOut.
// Opt the player out of marketing emails.
Teak.setChannelState(Teak.Channel.Type.Email, Teak.Channel.State.OptOut);
// Opt the player in to a specific push category.
Teak.setCategoryState(Teak.Channel.Type.MobilePush, "daily_reminders", Teak.Channel.State.OptIn);
Debugging with a Log Listener
Teak emits internal log events as it runs. You can observe them by registering a Teak.LogListener, which is useful for debugging your integration or forwarding Teak’s diagnostics into your own logging system.
void io.teak.sdk.Teak.setLogListener(LogListener logListener);
Teak.setLogListener(new Teak.LogListener() {
@Override
public void logEvent(String logEvent, String logLevel, Map<String, Object> logData) {
Log.d("Teak.Log", logLevel + " " + logEvent + " " + logData);
}
});