Integrating into the app lifecycle
A description of the ChatCenterUI SDK integration process, synchronizing the main application lifecycle (App Lifecycle) with the SDK.
Overall interaction diagram
The diagram below shows how app lifecycle events should trigger the corresponding SDK methods for a typical integration.
1. App start
SDK initialization is recommended in the Application class in onCreate() so that the SDK is ready to handle incoming push notifications regardless of which Activity is running.
Creating a ChatCenterUI instance is as fast as possible and performs no network requests in the process.
File: MyApp.kt
import android.app.Application
import edna.chatcenter.ui.visual.core.ChatCenterUI
import edna.chatcenter.ui.visual.ChatConfig
import edna.chatcenter.core.config.transport.ChatTransportConfig
import edna.chatcenter.core.config.transport.ChatNetworkConfig
class MyApp : Application() {
lateinit var chatCenterUI: ChatCenterUI
override fun onCreate() {
super.onCreate()
// The ChatConfig is usually created here as well.
// For a detailed field description — see "Settings → ChatConfig".
val chatConfig = ChatConfig(
transportConfig = ChatTransportConfig(cloudHost = "https://your.edna.io"),
networkConfig = ChatNetworkConfig()
)
// Constructor: ChatCenterUI(appContext: Context, logger: ChatLoggerConfig? = null).
// The second parameter is optional — if a custom logger is not needed, it can be omitted.
chatCenterUI = ChatCenterUI(applicationContext).apply {
// providerUid — unique app identifier issued by edna.
// The init(providerUid, appMarker, config) three-parameter overload is also available.
init("YOUR_PROVIDER_UID", chatConfig)
}
}
}
It makes sense to keep the ChatCenterUI object as a Singleton (via the Application class or DI) so that it is accessible from any layer of the app.
logger: ChatLoggerConfig? is the optional second parameter of the ChatCenterUI constructor. For logger setup details, see Advanced settings → Logger.
2. User authorization
Once your app has authorized the user (for example, sign-in into the authorized zone), you must pass the user data to the SDK. This lets the SDK load the chat history for that specific client.
File: AuthViewModel.kt
import edna.chatcenter.ui.visual.core.ChatCenterUI
import edna.chatcenter.core.config.ChatUser
// chatCenterUI — a ChatCenterUI instance obtained via DI or from the Application
fun handleSuccessfulLogin(
chatCenterUI: ChatCenterUI,
userId: String,
userName: String,
userEmail: String?
) {
// Build the user object.
// identifier — an immutable client identifier in your system (uuid), required and must not be empty.
// name — display name of the client (optional).
// data — arbitrary additional attributes (optional); the SDK does not interpret keys,
// the specific set is to be agreed with the integration team — see ../methods/auth.md.
val chatUser = ChatUser(
identifier = userId,
name = userName,
data = userEmail?.let { mapOf("clientEmail" to it) }
)
// Authorize in the SDK (auth = null if ChatAuth is not used).
chatCenterUI.authorize(chatUser, null)
}
3. Opening the chat
The SDK provides a ready-made ChatFragment that can be embedded into an Activity via FragmentManager or through Navigation Component.
File: MainActivity.kt
import edna.chatcenter.core.annotation.OpenWay
import edna.chatcenter.ui.visual.fragments.ChatFragment
fun openSupportChat() {
// Get the SDK instance (e.g., via DI or from the Application)
val chatCenterUI = (application as MyApp).chatCenterUI
// getChatFragment() returns the previously created instance (if it is still in memory)
// or null. On the first opening, create the fragment via ChatFragment.newInstance(...).
val chatFragment = chatCenterUI.getChatFragment()
?: ChatFragment.newInstance(OpenWay.DEFAULT)
supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container, chatFragment)
.addToBackStack(null)
.commit()
}
Direct navigation via navigate(R.id.action_global_chatFragment) does not work: Navigation Component instantiates the fragment via FragmentFactory without arguments, while ChatFragment expects the arguments set in ChatFragment.newInstance(@OpenWay from: Int). If you use Navigation Component, add the fragment obtained from getChatFragment() / newInstance(...) to the container manually via FragmentManager, or register a custom FragmentFactory that calls ChatFragment.newInstance(...) itself.
Before opening the chat, make sure the user is already authorized in the SDK (see the User authorization section). The getChatFragment() method itself does not validate authorization: it only returns the previously created ChatFragment (WeakReference), populated when ChatFragment.newInstance(...) is called. Without prior authorization, ChatFragment will display a history-loading error screen.
Available OpenWay values: OpenWay.DEFAULT — a regular opening, OpenWay.FROM_PUSH — an opening from a push notification (see edna.chatcenter.core.annotation.OpenWay).
4. User sign-out
When the user signs out of the account in the app, the SDK session must be terminated. The SDK has two methods for this with different semantics — the choice depends on the scenario:
| App-side sign-out scenario | Call |
|---|---|
| The user tapped "Sign out of account" | logout() |
| The user signed out of the authorized zone (PIN) but stays in the app | deauthorizeUser() |
The full contract of both methods — what they send to the server, what they clean locally, behavior with an inactive WebSocket, a separate caveat about FCM/HCM tokens — is in the canonical section Authorization → Logout.
File: ProfileViewModel.kt
import edna.chatcenter.ui.visual.core.ChatCenterUI
// Full sign-out — the client notifies the server, local session data is cleared.
// Contract — see ../methods/auth.md#logout
fun performLogout(chatCenterUI: ChatCenterUI) {
chatCenterUI.logout()
navigateToLoginScreen()
}
// Sign-out from the authorized zone (PIN) — the server connection is not broken,
// history is preserved. Contract — see ../methods/auth.md#logout
fun performDeauthorize(chatCenterUI: ChatCenterUI) {
chatCenterUI.deauthorizeUser()
navigateToLoginScreen()
}
On a repeated sign-in into the authorized zone, authorize(...) must be called again with the user data.