Skip to main content
In-app messages appear while users are active in your app. The Android SDK displays them automatically when you enable the in-app module and identify the user.

Add the dependency

dependencies {
    implementation("com.zixflow.com.android:datapipelines:1.1.3")
    implementation("com.zixflow.com.android:messaging-in-app:1.1.3")
}
For Jetpack Compose inline placements, also add messaging-in-app-compose. See Jetpack Compose Support.

Enable in-app messaging

Register ModuleMessagingInApp when you initialize the SDK:
import com.zixflow.sdk.Zixflow
import com.zixflow.sdk.ZixflowConfigBuilder
import com.zixflow.messaginginapp.MessagingInAppModuleConfig
import com.zixflow.messaginginapp.ModuleMessagingInApp
import com.zixflow.messaginginapp.type.InAppEventListener
import com.zixflow.messaginginapp.type.InAppMessage

val inAppConfig = MessagingInAppModuleConfig.Builder()
    .setEventListener(object : InAppEventListener {
        override fun messageShown(message: InAppMessage) {
            // Message displayed
        }

        override fun messageDismissed(message: InAppMessage) {
            // Message closed
        }

        override fun errorWithMessage(message: InAppMessage) {
            // Message failed to display
        }

        override fun messageActionTaken(
            message: InAppMessage,
            actionValue: String,
            actionName: String
        ) {
            // User tapped an action
        }
    })
    .build()

Zixflow.initialize(
    ZixflowConfigBuilder(this, "YOUR_API_KEY")
        .addZixflowModule(ModuleMessagingInApp(config = inAppConfig))
        .build()
)
You can also pass MessagingInAppModuleConfig.Builder().build() with no listener if you only need default display behavior.

Identify users

Identify a user before personalized in-app messages can be delivered:
Zixflow.instance().identify(
    userId = "user-123",
    traits = mapOf("email" to "user@example.com")
)
Anonymous users can still receive some in-app messages; identified users get personalized campaigns and inbox sync.

How messages appear

Once in-app is enabled:
  1. Create and launch an in-app campaign in the Zixflow dashboard.
  2. When campaign conditions match, the SDK fetches and displays the message.
  3. No extra UI code is required for standard modal messages—the SDK renders them in an overlay activity.
Track screen views with Zixflow.instance().screen(title = ...) if your campaigns target specific screens. Screen events update the in-app route used for targeting.

Listen for in-app events

CallbackWhen it fires
messageShownMessage is displayed
messageDismissedMessage is closed
messageActionTakenUser taps a message action
errorWithMessageMessage fails to display

Dismiss a message

Dismiss the currently visible in-app message from your app code:
ModuleMessagingInApp.instance().dismissMessage()

Inline in-app messages (Views)

Use InlineInAppMessageView to render a message inline in your layout. The elementId must match the placement ID configured in your campaign. XML:
<com.zixflow.messaginginapp.ui.InlineInAppMessageView
    android:id="@+id/inline_in_app_message"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:elementId="home-banner" />
Kotlin:
import com.zixflow.messaginginapp.type.InAppMessage
import com.zixflow.messaginginapp.type.InlineMessageActionListener
import com.zixflow.messaginginapp.ui.InlineInAppMessageView

val inlineView = findViewById<InlineInAppMessageView>(R.id.inline_in_app_message)
inlineView.elementId = "home-banner"
inlineView.setActionListener(object : InlineMessageActionListener {
    override fun onActionClick(
        message: InAppMessage,
        actionValue: String,
        actionName: String
    ) {
        // Handle inline action
    }
})
For Compose, use InlineInAppMessage from the compose module. See Jetpack Compose Support.

Notification inbox

Access persistent inbox messages with the inbox API:
import com.zixflow.messaginginapp.di.inAppMessaging
import com.zixflow.messaginginapp.inbox.NotificationInboxChangeListener

val inbox = Zixflow.instance().inAppMessaging().inbox()

// Async fetch
inbox.fetchMessages { result ->
    result.onSuccess { messages ->
        // Render inbox UI
    }
}

// Live updates
val listener = object : NotificationInboxChangeListener {
    override fun onMessagesChanged(messages: List<com.zixflow.messaginginapp.gist.data.model.InboxMessage>) {
        // Rebuild your inbox UI
    }
}
inbox.addChangeListener(listener)

// Mark read / unread / delete / track clicks
inbox.markMessageOpened(message)
inbox.markMessageUnopened(message)
inbox.markMessageDeleted(message)
inbox.trackMessageClicked(message, actionName = "cta")

// Remove when done
inbox.removeChangeListener(listener)
Optionally filter by topic: inbox.fetchMessages(topic = "promotions") { ... } or inbox.addChangeListener(listener, topic = "promotions"). For the full method list, see the API Reference.