API reference
Every public type, property and method in the Grovs Android SDK 3.1.
Members are on the Grovs companion object, so Kotlin calls them as Grovs.configure(...) and Java as Grovs.Companion.configure(...). Push helpers for your own messaging service are on GrovsMessaging. Every method works from any thread.
At a glance
| Area | Member | Kind | What it does |
|---|---|---|---|
| Setup | configure | method | Configures and authenticates the SDK |
setSDK | method | Turns collection on or off | |
setDebug | method | Sets the log level | |
| Deep links | onStart | method | Resolves the launch link |
onNewIntent | method | Resolves links while running | |
setOnDeeplinkReceivedListener | method | Registers the deep link listener | |
openedLinkDetails | property | Last link that opened the app | |
| Users | identifier | property | Your ID for the current user |
attributes | property | Attributes of the current user | |
| Links | generateLink | method | Creates a smart link |
linkDetails | method | Details of a link by path | |
| Events | track | method | Tracks a custom event |
trackScreenView | method | Tracks a screen view | |
trackNavigation | method | Tracks Jetpack Navigation destinations | |
setGlobalTags | method | Tags added to every event | |
setScreenAliases | method | Renames screens for the dashboard | |
| Revenue | logInAppPurchase | method | Logs a Google Play purchase |
logCustomPurchase | method | Logs a purchase outside Google Play | |
| Push notifications | pushToken | property | FCM token for push campaigns |
handleNotificationOpen | method | Handles a tap intent the launcher didn't get | |
isGrovsNotification | method | Checks if Grovs sent a push | |
GrovsMessaging | class | Calls for your own messaging service | |
MessagingService | class | The SDK's messaging service | |
| In-app messages | setInAppListener | method | Receives in-app message events |
pauseInAppMessages | method | Holds messages back | |
resumeInAppMessages | method | Lets messages show again | |
discardInAppMessages | method | Drops waiting messages | |
setInAppExcludedScreens | method | Screens where no message shows | |
setInAppDebugLogging | method | Logs why campaigns were skipped | |
| Types | DeeplinkDetails | class | A resolved deep link |
GrovsDeeplinkListener | interface | Deep link callback | |
GrovsLinkGenerationListener | interface | generateLink callback | |
GrovsLinkDetailsListener | interface | linkDetails callback | |
GrovsInAppListener | interface | In-app message callbacks | |
GrovsInAppListenerAdapter | class | GrovsInAppListener for Java | |
GrovsException | class | Link and SDK failures | |
GrovsErrorCode | enum | Failure categories | |
TrackingParams | class | UTM parameters | |
CustomRedirects | class | Per-platform link redirects | |
CustomLinkRedirect | class | One platform redirect | |
PaymentEventType | enum | Buy, cancel or refund | |
InstantCompat | class | Point in time for API 21 | |
LogLevel | enum | Log verbosity | |
| Deprecated | displayMessagesFragment | method | Shows nothing |
numberOfUnreadMessages | method | Always 0 | |
setOnAutomaticNotificationsListener | method | Never called | |
GrovsNotificationsListener | interface | Never called | |
handleGrovsNotification | method | Use GrovsMessaging.handleMessage |
Setup
configure
fun configure(application: Application, apiKey: String, useTestEnvironment: Boolean, baseURL: String? = null)
fun configure(application, apiKey, useTestEnvironment, baseURL, autoTrackScreenViews: Boolean)
fun configure(application, apiKey, useTestEnvironment, baseURL, autoTrackScreenViews, clipboardDomains: List<String>?)
fun configure(application, apiKey, useTestEnvironment, baseURL, autoTrackScreenViews, clipboardDomains, enabled: Boolean)Configures and authenticates the SDK. Call once per launch, in Application.onCreate().
| Name | Type | Description |
|---|---|---|
application | Application | Your Application instance. |
apiKey | String | Project API key from the Grovs dashboard. |
useTestEnvironment | Boolean | true targets the test environment, false production. |
baseURL | String? | Domain of a self-hosted backend, for example "https://sdk.example.com". The SDK appends the API path. null targets the Grovs cloud. |
autoTrackScreenViews | Boolean | Track Activity and Fragment screen views automatically. Defaults to true. |
clipboardDomains | List<String>? | Extra link hosts accepted by clipboard-assisted deferred deep linking, for example listOf("links.example.com"). Grovs-owned hosts are always accepted. |
enabled | Boolean | Whether the SDK may collect and send anything this launch. Defaults to true. |
- Calling it again replaces the previous configuration.
- Shorter overloads use
autoTrackScreenViews = true,clipboardDomains = nullandenabled = true. enabledisn't persisted. Pass your stored consent value every launch.
Calls made before configure:
| Calls | Effect |
|---|---|
Links passed to onStart or onNewIntent | Dropped, not held. Configure in Application.onCreate() so it runs before your launcher activity. |
| A Grovs push tap | Held (the latest one) and handled once configure runs |
identifier, attributes, pushToken | Kept and sent once the SDK authenticates |
setInAppListener and the other in-app calls | Kept, and survive later configure calls |
generateLink, linkDetails | Report a not-configured GrovsException |
track, trackScreenView, setGlobalTags, setScreenAliases | Ignored |
setSDK
fun setSDK(enabled: Boolean)Turns collection on or off at runtime, for example when consent changes. See Privacy & Consent.
- Call it only after
configure. - While disabled, the SDK doesn't authenticate, resolve the device, read the clipboard, or send events, screen views or purchases. Outstanding requests are cancelled.
- It holds
identifier,attributes,pushTokenand screen alias updates. Queued events stay on the device. - Disabling closes an in-app message on screen and drops unreported push opens.
- Enabling authenticates if needed and sends everything held.
setDebug
fun setDebug(level: LogLevel)Sets the log level. Default ERROR.
- Logs go through
android.util.Logwith tagLogger. Every message is prefixed🔗GROVS.
Deep links
See Deep Linking.
onStart
fun onStart(launcherActivity: Activity? = null)Forward from your launcher activity's onStart(). Required for the SDK to resolve the link the app was opened with.
onNewIntent
fun onNewIntent(intent: Intent?, launcherActivity: Activity? = null)Forward from your launcher activity's onNewIntent(). Required for links delivered while the app is running.
setOnDeeplinkReceivedListener
fun setOnDeeplinkReceivedListener(launcherActivity: Activity?, listener: GrovsDeeplinkListener)Registers the listener that gets DeeplinkDetails for every resolved link, including deferred links matched after install.
- Called on the main thread.
openedLinkDetails
val openedLinkDetails: DeeplinkDetails?The link the app was most recently opened from, or null.
- Observe it as a
StateFlowwithGrovs.Companion::openedLinkDetails.flow(importio.grovs.utils.flow). See Using Kotlin Flow.
Users
identifier
var identifier: String?Your identifier for the current user, typically your user_id. Shown in the dashboard and reports, and used to match test messages.
- Set before
configure, it's kept and sent once the SDK authenticates. - While the SDK is disabled, the latest value is held until it's enabled.
attributes
var attributes: Map<String, Any>?Attributes of the current user, shown in the dashboard. In-app campaigns can filter on them and personalize text with them.
- Set before
configure, they're kept and sent once the SDK authenticates. - Held while the SDK is disabled.
Links
Both methods come in a coroutine form and a callback form.
- The coroutine form resumes on the caller's dispatcher and throws
GrovsExceptionon failure. - The callback form runs the listener on the main thread. If the SDK isn't configured, or authentication is still retrying, the listener is called synchronously on the calling thread with a
GrovsException.
generateLink
suspend fun generateLink(
title: String? = null,
subtitle: String? = null,
imageURL: String? = null,
data: Map<String, Serializable>? = null,
tags: List<String>? = null,
customRedirects: CustomRedirects? = null,
showPreviewIos: Boolean? = null,
showPreviewAndroid: Boolean? = null,
copyToClipboardIos: Boolean? = null,
copyToClipboardAndroid: Boolean? = null,
tracking: TrackingParams? = null
): String
fun generateLink(
/* same parameters */,
lifecycleOwner: LifecycleOwner? = null,
listener: GrovsLinkGenerationListener
)Creates a smart link. See Link Creation.
| Name | Type | Description |
|---|---|---|
title | String? | Link preview title. |
subtitle | String? | Link preview subtitle. |
imageURL | String? | Link preview image URL. |
data | Map<String, Serializable>? | Custom payload delivered on deep link open. |
tags | List<String>? | Tags for filtering and analytics. |
customRedirects | CustomRedirects? | Per-platform redirect overrides. |
showPreviewIos | Boolean? | Show the preview page on iOS. null uses the project default. |
showPreviewAndroid | Boolean? | Show the preview page on Android. null uses the project default. |
copyToClipboardIos | Boolean? | Copy the link on the iOS preview page, for clipboard-assisted deferred deep linking. null uses the project setting. |
copyToClipboardAndroid | Boolean? | Same, for Android. |
tracking | TrackingParams? | UTM campaign, source and medium. |
lifecycleOwner | LifecycleOwner? | Callback form only. Scopes the callback to a lifecycle. |
listener | GrovsLinkGenerationListener | Callback form only. Gets the link or a GrovsException. |
Returns the URL (coroutine form).
linkDetails
suspend fun linkDetails(path: String): Map<String, Any>
fun linkDetails(path: String, lifecycleOwner: LifecycleOwner? = null, listener: GrovsLinkDetailsListener)Gets details for a link generated in the current environment, by path.
Returns the details (coroutine form). Failures throw, or reach the listener, as a GrovsException.
Events
track
fun track(name: String, properties: Map<String, Any>? = null, tags: List<String>? = null)Tracks a custom event.
- The name can't be blank or a reserved name. Rejected events are logged and dropped.
- Accepted events can trigger in-app messages.
- Property rules and limits: Tracking custom events.
trackScreenView
fun trackScreenView(screenName: String, properties: Map<String, Any>? = null)Tracks a screen view.
- A repeat of the same screen within one second is dropped.
trackNavigation
fun trackNavigation(navController: NavController)Tracks every destination change of a Jetpack Navigation NavController as a screen view. See Jetpack Navigation.
- Call once per controller. Repeat calls are ignored.
- Only a weak reference is kept.
setGlobalTags
fun setGlobalTags(tags: List<String>? = null)Sets tags merged onto every later event. Pass null to clear them.
setScreenAliases
fun setScreenAliases(aliases: Map<String, String>)Maps Activity and Fragment class names to dashboard names, for example mapOf("MainActivity" to "Home").
Revenue
See Revenue.
logInAppPurchase
fun logInAppPurchase(originalJson: String)Logs a Google Play Billing purchase. Pass purchase.originalJson.
- The SDK reads the product ID and purchase token.
- The backend verifies the purchase and resolves price and currency through the Google Play Developer API.
- Purchases are de-duplicated on purchase token.
logCustomPurchase
fun logCustomPurchase(
type: PaymentEventType,
priceInCents: Int,
currency: String,
productId: String,
startDate: InstantCompat? = InstantCompat.now()
)Logs a purchase, cancellation or refund made outside Google Play Billing.
| Name | Type | Description |
|---|---|---|
type | PaymentEventType | BUY, CANCEL or REFUND. |
priceInCents | Int | Price in cents. |
currency | String | ISO 4217 code. |
productId | String | Your product identifier. |
startDate | InstantCompat? | Defaults to now. See InstantCompat. |
Push notifications
Setup: Push Notifications.
pushToken
var pushToken: String?The FCM token, for push campaigns. See Ask for permission and pass the token.
- Held before
configureand while the SDK is disabled. - Token refreshes reach it through the SDK's
MessagingService, orGrovsMessaging.onNewTokenfrom your own service.
handleNotificationOpen
fun handleNotificationOpen(intent: Intent?): BooleanHandles the intent of a tapped Grovs push. Only needed when the tap doesn't reach the launcher activity's onStart or onNewIntent, for example a splash activity that doesn't forward its extras.
Returns true when the intent is a Grovs push.
- Reports a campaign open (
push_open, once per device and campaign) and delivers the push to yourGrovsDeeplinkListener. datais the push's data merged over the link's data if there is one. The push's keys win.- The same tap seen again through
onStartoronNewIntentisn't reported or delivered twice.
isGrovsNotification
fun isGrovsNotification(data: Map<String, String>): Boolean
fun isGrovsNotification(intent: Intent?): BooleanChecks whether Grovs sent the push, without handling it. Pass RemoteMessage.data, or the intent a tap opened.
Returns true when grovs_campaign_id is present and not blank.
GrovsMessaging
object GrovsMessaging {
@JvmStatic var showForegroundNotifications: Boolean = true
@JvmStatic fun handleMessage(context: Context, message: RemoteMessage): Boolean
@JvmStatic fun onNewToken(token: String)
}For an app with its own FirebaseMessagingService. See If your app has its own FirebaseMessagingService.
| Member | Description |
|---|---|
showForegroundNotifications | Show Grovs pushes that arrive while the app is open. Defaults to true. Background pushes are shown by Firebase. |
handleMessage | Call from onMessageReceived. Shows a Grovs push and returns true; returns false for any other message. |
onNewToken | Call from onNewToken. Same as setting pushToken. |
MessagingService
open class MessagingService : FirebaseMessagingService()io.grovs.handlers.MessagingService, declared in the SDK's manifest. It shows Grovs pushes received in the foreground and forwards token refreshes. Extend it if your app needs its own messaging service, and remove the SDK's declaration with tools:node="remove".
In-app messages
See In-app messages. Every method here works before configure and keeps its effect across later configure calls.
setInAppListener
fun setInAppListener(listener: GrovsInAppListener?)Receives in-app message events (shown, clicked, dismissed, answered, failed) and can stop a message. See GrovsInAppListener.
- Held strongly. Pass
nullto release it. - Messages show without it.
pauseInAppMessages
fun pauseInAppMessages()Holds in-app messages back, during a checkout or video, say. The highest priority one that comes due waits.
resumeInAppMessages
fun resumeInAppMessages()Lets messages show again, starting with the one that waited, if it still qualifies.
discardInAppMessages
@JvmOverloads
fun discardInAppMessages(dismissCurrent: Boolean = false)Drops waiting and delayed messages and stays paused. With dismissCurrent = true, also closes the message on screen (reason app).
setInAppExcludedScreens
fun setInAppExcludedScreens(screens: List<String>)Sets screens where no message shows. Messages wait until the user leaves.
- Use tracked screen names: from
trackScreenView, or the name automatic tracking reports (after aliases). - Case is ignored. Each call replaces the list.
setInAppDebugLogging
fun setInAppDebugLogging(enabled: Boolean)Logs each campaign considered for an event and why it was skipped. Writes to Logcat at INFO under the tag GrovsInApp, whatever the setDebug level.
Types
DeeplinkDetails
class DeeplinkDetails(
var link: String?,
var data: Map<String, Object>?,
var tracking: Map<String, Object>?
)A resolved deep link, passed to GrovsDeeplinkListener.
| Name | Type | Description |
|---|---|---|
link | String? | The link that opened the app, or null if unavailable. |
data | Map<String, Object>? | The custom payload attached to the link. |
tracking | Map<String, Object>? | Attribution and campaign metadata for the link. |
GrovsDeeplinkListener
fun interface GrovsDeeplinkListener {
fun onDeeplinkReceived(deeplinkDetails: DeeplinkDetails)
}Passed to setOnDeeplinkReceivedListener. A functional interface, so a Kotlin lambda works. Runs on the main thread.
GrovsLinkGenerationListener
fun interface GrovsLinkGenerationListener {
fun onLinkGenerated(link: String?, error: GrovsException?)
}Callback for generateLink. Runs on the main thread, except not-configured and still-retrying errors arrive on the calling thread.
GrovsLinkDetailsListener
fun interface GrovsLinkDetailsListener {
fun onLinkDetails(linkDetails: Map<String, Any>?, error: GrovsException?)
}Callback for linkDetails. Same threading as GrovsLinkGenerationListener.
GrovsInAppListener
interface GrovsInAppListener {
fun shouldShowInAppMessage(campaignId: String): Boolean = true
fun onInAppMessageShown(campaignId: String) {}
fun onInAppMessageClicked(campaignId: String, buttonId: String?, payload: Map<String, Any?>?) {}
fun onInAppMessageDismissed(campaignId: String, reason: String) {}
fun onInAppMessageAnswered(campaignId: String, value: Any, comment: String?) {}
fun onInAppMessageFailed(campaignId: String, message: String) {}
}Passed to setInAppListener. Every method has a default and runs on the main thread.
| Method | Called when |
|---|---|
shouldShowInAppMessage | A message is about to show. Return false to stop it. It isn't counted as seen, and nothing else is shown for that event. |
onInAppMessageShown | A message is on screen and its view was counted. |
onInAppMessageClicked | The user taps. buttonId is null for a tap on the message itself. payload is set only for a key-value action. |
onInAppMessageDismissed | A message closes without a click. See the reasons below. |
onInAppMessageAnswered | An answered message has closed, in place of the dismissal. value is an Int for stars, the option's ID for a choice. comment is null unless one was sent. |
onInAppMessageFailed | A message couldn't be drawn, for example with no visible activity. It isn't counted and is tried again at its next trigger. |
Dismiss reason | Meaning |
|---|---|
close_button | The close button, the back gesture, or the alert's Close. |
backdrop | The user tapped outside the message. |
swipe | The user swiped a banner away. |
app | The SDK or your app closed it, for example with discardInAppMessages(dismissCurrent = true). |
orientation | The device turned to an orientation the campaign doesn't allow. Not counted as a dismissal in the dashboard. |
GrovsInAppListenerAdapter
open class GrovsInAppListenerAdapter : GrovsInAppListenerFor Java. Kotlin interface defaults aren't Java defaults on the SDK's JVM target, so extend this and override only what you need.
GrovsException
class GrovsException(message: String?) : Exception(message) {
var errorCode: GrovsErrorCode?
}Thrown by the coroutine forms of generateLink and linkDetails, and passed to the callback forms' listeners.
GrovsErrorCode
enum class GrovsErrorCode {
LINK_GENERATION_ERROR,
SDK_NOT_INITIALIZED,
NOTIFICATIONS_ERROR,
LINK_DETAILS_ERROR,
EVENT_DISPATCH_ERROR
}The category in GrovsException.errorCode.
TrackingParams
class TrackingParams(
val utmCampaign: String? = null,
val utmSource: String? = null,
val utmMedium: String? = null
)UTM parameters for generateLink.
CustomRedirects
class CustomRedirects(
val ios: CustomLinkRedirect? = null,
val android: CustomLinkRedirect? = null,
val desktop: CustomLinkRedirect? = null
)Per-platform redirect overrides for generateLink.
CustomLinkRedirect
class CustomLinkRedirect(
val link: String,
val openAppIfInstalled: Boolean = true
)One platform redirect. When openAppIfInstalled is true, the app opens if installed. Otherwise link is always used.
PaymentEventType
enum class PaymentEventType {
BUY,
CANCEL,
REFUND
}Used with logCustomPurchase.
InstantCompat
data class InstantCompat(val epochMillis: Long)A point in time that works on API 21, for startDate in logCustomPurchase.
| Factory | Creates |
|---|---|
InstantCompat.now() | The current time. |
InstantCompat.ofEpochMilli(millis) | From epoch milliseconds. |
InstantCompat.ofEpochSecond(seconds) | From epoch seconds. |
InstantCompat.parse(iso8601) | From an ISO 8601 string. |
LogLevel
enum class LogLevel {
INFO,
ERROR
}Passed to setDebug.
| Value | Logs |
|---|---|
INFO | Everything, including informational messages. |
ERROR | Errors only (default). |
Deprecated
The messages inbox was removed in 3.1. These members remain so existing code compiles, and show nothing. Use in-app messages.
displayMessagesFragment
fun displayMessagesFragment(onDismissed: (() -> Unit)?)Shows nothing. Calls onDismissed once, on the main thread.
numberOfUnreadMessages
suspend fun numberOfUnreadMessages(): Int?
fun numberOfUnreadMessages(lifecycleOwner: LifecycleOwner? = null, onResult: ((Int?) -> Unit)?)Always yields 0. The callback runs once on the main thread, and is skipped if lifecycleOwner is destroyed by then.
setOnAutomaticNotificationsListener
fun setOnAutomaticNotificationsListener(listener: GrovsNotificationsListener)Does nothing. The listener is never called.
GrovsNotificationsListener
fun interface GrovsNotificationsListener {
fun onAutomaticNotificationClosed(isLast: Boolean)
}Never called.
handleGrovsNotification
fun FirebaseMessagingService.handleGrovsNotification(message: RemoteMessage): BooleanSame as GrovsMessaging.handleMessage(this, message). Use that instead.