Android: Integrating Live Chat as an Embedded View

Updated 

The Live Chat SDK provides flexibility to integrate Messenger directly into your app’s UI. Instead of launching Messenger as a standalone activity, you can embed it as a fragment within your host application. This approach allows the chat experience to coexist seamlessly with your app’s navigation, layouts, and lifecycle management.

Prerequisites (Host App)

Before embedding Messenger as a fragment, ensure the following setup is complete:

1. Extend host activity: Extend com.spr.messengerclient.SPRMessengerHostAppCompatActivity to your activity containing Sprinklr Messenger Fragment so React Native lifecycle, permissions, and notification intents are handled correctly.

2. Register fragment host activity class: Before takeOff(), register the activity that will host the chat fragment (used for notification routing):

SPRMessenger.shared().setSPRMessengerHostActivityClass(YourHostActivity.class);SPRMessenger.shared().takeOff(this, config);

3. Update manifest: On the host activity, set android:windowSoftInputMode="adjustResize" so the keyboard does not cover the chat input.

4. Back press, push, close: Implement hardware back press forwarding, notification reopen logic, and optional close handling as described in later sections.

Integration Steps

Follow these steps to embed Messenger as a fragment in your host app:

1. Adding the fragment automatically

SDK Method:

startApplicationAsFragment(...)
  • The SDK creates the chat Fragment, runs FragmentManager.beginTransaction().add(...), and tags it with SPRMessenger.MESSENGER_FRAGMENT_TAG. If that tag already exists, the SDK shows the existing fragment instead of adding a second one.

  • When to use: When you want the SDK to manage fragment attachment (typical tab or single container layouts).

Examples

  • With launch context (same applicationLaunchBundle as startApplication in the Help article):

SPRMessenger.shared().startApplicationAsFragment(applicationLaunchBundle, this, R.id.spr_fragment);
  • Default open (empty launchOptions and chatInitialisationContext, same idea as startApplication() with no extras):

SPRMessenger.shared().startApplicationAsFragment(this, R.id.spr_fragment);
  • From a notification intent (when the host extends SPRMessengerHostAppCompatActivity):

if (shouldOpenMessengerFromPushIntent()) {    SPRMessenger.shared()        .startApplicationAsFragment(applicationLaunchBundleFromIntent(), this, R.id.spr_fragment);}

Parameters

Parameter

Description

applicationLaunchBundle

Top-level bundle with launchOptions and chatInitialisationContext child bundles (each may be empty). Pass null to use the SDK’s empty default.

context

Host AppCompatActivity.

fragmentId

Layout id of the container (FrameLayout / FragmentContainerView).

Note:

  • The two‑argument overload of startApplicationAsFragment(...) only takes context and fragmentId. In this case, the SDK automatically uses empty inner bundles.

  • After an activity recreation (such as a configuration change or process restore), you must call SPRMessenger.shared().syncMessengerFragmentFromHost(this) to re‑sync the SDK with the restored fragment. This applies to both the automatic (startApplicationAsFragment) and manual (SPRMessengerFragment.create) integration options.

2. Manual handling for fragment behavior customizations

SDK Method:

SPRMessengerFragment.create(...)

  • You create the Fragment instance and run your own add, replace, show, hide, back stack, or multiple containers. The SDK does not commit a transaction for you.

  • When to use: You need full control over fragment transactions or navigation behavior.

Examples

Fragment fragment = SPRMessengerFragment.create(launchOptions, chatInitialisationContext);

val fragment = SPRMessengerFragment.create(launchOptions, chatInitialisationContext)

Parameters

Parameter

Description

launchOptions

Same bundle you would put in applicationLaunchBundle.putBundle("launchOptions", ...).

chatInitialisationContext

Same bundle you would put in applicationLaunchBundle.putBundle("chatInitialisationContext", ...).

Note: The method SPRMessengerFragment.create(...) will return null if the Messenger SDK has not been initialized.

Example transaction

if (fragment != null) {    getSupportFragmentManager()        .beginTransaction()        .replace(R.id.spr_fragment, fragment, SPRMessenger.MESSENGER_FRAGMENT_TAG)        .commit();}

Note:

  • Always tag the instance with SPRMessenger.MESSENGER_FRAGMENT_TAG so the SDK can locate it (including syncMessengerFragmentFromHost). See Syncing the SDK after activity recreation above.

  • Relationship to option 1: startApplicationAsFragment calls SPRMessengerFragment.create(...) internally with your bundles, then performs the add. Option 1 and 2 share the same payload; only the transaction owner differs.

  • Activity recreation: use the same sync section as for option 1.

Step 3: Syncing the SDK after activity recreation (options 1 and 2)

SDK Method:

