Brand Concierge Implementation Guide (Android)
The Brand Concierge UI has two integration approaches:
- Managed Integration: Provides a drop-in entry point to the chat interface and lets the Brand Concierge extension automatically manage it.
- Custom Integration: Embeds and manages the chat UI directly into your app's view hierarchy for dedicated chat screens or custom layouts.
Both approaches are available for Compose and XML/Views-based apps.
Prerequisites
Required SDK modules
Your app needs the following Experience Platform SDKs to be available and registered:
Android version
- Minimum Android API level 24 (Android 7.0) or higher
Permissions for speech to text (optional)
Speech to text uses Android Speech Recognition APIs and microphone APIs for voice input functionality. Add this permission to your app AndroidManifest.xml:
Copied to your clipboard<uses-permission android:name="android.permission.RECORD_AUDIO" />
The SDK handles permission requests internally when users interact with the microphone button.
Configuration
Step 1: Set up the Adobe Experience Platform Mobile SDK
Follow the Adobe Experience Platform Mobile SDK getting started guide to set up the base SDK integration used by Brand Concierge.
The required extensions are:
- AEPCore
- AEPEdge
- AEPEdgeIdentity
- AEPBrandConcierge
Step 2: Validate the Brand Concierge configuration keys exist
If you set the Adobe Experience Platform SDK log level to trace:
Copied to your clipboardMobileCore.setLogLevel(LoggingMode.VERBOSE)
you can then inspect the app logs to confirm that extension shared states are being set with the expected values.
Brand Concierge expects the following keys to be present in the Configuration shared state:
concierge.server: String (server host or base domain used by Brand Concierge requests)concierge.configId: String (datastream ID)
The ECID is read from the Edge Identity shared state.
Another option for validation is to use Adobe Assurance. Refer to the Mobile SDK validation guide for more information.
Integration
Managed Integration
Use this when you want to provide a drop-in entry point to the chat interface and let the Brand Concierge extension automatically manage it.
This mode:
- Shows the configured trigger when the Brand Concierge extension is ready (ECID and Concierge configuration available)
- Opens chat as a full-screen dialog when the trigger is invoked
- Handles dismissal (back press, close button, gestures) automatically
Jetpack Compose
The ConciergeChat composable can be configured with a UI element (button, floating action button, or any custom element) of your choice to act as a trigger to launch the chat interface. Pass the list of surface URLs via surfaces.
Copied to your clipboard@Composablefun MyScreen() {val viewModel = viewModel<ConciergeChatViewModel>()val surfaces = listOf("web://example.com/your-surface.html")// Your app content// ... other views ...ConciergeChat(viewModel = viewModel,surfaces = surfaces) { showChat ->// Your trigger button/view that launches ConciergeChatMyTriggerButton(onClick = { showChat() })}}
XML/Views
For non-Compose apps, the SDK provides ConciergeChatView that wraps the Compose chat UI and can be included in XML layouts.
Step 1: Add the view to your XML layout
Copied to your clipboard<com.adobe.marketing.mobile.concierge.ui.chat.ConciergeChatViewandroid:id="@+id/concierge_chat"android:layout_width="match_parent"android:layout_height="wrap_content" />
Step 2: Bind with a trigger view in your Activity/Fragment
Copied to your clipboardclass XmlActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)// Load optional themeval theme = ConciergeThemeLoader.load(this, "myTheme.json")// Create a trigger button of your choiceval triggerButton = Button(this).apply {text = "Start Chat"textSize = 18fsetPadding(32, 16, 32, 16)}// Obtain the ConciergeChatView and bind the triggerButtonval chatView = findViewById<ConciergeChatView>(R.id.concierge_chat)val surfaces = listOf("web://example.com/your-surface.html")chatView.bind(lifecycleOwner = this,viewModelStoreOwner = this,surfaces = surfaces,theme = theme, // Optional: apply custom themetriggerView = triggerButton)}}
Custom Integration
Use this when you want to embed the chat interface directly into your app's view hierarchy for more flexibility. This is useful for dedicated chat screens or custom layouts.
In this mode, you should:
- Ensure that the necessary components (ECID, Configuration) are ready before making this visible. You can check readiness by observing
ConciergeStateRepository.instance.state. - Manage the logic to control what happens when the chat interface is dismissed when notified via
onClose.
Jetpack Compose
Set surfaces via surfaces and ensure the extension is ready (configuration, ECID, and surfaces) before showing the chat.
Copied to your clipboard@Composablefun YourChatScreen() {val viewModel = viewModel<ConciergeChatViewModel>()val conciergeState by ConciergeStateRepository.instance.state.collectAsStateWithLifecycle()val surfaces = listOf("web://example.com/your-surface.html")// Set surfaces so they are available for the chat sessionConciergeStateRepository.instance.setSessionSurfaces(surfaces)val ready = conciergeState.configurationReady &&conciergeState.experienceCloudId != null &&conciergeState.surfaces.isNotEmpty()if (ready) {ConciergeChat(viewModel = viewModel,onClose = {// your logic on close or back press})} else {// Show your intermediate loading state or wait for SDK to be ready}}
XML/Views
Step 1: Add the view to your XML layout
Copied to your clipboard<com.adobe.marketing.mobile.concierge.ui.chat.ConciergeChatViewandroid:id="@+id/concierge_chat"android:layout_width="match_parent"android:layout_height="match_parent" />
Step 2: Bind in your Activity/Fragment
Copied to your clipboardclass XmlActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)// Load optional themeval theme = ConciergeThemeLoader.load(this, "myTheme.json")// Obtain the chat view and bindval chatView = findViewById<ConciergeChatView>(R.id.concierge_chat)val surfaces = listOf("web://example.com/your-surface.html")chatView.bind(lifecycleOwner = this,viewModelStoreOwner = this,surfaces = surfaces,theme = theme, // Optional: apply custom themeonClose = { finish() })}}
Theme Customization
The Brand Concierge chat interface can be customized by loading the theme file from the assets directory of your app using ConciergeThemeLoader.
Copied to your clipboard@Composablefun MyScreen() {val context = LocalContext.currentval theme = remember {ConciergeThemeLoader.load(context, "myTheme.json")?: ConciergeThemeLoader.default()}ConciergeTheme(theme = theme) {ConciergeChat(/* ... */)}}
More information regarding theme customization can be found in the Style guide (Android).
Next steps
- Style guide (Android) — Theme JSON reference and implementation status for Android.
