Методы работы с сообщениями
Если пользователь сам печатает в чате — никакого send() вызывать не нужно: SDK обрабатывает отправку из встроенного UI автоматически. send() предназначен для случаев, когда ваше приложение инициирует сообщение (например, отправка контекста заказа при открытии чата).
logout() / deauthorizeUser()Методы выхода пользователя описаны в Авторизация → Логаут.
Отправка и предзаполнение
send(message: ChatMessage): Boolean
Отправляет сообщение от имени текущего авторизованного пользователя.
| Возвращает / бросает | Когда |
|---|---|
true | Для TextMessage / FileMessage: пользователь авторизован — сообщение сохранено в локальную БД и поставлено в очередь отправки (если сокет активен) или отправлено через свежеоткрытый сокет. Для LocationMessage: пользователь авторизован, либо deviceAddress ещё не получен (в этом случае координаты кэшируются и отправятся после регистрации устройства). |
false | Для TextMessage / FileMessage: пользователь не авторизован (authorize() не вызывался или сброшен через logout() / deauthorizeUser()). Для LocationMessage: deviceAddress уже получен, но ChatUser / ChatAuth отсутствуют, либо отправка не была принята транспортом. |
IllegalStateException | SDK не инициализирован — вызывайте send() только после init() / initAsync(). |
Подтипы ChatMessage:
ChatMessage.TextMessage(text: String)— текстовое сообщениеChatMessage.FileMessage(file: File)— файлChatMessage.LocationMessage(point: Point)— геолокация (edna.chatcenter.core.models.Point)
import edna.chatcenter.core.models.ChatMessage
import edna.chatcenter.core.models.Point
chatCenterUI.send(ChatMessage.TextMessage("Здравствуйте"))
chatCenterUI.send(ChatMessage.FileMessage(file))
chatCenterUI.send(ChatMessage.LocationMessage(Point(latitude = 55.7558, longitude = 37.6173)))
Статусы сообщения — MessageStatus
edna.chatcenter.core.models.MessageStatus — enum состояния доставки сообщения. SDK обновляет статус автоматически: SENDING → SENT → DELIVERED → READ для успешного пути; FAILED при ошибке транспорта; ENQUEUED для отложенной отправки.
| Значение | Когда устанавливается |
|---|---|
SENDING | Сообщение сохранено локально, отправляется на сервер |
SENT | Сервер принял сообщение |
DELIVERED | Сообщение доставлено оператору |
READ | Оператор прочитал сообщение |
FAILED | Ошибка отправки — в штатном UI пользователю доступен повтор |
ENQUEUED | Отложенная отправка (например, до восстановления соединения) |
Статус доступен в поле sentState элементов истории. В кастомном UI подписывайтесь на изменения через outgoingMessageStatusChangedFlow — он эмитит List<Status> с обновлениями статусов разных сообщений.
prefill(message: String)
fun prefill(message: String)
Предзаполняет поле ввода указанным текстом. Текст будет отображён при следующем открытии экрана чата. Передайте пустую строку (""), чтобы очистить ранее установленное предзаполнение.
chatCenterUI.prefill("Здравствуйте, у меня вопрос по заказу №12345")
// Сбросить предзаполнение
chatCenterUI.prefill("")
Счётчик непрочитанных сообщений
updateUnreadCountMessagesIfNeed()
fun updateUnreadCountMessagesIfNeed()
Принудительно обновляет счётчик непрочитанных сообщений с запросом к серверу. Также вызывается SDK автоматически при authorize(...) — явный вызов нужен только если приложение хочет инициировать обновление вне этого сценария. Если пользователь не авторизован — обновление пропускается без ошибки.
UnreadMessagesController
Для программного управления счётчиком используйте UnreadMessagesController (enum-singleton):
| Метод / Свойство | Тип | Описание |
|---|---|---|
pushesCount | UInt | Текущее количество непрочитанных push-уведомлений; чтение потокобезопасно из любого потока. |
unreadMessagesPublishProcessor | MutableSharedFlow<UInt> | Реактивный поток изменений счётчика — потребителям доступен только для чтения через collect, запись зарезервирована за SDK. Поток не отдаёт текущее значение при подписке (только новые эмиссии); для чтения актуального значения — поле pushesCount. |
refreshUnreadMessagesCount(getCountRemotely, block?) | — | Обновить счётчик. getCountRemotely = false по умолчанию. При true запрашивает данные с сервера. |
clearPushesCount() | — | Локально сбрасывает pushesCount в 0. Не эмитит событие в unreadMessagesPublishProcessor — если UI обновляется только по подписке на поток, синхронизируйте badge вручную. |
// Получить текущее количество непрочитанных push-уведомлений
val count = UnreadMessagesController.INSTANCE.pushesCount
// Подписаться на изменения счётчика через Flow
lifecycleScope.launch {
UnreadMessagesController.INSTANCE.unreadMessagesPublishProcessor.collect { count ->
updateBadge(count)
}
}
// Принудительно обновить счётчик (с запросом на сервер)
UnreadMessagesController.INSTANCE.refreshUnreadMessagesCount(getCountRemotely = true) { count ->
updateBadge(count)
}
// Сбросить счётчик push-уведомлений
UnreadMessagesController.INSTANCE.clearPushesCount()
Хранение истории сообщений
История сообщений живёт в SQLite в памяти процесса (in-memory): она доступна для пагинации, обновления статусов и поиска в рамках текущего запуска, но не сохраняется на диск и теряется при завершении процесса — при следующем authorize(...) загружается с сервера заново.
Полный обзор всех хранилищ SDK (prefs, push-токены, что переживёт logout()) — см. Авторизация → Хранение данных пользователя.
Потокобезопасность и потоки
Публичные методы SDK не требуют конкретного диспетчера вызова, за исключением методов, возвращающих/работающих с UI-компонентами Android.
| Метод | Откуда вызывать | Примечание |
|---|---|---|
init() / initAsync() | Из Application.onCreate() | init() выполняет инициализацию синхронно и блокирует вызывающий поток; initAsync() выполняет ту же работу асинхронно. |
authorize() | Любой поток | Требует, чтобы SDK был инициализирован, и непустой identifier. Сетевые операции запускаются асинхронно. |
send() | Любой поток | Запись в локальную БД и отправка через транспорт SDK выполняются внутри метода. |
logout() / deauthorizeUser() | Любой поток | См. Авторизация → Логаут. |
getChatFragment() | Main thread | Возвращает Android Fragment — с UI-компонентами работайте только из main thread. |
setChatCenterUIListener() | Любой поток | Сам вызов потоконезависим; где будут выполняться колбэки — см. ниже. |
ChatFragment.onBackPressed() | Main thread | Fragment-метод, вызывайте из UI. |
networkErrorReceived приходит не на main threadИз четырёх колбэков ChatCenterUIListener только networkErrorReceived вызывается из фонового потока (сеть OkHttp/Retrofit). Перед UI-операциями переключайтесь на main явно. Полная таблица потоков и рекомендуемый идиом — в Делегатах → Потоки callback'ов.
Связанные разделы
- Авторизация (auth) — обязательное предусловие для
send(). - Делегаты (delegates) —
ChatCenterUIListenerиChatUpdateProcessor. - Ошибки (errors) — что приходит в
networkErrorReceivedиexceptionReceived.