SPRMessenger.shared().syncMessengerFragmentFromHost(this);

You should call syncMessengerFragmentFromHost(...) from your host activity when both of the following are true:

  • Integration type: You’re using either integration automatic (startApplicationAsFragment) or manual (SPRMessengerFragment.create).

  • System restored the fragment: The system may have restored the messenger fragment without going through your “open chat” code again. For example: savedInstanceState != null in onCreate(Bundle) — activity recreated after a configuration change (rotation, locale, etc.) or process death while your task is restored, so FragmentManager restores fragments by tag.

  • In that case the in-memory SPRMessenger reference to the fragment (and host activity) can be stale or null even though findFragmentByTag(MESSENGER_FRAGMENT_TAG) returns the live instance.

  • When you usually do not need it: Cold start or fresh navigation where savedInstanceState == null and you immediately call startApplicationAsFragment(...) or add/replace the fragment yourself — those paths attach the fragment and update the SDK.

Typical pattern:

@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_host);    if (savedInstanceState != null) {        SPRMessenger.shared().syncMessengerFragmentFromHost(this);    }    // ...}

The messenger fragment must still use tag SPRMessenger.MESSENGER_FRAGMENT_TAG so the sync can find it.

4. Hardware back press

You must determine when Live Chat is the active UI. For example, by using isLiveChatFragmentVisible(), checking the current navigation destination or tab state, or comparing the visible fragment against getMessengerFragment().

Pattern:

/** * Implement this in your host app. */private boolean isLiveChatFragmentVisible() {    // e.g. navController.getCurrentDestination() matches your chat route    return /* your condition */;}@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    // ...    getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {        @Override        public void handleOnBackPressed() {            Fragment messengerFragment = SPRMessenger.shared().getMessengerFragment();            if (messengerFragment != null && isLiveChatFragmentVisible()) {                handleBackPressed();                return;            }            // customize according to app back handling behaviour.            setEnabled(false);            getOnBackPressedDispatcher().onBackPressed();            setEnabled(true);        }    });}

5. Close behavior in fragment mode

Register SPRMessengerCloseHandler to remove the Messenger fragment and restore your shell UI (such as the previous screen, default tab, or other container). If you do not provide a close handler, the SDK will instead finish the activity instance that hosts the Messenger fragment.

Pattern:

private final SPRMessengerCloseHandler sprMessengerCloseHandler = new SPRMessengerCloseHandler() {    @Override    public void onClose() {        runOnUiThread(() -> {            SPRMessenger.shared().removeMessengerFragment();            restoreYourShellAfterChatCloses(); // e.g. pop back stack, select another tab, clear your own flags        });    }};@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    // ...    SPRMessenger.shared().setSPRMessengerCloseHandler(sprMessengerCloseHandler);}@Overrideprotected void onDestroy() {    super.onDestroy();    SPRMessenger.shared().setSPRMessengerCloseHandler(null);}

Note: Implement restoreYourShellAfterChatCloses() in your app to define how the UI should behave once the Messenger fragment is closed.

6. Fragment visibility handling

SDK Method:

SPRMessenger.shared().toggleMessengerVisibility(false);
  • Call this method when Live Chat is no longer visible to the user due to fragment navigation.

  • When to use: This should be invoked when switching fragments, navigating to another screen, or otherwise hiding the messenger fragment while it remains attached to the activity.

​7. Push notifications

  • Keep super.onNewIntent(intent) and super.onResume(): These calls are required because the base activity contains the SDK’s built‑in notification handling.

  • Opening embedded chat from a Messenger push: To open embedded chat from a messenger push, use shouldOpenMessengerFromPushIntent() and applicationLaunchBundleFromIntent(), and navigate in your own shell (router, drawer, tab controller, etc.) so the chat container is shown, then call startApplicationAsFragment with the intent bundle.

Lifecycle scenarios

onCreate: First entry with a push intent (pseudocode):

if (savedInstanceState == null && shouldOpenMessengerFromPushIntent()) {    navigateToLiveChatInYourApp(); }

onNewIntent: Same activity already running (pseudocode):

@Overrideprotected void onNewIntent(Intent intent) {    super.onNewIntent(intent);    if (!shouldOpenMessengerFromPushIntent()) {        return;    }    if (isLiveChatFragmentVisible()) {        SPRMessenger.shared().startApplicationAsFragment(            applicationLaunchBundleFromIntent(),            this,            R.id.your_chat_container        );        // ensure your own show/hide logic leaves the chat container visible    } else {        navigateToLiveChatInYourApp();    }}

Note: Replace navigateToLiveChatInYourApp(), isLiveChatFragmentVisible(), and R.id.your_chat_container with your real navigation and layout id.