Решение проблем
Руководство по диагностике и устранению типичных проблем при интеграции и работе edna Chat Center Android SDK.
Перед началом диагностики включите подробное логирование: ChatLoggerConfig(logLevel = ChatLogLevel.VERBOSE). В Logcat появятся события инициализации, авторизации, отправки сообщений и состояния WebSocket. Конфигурация и LogInterceptor — Логгер.
SDK не инициализируется
Симптомы
- Приложение падает при вызове
init() IllegalStateExceptionпри вызовеauthorize(),send()или других методов SDK без предварительногоinit()
Чеклист
-
init()вызван вApplication.onCreate()?Корректное место для конструктора и
init():class MyApp : Application() {
lateinit var chatCenterUI: ChatCenterUI
override fun onCreate() {
super.onCreate()
chatCenterUI = ChatCenterUI(applicationContext).apply {
init(providerUid = "YOUR_PROVIDER_UID", config = chatConfig)
}
}
}Если конструктор вызван из Activity — SDK выбросит
IllegalArgumentException:class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
ChatCenterUI(this) // Activity context — выбрасывает IllegalArgumentException
}
} -
Передан
applicationContext, а не Activity context?ChatCenterUIтребует context уровня Application- При передаче Activity context SDK выбросит
IllegalArgumentExceptionс сообщением «передайте Context уровня Application»
-
providerUidуказан верно?- Значение получено от edna при интеграции
- Пустая строка приведёт к
IllegalArgumentException
-
Защита от двойной инициализации
- Повторный вызов
init()приводит к переинициализации SDK с очисткой текущего состояния и пересозданием транспортного слоя. - Если вы храните экземпляр в
Applicationчерезlateinit var, проверяйте инициализацию перед повторным присваиванием:if (!::chatCenterUI.isInitialized) {
chatCenterUI = ChatCenterUI(applicationContext).apply { init(...) }
}
- Повторный вызов
Как проверить
- В Logcat (фильтр
ELog, см. Сбор логов) после успешногоinit()появляются записи об инициализации SDK и поднятии сетевого транспорта. - Следующий вызов
authorize()не выбрасываетIllegalStateException.
Чат не загружается
Симптомы
getChatFragment()возвращаетnull- Экран чата показывает индикатор загрузки бесконечно
- Ошибка подключения
Чеклист
-
Пользователь авторизован?
getChatFragment()возвращает не-nullтолько послеauthorize().chatCenterUI.authorize(chatUser, chatAuth)
val fragment = chatCenterUI.getChatFragment() -
URL-адреса серверов корректны?
cloudHostв упрощённом конструкторе принимает полный URL с протоколом — без path:val transport = ChatTransportConfig(cloudHost = "https://company.edna.ru")SDK передаёт значение
cloudHostнапрямую вRetrofit.baseUrl()иOkHttp Request.url()— без протокола вы получитеIllegalArgumentException: Expected URL schemeпри инициализации. URL с path (например,"https://company.edna.ru/api") даст некорректный итоговый адрес. Если нужен нестандартный порт или path — используйте полную форму с явнымиrest,webSocket,dataStore(ChatTransportConfig). -
Устройство имеет доступ к сети?
- Откройте
https://<your-cloud-host>/в браузере устройства — ожидается HTTP 200/301/404 (любой ответ от сервера, не «connection refused») - При VPN убедитесь, что трафик маршрутизируется корректно: SDK использует WSS (порт 443) и HTTPS
- В VERBOSE-логах SDK видны итоговые URL-адреса WebSocket и REST после нормализации
- Откройте
-
ProGuard/R8 не обфусцирует SDK?
warningВ release-сборке без
-keep-правил SDK гарантированно упадёт при первой загрузке конфигурации или приёме сообщения (JsonSyntaxException,ClassNotFoundException). Полный набор правил для SDK и его транзитивных зависимостей — в разделе Установка → Обфускация; правила должны быть вproguard-rules.proприложения.
Как проверить
- В Logcat после успешного
authorize()и открытия чата отсутствуют исключения, видны записи о приёме сообщений по WebSocket. chatCenterUI.getChatFragment()возвращает не-nullFragment.
Сообщения не отправляются
send() возвращает false, сообщение зависает в статусе «отправляется» либо показывает значок ошибки. По убыванию вероятности:
send()выбросилIllegalStateException— SDK не инициализирован, сначала вызовитеinit().send()вернулfalse— пользователь не авторизован:authorize()не вызван или вернулся с ошибкой.- WebSocket разорван — подпишитесь на
ChatCenterUIListener.networkErrorReceived(error); при разрыве в Logcat видны записи уровня WARNING/ERROR. - Файл превышает серверный лимит —
AttachmentSettings.content.maxSize(в мегабайтах). Типичное значение — 30, для on-premise отличается. См. Файлы и медиа не отправляются.
При успешной отправке статус проходит цепочку SENDING → SENT → DELIVERED → READ. Полный набор значений MessageStatus (включая ENQUEUED, FAILED) — в каноническом разделе.
Файлы и медиа не отправляются
Симптомы
- Кнопка прикрепления файла не открывает выбор файла
- При выборе файла отображается ошибка «файл слишком большой» или «тип файла не поддерживается»
- Файл выбирается, но отправка падает с ошибкой
- Превью изображения не загружается
Чеклист
-
Разрешения на чтение медиа выданы?
- SDK сам показывает системный диалог запроса при попытке прикрепить файл: для CAMERA и storage — через собственный служебный экран запроса разрешений, для
RECORD_AUDIO— через стандартныйActivityResultContracts.RequestPermission()(см. секцию Голосовые сообщения) - При отказе «Не спрашивать снова» для CAMERA/storage SDK показывает свой
AlertDialogс кнопкой перехода в системные настройки приложения. Для микрофона SDK показывает только Toast — переход в настройки нужно реализовать в собственном UI. - Runtime-разрешения и их поведение по версиям Android — Разрешения Android
- SDK сам показывает системный диалог запроса при попытке прикрепить файл: для CAMERA и storage — через собственный служебный экран запроса разрешений, для
-
Размер файла не превышает серверный лимит?
- Лимит приходит в
AttachmentSettings.content.maxSize(в мегабайтах) от сервера при загрузке конфигурации - Типичное значение — 30 МБ, но для on-premise установок может отличаться. Уточните у вашего администратора edna
- Превентивно отсекайте большие файлы на стороне приложения — статус ошибки от сервера приходит асинхронно
- Лимит приходит в
-
MIME-тип файла разрешён?
- Разрешённые расширения приходят в
AttachmentSettings.content.fileExtensions - Серверная конфигурация может запрещать
.exe,.dll,.apkи другие потенциально опасные типы - В Logcat появится ошибка с указанием отвергнутого расширения
- Разрешённые расширения приходят в
-
Доступ к камере (если используется фотографирование)?
- SDK запрашивает
CAMERA-разрешение через системный диалог при попытке открыть камеру из чата - Если разрешение отозвано — кнопка камеры будет недоступна
- SDK запрашивает
-
Файл передаётся через
ContentResolver, а не напрямую черезFile?- Если ваш код перед передачей файла в SDK работает с
java.io.Fileповерх Scoped Storagecontent://URI — отправка упадёт. ИспользуйтеContentResolverили передавайте URI в API SDK без собственного пайплайна
- Если ваш код перед передачей файла в SDK работает с
Как проверить
- Тестовый файл размером ниже
maxSizeс разрешённым расширением отправляется и переходит в статусSENT. - В Logcat при отказе сервера видна причина: «File size exceeds limit», «Disallowed file type» или подобная.
Голосовые сообщения не записываются или не воспроизводятся
Симптомы
- Кнопка записи голосового сообщения не реагирует на удержание
- Запись стартует, но при отпускании отправка не происходит
- Полученное голосовое сообщение не воспроизводится — нет звука или ошибка плеера
- В Logcat —
MediaRecorder start failed/IllegalStateException
Чеклист
-
Разрешение
RECORD_AUDIOвыдано?- SDK запрашивает разрешение через стандартный
ActivityResultContracts.RequestPermission()при нажатии на кнопку микрофона в чате - При отказе пользователя кнопка визуально остаётся, но запись не начинается
- Проверьте
Settings → Apps → <ваше приложение> → Permissions → Microphone = Allow
- SDK запрашивает разрешение через стандартный
-
Микрофон не занят другим приложением?
- Параллельный звонок, VoIP-сессия или активная диктофон-запись блокируют микрофон. Завершите конкурирующее приложение и попробуйте снова.
-
Серверная конфигурация
fileExtensionsразрешает формат записи?- SDK записывает голос в
.ogg(OPUS) на Android 10+ (API 29+) и в.3gp(AMR-WB) на Android 9 и ниже - Если серверная конфигурация запрещает эти расширения — отправка голосовых не пройдёт
- Уточните у администратора edna, что
oggи3gpприсутствуют вAttachmentSettings.content.fileExtensions
- SDK записывает голос в
-
Длительность записи не превышает
maxSize?- Размер файла записи подчиняется тому же серверному лимиту
AttachmentSettings.content.maxSize(в мегабайтах) - Длинная запись (несколько минут) может его превысить — отправка отклоняется сервером постфактум
- Размер файла записи подчиняется тому же серверному лимиту
-
Воспроизведение: громкость и Do Not Disturb
- SDK воспроизводит голосовые сообщения через медиа-канал звука — регулируйте громкость media-канала, не звонка
- Режим Do Not Disturb с настройкой «Полная тишина» заглушит воспроизведение. Проверьте DND-исключения для медиа
Как проверить
- Долгое нажатие на кнопку микрофона при выданном
RECORD_AUDIOзапускает запись и показывает индикатор уровня сигнала. - Отпускание после паузы более 1 секунды отправляет файл; статус сообщения переходит
SENDING → SENT. - Воспроизведение принятого голосового сообщения проигрывает аудио без ошибок в Logcat.
Push-уведомления не приходят
Симптомы
- Уведомления не отображаются при свёрнутом приложении
- Уведомления других SDK работают, а edna — нет
Чеклист
Проверки идут от дешёвых build-time к runtime — двигайтесь по списку сверху вниз.
-
google-services.jsonв правильном месте?- Файл должен быть в корне app-модуля (рядом с
build.gradle), не рядом сAndroidManifest.xml - В
build.gradle(app) подключён плагинcom.google.gms.google-services— без него файл игнорируется
- Файл должен быть в корне app-модуля (рядом с
-
Тот же Firebase-проект подключён в админке edna? В админке edna Chat Center на вкладке «Уведомления» Android-канала указаны Sender ID и service-account.json. Оба значения должны принадлежать тому же Firebase-проекту, чей
google-services.jsonлежит в приложении. Если в админке поля пустые или указан другой проект, backend edna не сможет отправить push, даже если токен корректно зарегистрирован SDK (тестовый push из Firebase Console при этом приходит). Сверить значения: Подключение мобильного чата Android. -
FirebaseMessagingServiceзарегистрирован в манифесте?<!-- Замените .YourFcmService на полное имя вашего сервиса -->
<service android:name=".YourFcmService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service> -
FCM-токен передан в SDK?
// В вашем FirebaseMessagingService:
override fun onNewToken(token: String) {
// setFCMToken — статический метод в companion object ChatCenterUI
ChatCenterUI.setFCMToken(token, applicationContext)
} -
handleFCMMessage()вызывается?// В вашем FirebaseMessagingService:
override fun onMessageReceived(message: com.google.firebase.messaging.RemoteMessage) {
// SDK фильтрует push по полю origin == "threads"; если push не от edna —
// вызов будет проигнорирован (в VERBOSE-логах появится соответствующая запись)
chatCenterUI.handleFCMMessage(message.data)
} -
Поведение
handleFCMMessageотносительно состоянияinit()- При синхронной форме
init(): вызовhandleFCMMessage()дожидается завершения текущей инициализации и затем обрабатывает сообщение штатно. Еслиinit()так и не был вызван —handleFCMMessage()выбрасываетIllegalStateException. - При
initAsync(): вызов безопасен, push кладётся во внутреннюю очередь и обрабатывается после завершения инициализации.
- При синхронной форме
-
origin=threadsприсутствует в payload? Если push доходит до устройства, ноhandleFCMMessageничего не делает — проверьте полеoriginвmessage.data. При рассылке из админки edna оно зашивается серверным шаблоном push; при ручной рассылке через Firebase Console / AppGallery Connectorigin=threadsнужно добавить вручную в Custom data. Описание шаблонов: Настройка шаблонов пуш-уведомлений.
Как проверить
- В Logcat после
onNewToken(...)видна запись о сохранении FCM-токена. - При тестовом push (через консоль Firebase или backend)
onMessageReceivedвызывается, а в UI/Logcat появляется новое сообщение.
Push-уведомления не приходят (HMS / Huawei)
На устройствах Huawei без Google Play Services используется Huawei Push Kit (HMS), а не FCM. Симптомы и шаги диагностики отличаются от Google. Базовый setup (зависимости, манифест, обработчик токена) — в Настройка push-уведомлений → HMS; ниже — диагностика интеграции.
Симптомы
- Сборка с HMS на Huawei-устройстве не показывает уведомления, при этом FCM-сборка на других телефонах работает.
- В логах
ChatLogLevel.VERBOSEвидно, что HCM-токен пустой или не передаётся.
Чеклист
-
HCM-токен передан статическим методом?
// setHCMToken — статический метод в companion object ChatCenterUI
override fun onNewToken(token: String) {
ChatCenterUI.setHCMToken(token, applicationContext)
}warningНе путайте
setFCMTokenиsetHCMToken— это разные каналы. SDK сохраняет токен по типу, и неверный вызов тихо ничего не делает: push приходить не будет. -
agconnect-services.jsonв корне app-модуля?- Файл нужен HMS-плагину Gradle для регистрации Service-ID. Без него HMS не активируется.
-
HMS-сервис (наследник
HmsMessageService) зарегистрирован в манифесте с intent-фильтромcom.huawei.push.action.MESSAGING_EVENT? -
HMS
RemoteMessage.dataдекодируется как base64 → JSON → Bundle, а не отдаётся в SDK как есть? В отличие от FCM, HMS отдаёт payload вRemoteMessage.dataкак base64-строку с JSON внутри. Перед вызовомhandlePushMessage(bundle)строку нужно декодировать и разложить вBundle— иначе SDK увидит «origin=threads» как невалидный payload и проигнорирует push. Пример декодера: Настройка push-уведомлений → HMS, Шаг 2.примечаниеИмпорт критичен: и FCM, и HMS имеют класс
RemoteMessage, но они разные. Перепутанный импорт ломает сборку или приводит кNoSuchMethodErrorв рантайме. -
App_package в админке совпадает с
applicationIdмодуля? В edna Chat Center на вкладке «Параметры» Huawei-канала указан App_package — этоapplicationIdизbuild.gradle(.kts). Если значения расходятся (типичная ошибка после переименования пакета или при использовании отдельной Huawei-сборки сapplicationIdSuffix), backend edna не отправит push на ваше приложение. Сверить значение: Подключение мобильного чата Huawei → Параметры канала. -
Huawei App ID и App Secret в админке актуальны? После пересоздания OAuth 2.0 ключей в AppGallery Connect старые значения в админке перестают работать молча — без явной ошибки в логах. Сверьте Huawei App ID и Huawei App Secret в канале с актуальными OAuth 2.0 Client ID и Client secret из AppGallery Connect → Project settings → App information.
Как проверить
- В Logcat после
onNewToken(...)появляется запись о сохранении HCM-токена. - При тестовом push через AppGallery Push Kit сообщение попадает в
onMessageReceivedи затем в UI/Logcat SDK.
Тема не применяется
Симптомы
- Цвета/шрифты не соответствуют заданным
- Тёмная тема не переключается
Чеклист
-
Тема установлена до
init()?// Рекомендованный порядок: тема → init()
chatCenterUI.theme = myTheme
chatCenterUI.darkTheme = myDarkTheme
chatCenterUI.init(providerUid, config)Установка темы после
init()поддерживается, но изменения вступают в силу при следующем открытии экрана чата. Если правки не отображаются — перезапустите чат. -
Кастомизация выполнена через
ChatComponents? Единственный публичный способ настройки темы — передачаChatComponentsв конструкторChatTheme. Цвета, шрифты и изображения задаются на свойствах компонентов:val components = ChatComponents(applicationContext).apply {
chatMainComponent.chatBackgroundColor = R.color.my_bg
// настройка остальных компонентов...
}
val myTheme = ChatTheme(components)
chatCenterUI.theme = myThemeНастраиваемые поля компонентов перечислены в Design system → Components.
-
Тёмная тема задана отдельным экземпляром
ChatComponents?- Если
darkThemeне задана, SDK использует значениеthemeв обоих режимах - Светлая и тёмная темы должны использовать разные экземпляры
ChatComponents— иначе изменения цветов одного режима пересекаются с другим
- Если
Как проверить
- Откройте чат после
chatCenterUI.theme = .... Визуально цвета/шрифты соответствуют переданным. - Логи на VERBOSE-уровне содержат записи о применении темы при создании
ChatFragment.
WebSocket-разрывы
Симптомы
- Частые переподключения
- Сообщения приходят с задержкой
- В логах:
ChatCenterUIListener.networkErrorReceivedили сообщения уровня WARNING/ERROR в логах SDK
Чеклист
-
Таймауты не слишком маленькие?
WSConfigпринимает значения в секундах, дефолт — 30. Если сеть нестабильна, таймауты нужно увеличивать, а не уменьшать. Слишком короткие интервалы (5/5/5) приводят к постоянным разрывам. Для нестабильных сетей разумно поднять до60/60/30:val wsConfig = WSConfig(connectionTimeout = 60, sendTimeout = 60, pingInterval = 30) -
keepWebSocketActiveвключён при необходимости?- Если нужен счётчик непрочитанных вне экрана чата — установите
keepWebSocketActive = trueвChatConfig - Иначе WebSocket закрывается при уходе с экрана чата
примечаниеПараметр помечен устаревшим — итоговое поведение управляется серверной конфигурацией. См.
ChatConfig→ Устаревшие параметры. - Если нужен счётчик непрочитанных вне экрана чата — установите
-
Включено ли автоматическое переподключение?
- Если в логах видны частые единичные разрывы — установите
WSConfig.isReconnectEnabled = true; SDK будет восстанавливать соединение самостоятельно с экспоненциальным backoff и заголовком «Подключение...» в тулбаре чата. - Если переподключение уже включено, но соединение всё равно периодически отваливается без восстановления — увеличьте
maxReconnectAttemptsили проверьте стабильность сети устройства. - Полное описание поведения и поведение pending-сообщений — в Network config → Автоматическое переподключение.
- Если в логах видны частые единичные разрывы — установите
-
SSL pinning настроен корректно?
- Сертификат, заданный в
ChatNetworkConfig(sslPinning = SSLPinningConfig(...)), должен соответствовать серверному - Рекомендуется указывать минимум 2 сертификата (текущий + резервный): при ротации на стороне сервера резервный обеспечит непрерывную работу приложения у всех клиентов
warningОшибка SSL pinning приводит к полной невозможности коммуникации с сервером и не сопровождается понятным сообщением в UI — только
networkErrorReceived(error)в listener. Перед публикацией release-сборки протестируйте pinning отдельно. - Сертификат, заданный в
Как проверить
- В
ChatCenterUIListener.networkErrorReceived(error)события приходят реже одного раза в минуту при стабильной сети.
Краши в release-сборке
Симптомы
- Работает в debug, падает в release
ClassNotFoundExceptionилиNoSuchMethodExceptionв стектрейсе
Чеклист
-
ProGuard/R8 правила добавлены?
warningБез
-keep-правил release-сборка падает при первой загрузке конфигурации или приёме сообщения. Проверяйте обфускацию в первую очередь при любых крашах release.-keep-правила для SDK и его транзитивных зависимостей (Gson, Retrofit, OkHttp, Markwon, Jsoup) собраны в Установка → Обфускация. Скопируйте их вproguard-rules.proприложения целиком. -
mapping.txtсохранён?- При включённом R8 имена классов в стектрейсе обфусцированы (
a.b.c.d). Безmapping.txtот той же сборки восстановить читаемый стектрейс невозможно. - Файл генерируется в
app/build/outputs/mapping/release/mapping.txtпри каждой release-сборке.
- При включённом R8 имена классов в стектрейсе обфусцированы (
-
Релиз-сборка воспроизводит проблему локально?
- Соберите
assembleReleaseлокально и установите APK на устройство - Включите
ChatLogLevel.VERBOSE— стектрейс в Logcat покажет, какой класс не нашёлся - Добавьте отсутствующий класс в
-keep-правила, пересоберите
- Соберите
Как проверить
- После добавления правил release-сборка проходит smoke-тест: открытие чата, отправка сообщения, приём сообщения — без
FATAL EXCEPTIONв Logcat. - В Crashlytics/Sentry за сутки после релиза не появилось новых событий с
ClassNotFoundException/NoSuchMethodException/JsonSyntaxExceptionот пакетовedna.chatcenter.*.
Push-уведомления приходят непредсказуемо
Часть push-сообщений доходит, часть теряется (из десяти — четыре-семь); либо доставка приходит с минутной задержкой после долгого фона; либо первый push после перезагрузки устройства теряется до открытия приложения. Возможные причины:
-
Гонка с холодным стартом SDK. При синхронной
init()ранний push блокируется до завершения инициализации и обрабатывается после неё. Если на полном холодном старте Application первый push прилетает раньшеinit()и приложение закрывается сразу после прихода — push теряется. Решение —initAsync(): push кладётся в очередь и доставляется по готовности SDK. -
Дубли с одинаковым
message_id. SDK дедуплицирует push по id сообщения; повторный push с тем же id молча игнорируется. Решения о дедупликации видны в VERBOSE-логах. -
OEM-ограничения энергосбережения. Xiaomi MIUI, Huawei, Samsung и др. могут применять собственные политики (whitelist приложений, «защищённые приложения», «спящие приложения»). В справке для конечных пользователей укажите, как добавить ваше приложение в whitelist.
В фоне при priority: high доходит 90%+ сообщений; при priority: normal push доходит при следующем активном использовании приложения.
Пользователь отказал в разрешении (CAMERA / RECORD_AUDIO / Storage)
Симптомы
- Соответствующая кнопка в чате не реагирует на нажатие
- Системный диалог запроса разрешения больше не показывается
- Логика чата работает, но прикрепление файлов / запись голоса / фото — нет
Чеклист
-
Превентивный диалог-объяснение появлялся перед системным запросом?
- Если в
ChatConfigвключёнpermissionsDescriptionDialogsEnabled = true, SDK сначала показывает собственный диалог с объяснением, зачем нужно разрешение, и только потом — системный диалог Android - Если флаг выключен, системный диалог появляется сразу
- Стиль превентивного диалога настраивается через
PermissionDescriptionPopupStyle— см. Design system
- Если в
-
После двух отказов: SDK предлагает перейти в настройки приложения?
- После «Не спрашивать снова» Android 11+ переключает разрешение в режим «Denied permanently»
- Для CAMERA и storage: SDK показывает
AlertDialogс кнопкой «Настройки», по нажатию открывается экран приложения (Settings.ACTION_APPLICATION_DETAILS_SETTINGS). Интегратору руками ничего делать не нужно. - Для
RECORD_AUDIO: SDK показывает только Toast о невозможности записать сообщение, без перехода в настройки. В этом случае подскажите пользователю перейти в настройки в собственном UI или обработайте кейс через свой listener.
-
Разрешение не запрашивается вообще?
- SDK запрашивает разрешение лениво — при первой попытке использовать соответствующую функцию (камера, микрофон, файлы)
- Если запрос не появляется при нажатии кнопки — соответствующая фича отключена в
ChatConfig(например, прикрепление файлов запрещено настройками сервера)
-
POST_NOTIFICATIONSна Android 13+ не выдан?- Это влияет только на показ push-уведомлений в системной шторке, не на обработку push внутри SDK (
handleFCMMessage/handlePushMessageотрабатывают независимо) - SDK запрашивает это разрешение при первом открытии чата на Android 13+. Если пользователь отказал — push будут обрабатываться SDK, но не отображаться в системной шторке. При желании можно дополнительно запросить разрешение в собственном UI (например, при входе пользователя) до открытия чата.
- Это влияет только на показ push-уведомлений в системной шторке, не на обработку push внутри SDK (
Как проверить
- В
Settings → Apps → <приложение> → Permissionsсоответствующее разрешение в состоянииAllowилиAsk every time. - Кнопка прикрепления / микрофон / камера в чате открывает соответствующий UI без задержки.
- Таблица всех runtime-разрешений SDK и сценариев их запроса — Разрешения Android.
Счётчик непрочитанных не обновляется
Симптомы
- Бейдж показывает устаревшее значение
unreadMessageCountChanged()не вызывается
Чеклист
-
Пользователь авторизован?
- Счётчик работает только после успешного
authorize(). Это самая частая причина — проверяйте в первую очередь.
- Счётчик работает только после успешного
-
ChatCenterUIListenerустановлен?chatCenterUI.setChatCenterUIListener(object : ChatCenterUIListener {
override fun unreadMessageCountChanged(count: UInt) {
updateBadge(count.toInt())
}
})примечаниеТип параметра —
kotlin.UInt. Для использования из Java вам потребуется получитьint-представление через рефлексию или wrapper-метод на Kotlin: прямое переопределение из Java невозможно из-за mangling имени. -
keepWebSocketActive = trueесли чат закрыт?- Без активного WebSocket счётчик обновляется только при открытии чата
- Параметр помечен устаревшим, итоговое поведение управляется сервером — см.
ChatConfig
Как проверить
- В Logcat при получении нового сообщения вызывается
unreadMessageCountChangedс увеличенным значениемcount. - При открытии чата и прочтении всех сообщений
unreadMessageCountChangedвызывается сcount = 0u.
Сбор логов для поддержки
На уровне ChatLogLevel.VERBOSE SDK логирует, в том числе, тексты сообщений, идентификаторы пользователей, метаданные авторизации и URL обращений. Перед отправкой логов в support@edna.ru:
- Получите согласие пользователя (или используйте обезличенный тестовый аккаунт) — это требование GDPR/152-ФЗ.
- Удалите токены авторизации (
Authorization: Bearer ..., JWT в payload) — они дают доступ к сессии пользователя. - Маскируйте тексты переписки или используйте репродукцию на синтетических данных.
Не отправляйте сырые VERBOSE-логи с production-устройств клиента без юридического согласования.
Если проблема не решается — соберите логи и отправьте в support@edna.ru:
- Включите максимальный уровень логирования:
ChatLoggerConfig(applicationContext, logLevel = ChatLogLevel.VERBOSE)(передайте конфиг в конструкторChatCenterUI). - Воспроизведите проблему.
- Выгрузите логи: через Shake-жест в чате, через
adb logcat | grep ELogили из файлов{filesDir}/logs/. Для отправки в release-сборках без физического доступа к устройству используйтеChatLoggerConfig.LogInterceptor(Crashlytics/Sentry/AppMetrica).
На Android 11+ (API 30+) каталог data/data/{package}/files/ недоступен через ADB для release-сборок (debuggable = false). Используйте Shake-жест, LogInterceptor или отправку логов из самого приложения.
Развёрнутая конфигурация логгера, форматы и примеры LogInterceptor — Логгер.
Связанные разделы
- Ошибки SDK — полный список исключений и их причин
- Логгер — полная конфигурация, уровни логирования,
LogInterceptor - Установка → Обфускация — полный список ProGuard/R8-правил
- Настройка push-уведомлений — базовая интеграция FCM и HMS
- Разрешения Android — полная таблица runtime-разрешений и сценариев их запроса
- Design system → Components — стилизация SDK, включая диалог запроса разрешений
ChatTransportConfig— конфигурация транспорта с нестандартным портом/path- Сообщить об ошибке — шаблон bug-report с необходимыми артефактами
Если ни один из чек-листов не помог, обратитесь в службу поддержки support@edna.ru. Перед обращением попробуйте воспроизвести проблему на минимальном тестовом проекте — если в нём проблема не воспроизводится, это поможет локализовать дефект в интеграции, а не в SDK.