Displaying the chat
The SDK provides two ways to display the chat: via ChatFragment (recommended) or via the built-in ChatActivity.
Make sure the SDK is initialized and the user is authorized:
chatCenterUI.init(...)is called inApplication.onCreate()— see SDK initialization.chatCenterUI.authorize(chatUser, chatAuth)has been called at least once — without it, the chat will open but will not be able to send messages. See App lifecycle for details.- Runtime permissions
CAMERA,RECORD_AUDIO,POST_NOTIFICATIONSare requested by the SDK on demand (when the camera/microphone button is tapped and after history is loaded) — see Installation → What the SDK adds to the manifest.
In the examples below, chatCenterUI is a singleton ChatCenterUI instance, typically stored in a custom Application. The creation pattern is in SDK initialization.
Option 1: ChatFragment (recommended)
Gives full control over the container, navigation, and lifecycle.
- Kotlin
- Java
import edna.chatcenter.core.annotation.OpenWay
import edna.chatcenter.ui.visual.fragments.ChatFragment
class MyChatActivity : AppCompatActivity() {
private val chatCenterUI: ChatCenterUI
get() = (application as MyApp).chatCenterUI
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_chat)
// 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.chat_container, chatFragment)
.commit()
// The SDK handles internal navigation (search, selection, quoting),
// so "Back" is forwarded to the fragment first.
onBackPressedDispatcher.addCallback(this) {
val chat = supportFragmentManager
.findFragmentById(R.id.chat_container) as? ChatFragment
val shouldClose = chat?.onBackPressed() ?: true
if (shouldClose) finish()
}
}
}
import edna.chatcenter.core.annotation.OpenWay;
import edna.chatcenter.ui.visual.fragments.ChatFragment;
import androidx.activity.OnBackPressedCallback;
public class MyChatActivity extends AppCompatActivity {
private ChatCenterUI chatCenterUI() {
return ((MyApp) getApplication()).getChatCenterUI();
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
// getChatFragment() returns the previously created instance (if it is still in memory)
// or null. On the first opening, create the fragment via ChatFragment.newInstance(...).
ChatFragment chatFragment = chatCenterUI().getChatFragment();
if (chatFragment == null) {
chatFragment = ChatFragment.newInstance(OpenWay.DEFAULT);
}
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.chat_container, chatFragment)
.commit();
// The SDK handles internal navigation (search, selection, quoting),
// so "Back" is forwarded to the fragment first.
getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
ChatFragment chat = (ChatFragment) getSupportFragmentManager()
.findFragmentById(R.id.chat_container);
boolean shouldClose = (chat == null) || chat.onBackPressed();
if (shouldClose) {
finish();
}
}
});
}
}
R.id.chat_container is a FrameLayout container in your layout. The SDK is a fragment — you can configure the container's paddings yourself.
OpenWay valuesOpenWay.DEFAULT— a regular chat open by a tap in the app.OpenWay.FROM_PUSH— open from a push notification; the SDK performs additional processing to sync with the notification state. Use this when handling a push tap.
If your app does not use androidx.activity:activity-ktx, you can override onBackPressed() the classic way:
override fun onBackPressed() {
val chat = supportFragmentManager
.findFragmentById(R.id.chat_container) as? ChatFragment
val shouldClose = chat?.onBackPressed() ?: true
if (shouldClose) super.onBackPressed()
}
The Activity.onBackPressed() method itself is deprecated from API 33 (Android 13), so for new apps the OnBackPressedDispatcher is preferred (example above).
Option 2: ChatActivity
The SDK's built-in Activity, which already contains a ChatFragment and its own layout. Does not require the app to provide a separate Activity and container layout.
- Kotlin
- Java
import edna.chatcenter.ui.visual.activities.ChatActivity
val intent = Intent(context, ChatActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK
}
context.startActivity(intent)
To obtain a reference to the current Activity:
val activity = chatCenterUI.getChatActivity() // null if the Activity has not been created yet
import edna.chatcenter.ui.visual.activities.ChatActivity;
Intent intent = new Intent(context, ChatActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
To obtain a reference to the current Activity:
ChatActivity activity = chatCenterUI.getChatActivity(); // null if the Activity has not been created yet
Approach comparison
- ChatFragment — for production apps when you need control over navigation, Navigation Component, or embedding the chat into an existing screen.
- ChatActivity — when the chat occupies a separate screen with no custom navigation, and the built-in SDK layout is acceptable.
Edge-to-edge (Android 15+)
Starting with Android 15 (targetSdk = 35), the edge-to-edge approach has become mandatory: the system ignores android:fitsSystemWindows, and content is drawn under the status bar and navigation bar by default.
The SDK handles insets automatically at targetSdk = 35: the toolbar and input field receive correct WindowInsets paddings without additional configuration.
ChatFlow.fullScreenMode is deprecatedThe fullScreenMode property in ChatFlow is marked @Deprecated. According to the annotation message in the SDK code — "since targetSdk = 35, the parameter is no longer used (always true)". The field is kept for binary compatibility; see also Known limitations (section "Fields with no effect in the current version").
Chat in a partial container (bottom sheet, drawer)
On Android 15+, ChatFragment unconditionally applies WindowInsets paddings — there is no public opt-out, so a chat embedded in a BottomSheetDialogFragment or drawer will get a padding the height of the system navigation bar. The current status and workarounds are in Known limitations.
The chatCenterUI.theme / darkTheme fields are queried on every ChatFragment creation (in onCreateView). If you change the theme while the chat is already open, the current screen does not automatically repaint — close the chat and open it again, the new theme will be applied. SDK re-initialization is not required. See also Themes.
Handling the "Back" button
The SDK uses internal navigation (message search, image viewing, selected messages, quoting). Always forward the "Back" press to ChatFragment:
Signature:
fun onBackPressed(): Boolean
Returns:
true— the chat is ready to be closed (no internal navigation was active).false— the SDK handled the press itself (for example, closed the search bar, cleared message selection, hid the quote); the host screen must not be closed.
val shouldClose = chatFragment.onBackPressed()
if (shouldClose) finish()
Related sections
- SDK initialization — a required preliminary step before opening the chat.
- Integrating into the app lifecycle — user authorization and logout / deauthorize scenarios.
- Push notifications — handling pushes that open the chat on tap (
OpenWay.FROM_PUSH). - Themes — chat appearance customization.
- Known limitations — SDK behavior in bottom sheet / drawer.