Android Usage
This page explains how to use Context Decision to calibrate your custom model, and how to make decisions based on the predictions.
- Step 1: Add ContextSDK to your app
- Step 2: Ship app into production in Calibration Mode
- Step 3: Once the model is ready, you can start making decisions based on the SDK's predictions
Usage
- Use a different, unique
flowName
for each upsell funnel (e.g.upsell_prompt
,upsell_onboarding
, etc.)- If you have the same purchase flow, but from different parts of your app, please use different a different
flowName
for each. - We automatically analyze the overlap between different flows, to decide if there should be one, or more models.
- If you have the same purchase flow, but from different parts of your app, please use different a different
- The timing is crucial: You need to create the
context
object right before showing your prompt, and then log the outcome of the user interaction after the user has either accepted or dismissed the prompt. - For each
context
object you create, be sure to log an outcome, even if the user dismisses the prompt.
We recommend using this approach for most apps, unless you have a specific reason to use the advanced methods.
In most cases, ContextSDK will execute your block instantly. Only if your app was recently launched, or resumed from the background, it will take up to a few seconds to get a full context.
It's critical you trigger your prompt inside the block, which behaves as follows:
- The callback is instantly executed if your app has been running for at least 3 seconds
- The callback being executed within 3 seconds if your app was just put into the foreground recently
Use Instant Callbacks if you want to show a prompt right after a user action (e.g. opening a screen)
There are cases where you may prefer to always instantly have your callback executed. For example, when you want to show a prompt right after a certain user-action, to prevent the prompt showing up when the user already left the screen.
Using maxDelayS = 0
means that the context
object may not be complete, which may reduce data quality. We recommend not using this approach right after the app start. Use in places where the app usually has already been running for a few seconds.
If you want full control, you can use the instantContext
method to get a Context
object instantly. This comes with some extra complexity, as you also need to check the .shouldUpsell
property yourself to decide if you should show the prompt or not.
val context = ContextSDK.instantContext("upsell", durationS = 3)
if (context.shouldUpsell) {
// [Show the upgrade prompt here right after fetching the context]
// Once you know if the user purchased or dismissed the upsell, log the outcome:
context.log(EventOutcome.POSITIVE) // or EventOutcome.NEGATIVE
} else{
context.log(EventOutcome.SKIPPED)
}
RealWorldContext context = ContextSDK.Companion.instantContext("upsell", 3, null);
if (context.getShouldUpsell()) {
// [Show the upgrade prompt here right after fetching the context]
// Once you know if the user purchased or dismissed the upsell, log the outcome:
context.log(EventOutcome.POSITIVE); // or EventOutcome.NEGATIVE
} else{
context.log(EventOutcome.SKIPPED);
}
During calibration phase, .shouldUpsell
will always be true
, so your app's behavior won't change. Once your custom model is rolled out, the .shouldUpsell
property will reflect the prediction of your model.
Helpers
Some apps may not have an easy way to pass the context
object from where you initially generate it, to where you know the outcome of the user interaction. In those cases, you can use the recentContext
method to get the most recent context
object you created based on the unique flowName
.
- This approach requires you to create the
context
object first. - Only the most recent
context
for eachflowName
name will be stored, and oldercontext
objects will be discarded. - The
context
object must already be created before you show the prompt.
You can provide additional outcome details, for example to indicate which type of product the user has purchased.
ContextSDK.optimize("show_all_deals") { context ->
// [Show the user a list of deals]
val selectedDeal = user.selectedDeal
if (selectedDeal != null) {
context.outcomeMetadata["deal_selected"] = selectedDeal.number
context.outcomeMetadata["deal_value_in_usd"] = selectedDeal.usdValue
context.log(EventOutcome.POSITIVE)
} else {
context.log(EventOutcome.NEGATIVE)
}
}
ContextSDK.Companion.optimize("show_all_deals", null, null, context -> {
// [Show the user a list of deals]
Deal selectedDeal = user.selectedDeal;
if (selectedDeal != null) {
context.getOutcomeMetadata().set("deal_selected",selectedDeal.number);
context.getOutcomeMetadata().set("deal_value_in_usd", selectedDeal.usdValue);
context.log(EventOutcome.POSITIVE);
} else {
context.log(EventOutcome.NEGATIVE);
}
return Unit.INSTANCE;
});
The information provided via the outcomeMetadata
will not be used to determine if it's currently a good moment, you can use Custom Signals for that.
The information provided is used to help you decide on variants. For example, you may have different types of offers, or different price points, and you want to train ContextSDK to recommend the best one based on the current user context.
Custom Signals
ContextSDK uses more than 200 signals based on various built-in sensors to make its predictions. However, you can improve its performance by providing additional data to the ContextSDK that's specific to your app. Some examples of what you could provide: In-game progress, number of friends/messages, number of entries in a list, etc.
Global signals will be used across all ContextSDK calls, and are an easy way to provide additional data to the ContextSDK.
You can easily override the global custom signals by providing the same key
again using a different value. To remove a global custom signal, call the globalCustomSignals
method with a null
value.
In general, we recommend using global signals. But if have custom signals that are specific to a certain flow, you can provide them as a parameter when getting your context
object:
Please be sure to consider the user's privacy and don't include any sensitive data. You are responsible for ensuring that you have the necessary rights to provide the data to us. Please at no point include any PII (including but not limited to emails, user IDs, IP addresses, exact locations, etc.) in your custom signals.