Перейти к основному содержимому
Версия: 5.21.0

Решение проблем

Руководство по диагностике и устранению типичных проблем при интеграции и работе edna Chat Center Android SDK.

подсказка

Перед началом диагностики включите подробное логирование: ChatLoggerConfig(logLevel = ChatLogLevel.VERBOSE). В Logcat появятся события инициализации, авторизации, отправки сообщений и состояния WebSocket. Конфигурация и LogInterceptorЛоггер.


SDK не инициализируется

Симптомы

  • Приложение падает при вызове init()
  • IllegalStateException при вызове authorize(), send() или других методов SDK без предварительного init()

Чеклист

  1. 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
    }
    }
  2. Передан applicationContext, а не Activity context?

    • ChatCenterUI требует context уровня Application
    • При передаче Activity context SDK выбросит IllegalArgumentException с сообщением «передайте Context уровня Application»
  3. providerUid указан верно?

    • Значение получено от edna при интеграции
    • Пустая строка приведёт к IllegalArgumentException
  4. Защита от двойной инициализации

    • Повторный вызов init() приводит к переинициализации SDK с очисткой текущего состояния и пересозданием транспортного слоя.
    • Если вы храните экземпляр в Application через lateinit var, проверяйте инициализацию перед повторным присваиванием:
      if (!::chatCenterUI.isInitialized) {
      chatCenterUI = ChatCenterUI(applicationContext).apply { init(...) }
      }

Как проверить

  • В Logcat (фильтр ELog, см. Сбор логов) после успешного init() появляются записи об инициализации SDK и поднятии сетевого транспорта.
  • Следующий вызов authorize() не выбрасывает IllegalStateException.

Чат не загружается

Симптомы

  • getChatFragment() возвращает null
  • Экран чата показывает индикатор загрузки бесконечно
  • Ошибка подключения

Чеклист

  1. Пользователь авторизован? getChatFragment() возвращает не-null только после authorize().

    chatCenterUI.authorize(chatUser, chatAuth)
    val fragment = chatCenterUI.getChatFragment()
  2. 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).

  3. Устройство имеет доступ к сети?

    • Откройте https://<your-cloud-host>/ в браузере устройства — ожидается HTTP 200/301/404 (любой ответ от сервера, не «connection refused»)
    • При VPN убедитесь, что трафик маршрутизируется корректно: SDK использует WSS (порт 443) и HTTPS
    • В VERBOSE-логах SDK видны итоговые URL-адреса WebSocket и REST после нормализации
  4. ProGuard/R8 не обфусцирует SDK?

    warning

    В release-сборке без -keep-правил SDK гарантированно упадёт при первой загрузке конфигурации или приёме сообщения (JsonSyntaxException, ClassNotFoundException). Полный набор правил для SDK и его транзитивных зависимостей — в разделе Установка → Обфускация; правила должны быть в proguard-rules.pro приложения.

Как проверить

  • В Logcat после успешного authorize() и открытия чата отсутствуют исключения, видны записи о приёме сообщений по WebSocket.
  • chatCenterUI.getChatFragment() возвращает не-null Fragment.

Сообщения не отправляются

send() возвращает false, сообщение зависает в статусе «отправляется» либо показывает значок ошибки. По убыванию вероятности:

  1. send() выбросил IllegalStateException — SDK не инициализирован, сначала вызовите init().
  2. send() вернул false — пользователь не авторизован: authorize() не вызван или вернулся с ошибкой.
  3. WebSocket разорван — подпишитесь на ChatCenterUIListener.networkErrorReceived(error); при разрыве в Logcat видны записи уровня WARNING/ERROR.
  4. Файл превышает серверный лимитAttachmentSettings.content.maxSize (в мегабайтах). Типичное значение — 30, для on-premise отличается. См. Файлы и медиа не отправляются.

При успешной отправке статус проходит цепочку SENDING → SENT → DELIVERED → READ. Полный набор значений MessageStatus (включая ENQUEUED, FAILED) — в каноническом разделе.


Файлы и медиа не отправляются

Симптомы

  • Кнопка прикрепления файла не открывает выбор файла
  • При выборе файла отображается ошибка «файл слишком большой» или «тип файла не поддерживается»
  • Файл выбирается, но отправка падает с ошибкой
  • Превью изображения не загружается

Чеклист

  1. Разрешения на чтение медиа выданы?

    • SDK сам показывает системный диалог запроса при попытке прикрепить файл: для CAMERA и storage — через собственный служебный экран запроса разрешений, для RECORD_AUDIO — через стандартный ActivityResultContracts.RequestPermission() (см. секцию Голосовые сообщения)
    • При отказе «Не спрашивать снова» для CAMERA/storage SDK показывает свой AlertDialog с кнопкой перехода в системные настройки приложения. Для микрофона SDK показывает только Toast — переход в настройки нужно реализовать в собственном UI.
    • Runtime-разрешения и их поведение по версиям Android — Разрешения Android
  2. Размер файла не превышает серверный лимит?

    • Лимит приходит в AttachmentSettings.content.maxSize (в мегабайтах) от сервера при загрузке конфигурации
    • Типичное значение — 30 МБ, но для on-premise установок может отличаться. Уточните у вашего администратора edna
    • Превентивно отсекайте большие файлы на стороне приложения — статус ошибки от сервера приходит асинхронно
  3. MIME-тип файла разрешён?

    • Разрешённые расширения приходят в AttachmentSettings.content.fileExtensions
    • Серверная конфигурация может запрещать .exe, .dll, .apk и другие потенциально опасные типы
    • В Logcat появится ошибка с указанием отвергнутого расширения
  4. Доступ к камере (если используется фотографирование)?

    • SDK запрашивает CAMERA-разрешение через системный диалог при попытке открыть камеру из чата
    • Если разрешение отозвано — кнопка камеры будет недоступна
  5. Файл передаётся через ContentResolver, а не напрямую через File?

    • Если ваш код перед передачей файла в SDK работает с java.io.File поверх Scoped Storage content:// URI — отправка упадёт. Используйте ContentResolver или передавайте URI в API SDK без собственного пайплайна

Как проверить

  • Тестовый файл размером ниже maxSize с разрешённым расширением отправляется и переходит в статус SENT.
  • В Logcat при отказе сервера видна причина: «File size exceeds limit», «Disallowed file type» или подобная.

Голосовые сообщения не записываются или не воспроизводятся

Симптомы

  • Кнопка записи голосового сообщения не реагирует на удержание
  • Запись стартует, но при отпускании отправка не происходит
  • Полученное голосовое сообщение не воспроизводится — нет звука или ошибка плеера
  • В Logcat — MediaRecorder start failed / IllegalStateException

Чеклист

  1. Разрешение RECORD_AUDIO выдано?

    • SDK запрашивает разрешение через стандартный ActivityResultContracts.RequestPermission() при нажатии на кнопку микрофона в чате
    • При отказе пользователя кнопка визуально остаётся, но запись не начинается
    • Проверьте Settings → Apps → <ваше приложение> → Permissions → Microphone = Allow
  2. Микрофон не занят другим приложением?

    • Параллельный звонок, VoIP-сессия или активная диктофон-запись блокируют микрофон. Завершите конкурирующее приложение и попробуйте снова.
  3. Серверная конфигурация fileExtensions разрешает формат записи?

    • SDK записывает голос в .ogg (OPUS) на Android 10+ (API 29+) и в .3gp (AMR-WB) на Android 9 и ниже
    • Если серверная конфигурация запрещает эти расширения — отправка голосовых не пройдёт
    • Уточните у администратора edna, что ogg и 3gp присутствуют в AttachmentSettings.content.fileExtensions
  4. Длительность записи не превышает maxSize?

    • Размер файла записи подчиняется тому же серверному лимиту AttachmentSettings.content.maxSize (в мегабайтах)
    • Длинная запись (несколько минут) может его превысить — отправка отклоняется сервером постфактум
  5. Воспроизведение: громкость и Do Not Disturb

    • SDK воспроизводит голосовые сообщения через медиа-канал звука — регулируйте громкость media-канала, не звонка
    • Режим Do Not Disturb с настройкой «Полная тишина» заглушит воспроизведение. Проверьте DND-исключения для медиа

Как проверить

  • Долгое нажатие на кнопку микрофона при выданном RECORD_AUDIO запускает запись и показывает индикатор уровня сигнала.
  • Отпускание после паузы более 1 секунды отправляет файл; статус сообщения переходит SENDING → SENT.
  • Воспроизведение принятого голосового сообщения проигрывает аудио без ошибок в Logcat.

Push-уведомления не приходят

Симптомы

  • Уведомления не отображаются при свёрнутом приложении
  • Уведомления других SDK работают, а edna — нет

Чеклист

Проверки идут от дешёвых build-time к runtime — двигайтесь по списку сверху вниз.

  1. google-services.json в правильном месте?

    • Файл должен быть в корне app-модуля (рядом с build.gradle), не рядом с AndroidManifest.xml
    • В build.gradle (app) подключён плагин com.google.gms.google-services — без него файл игнорируется
  2. Тот же Firebase-проект подключён в админке edna? В админке edna Chat Center на вкладке «Уведомления» Android-канала указаны Sender ID и service-account.json. Оба значения должны принадлежать тому же Firebase-проекту, чей google-services.json лежит в приложении. Если в админке поля пустые или указан другой проект, backend edna не сможет отправить push, даже если токен корректно зарегистрирован SDK (тестовый push из Firebase Console при этом приходит). Сверить значения: Подключение мобильного чата Android.

  3. FirebaseMessagingService зарегистрирован в манифесте?

    <!-- Замените .YourFcmService на полное имя вашего сервиса -->
    <service android:name=".YourFcmService"
    android:exported="false">
    <intent-filter>
    <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
    </service>
  4. FCM-токен передан в SDK?

    // В вашем FirebaseMessagingService:
    override fun onNewToken(token: String) {
    // setFCMToken — статический метод в companion object ChatCenterUI
    ChatCenterUI.setFCMToken(token, applicationContext)
    }
  5. handleFCMMessage() вызывается?

    // В вашем FirebaseMessagingService:
    override fun onMessageReceived(message: com.google.firebase.messaging.RemoteMessage) {
    // SDK фильтрует push по полю origin == "threads"; если push не от edna —
    // вызов будет проигнорирован (в VERBOSE-логах появится соответствующая запись)
    chatCenterUI.handleFCMMessage(message.data)
    }
  6. Поведение handleFCMMessage относительно состояния init()

    • При синхронной форме init(): вызов handleFCMMessage() дожидается завершения текущей инициализации и затем обрабатывает сообщение штатно. Если init() так и не был вызван — handleFCMMessage() выбрасывает IllegalStateException.
    • При initAsync(): вызов безопасен, push кладётся во внутреннюю очередь и обрабатывается после завершения инициализации.
  7. origin=threads присутствует в payload? Если push доходит до устройства, но handleFCMMessage ничего не делает — проверьте поле origin в message.data. При рассылке из админки edna оно зашивается серверным шаблоном push; при ручной рассылке через Firebase Console / AppGallery Connect origin=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-токен пустой или не передаётся.

Чеклист

  1. HCM-токен передан статическим методом?

    // setHCMToken — статический метод в companion object ChatCenterUI
    override fun onNewToken(token: String) {
    ChatCenterUI.setHCMToken(token, applicationContext)
    }
    warning

    Не путайте setFCMToken и setHCMToken — это разные каналы. SDK сохраняет токен по типу, и неверный вызов тихо ничего не делает: push приходить не будет.

  2. agconnect-services.json в корне app-модуля?

    • Файл нужен HMS-плагину Gradle для регистрации Service-ID. Без него HMS не активируется.
  3. HMS-сервис (наследник HmsMessageService) зарегистрирован в манифесте с intent-фильтром com.huawei.push.action.MESSAGING_EVENT?

  4. 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 в рантайме.

  5. App_package в админке совпадает с applicationId модуля? В edna Chat Center на вкладке «Параметры» Huawei-канала указан App_package — это applicationId из build.gradle(.kts). Если значения расходятся (типичная ошибка после переименования пакета или при использовании отдельной Huawei-сборки с applicationIdSuffix), backend edna не отправит push на ваше приложение. Сверить значение: Подключение мобильного чата Huawei → Параметры канала.

  6. 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.

Тема не применяется

Симптомы

  • Цвета/шрифты не соответствуют заданным
  • Тёмная тема не переключается

Чеклист

  1. Тема установлена до init()?

    // Рекомендованный порядок: тема → init()
    chatCenterUI.theme = myTheme
    chatCenterUI.darkTheme = myDarkTheme
    chatCenterUI.init(providerUid, config)

    Установка темы после init() поддерживается, но изменения вступают в силу при следующем открытии экрана чата. Если правки не отображаются — перезапустите чат.

  2. Кастомизация выполнена через ChatComponents? Единственный публичный способ настройки темы — передача ChatComponents в конструктор ChatTheme. Цвета, шрифты и изображения задаются на свойствах компонентов:

    val components = ChatComponents(applicationContext).apply {
    chatMainComponent.chatBackgroundColor = R.color.my_bg
    // настройка остальных компонентов...
    }
    val myTheme = ChatTheme(components)
    chatCenterUI.theme = myTheme

    Настраиваемые поля компонентов перечислены в Design system → Components.

  3. Тёмная тема задана отдельным экземпляром ChatComponents?

    • Если darkTheme не задана, SDK использует значение theme в обоих режимах
    • Светлая и тёмная темы должны использовать разные экземпляры ChatComponents — иначе изменения цветов одного режима пересекаются с другим

Как проверить

  • Откройте чат после chatCenterUI.theme = .... Визуально цвета/шрифты соответствуют переданным.
  • Логи на VERBOSE-уровне содержат записи о применении темы при создании ChatFragment.

WebSocket-разрывы

Симптомы

  • Частые переподключения
  • Сообщения приходят с задержкой
  • В логах: ChatCenterUIListener.networkErrorReceived или сообщения уровня WARNING/ERROR в логах SDK

Чеклист

  1. Таймауты не слишком маленькие? WSConfig принимает значения в секундах, дефолт — 30. Если сеть нестабильна, таймауты нужно увеличивать, а не уменьшать. Слишком короткие интервалы (5/5/5) приводят к постоянным разрывам. Для нестабильных сетей разумно поднять до 60/60/30:

    val wsConfig = WSConfig(connectionTimeout = 60, sendTimeout = 60, pingInterval = 30)
  2. keepWebSocketActive включён при необходимости?

    • Если нужен счётчик непрочитанных вне экрана чата — установите keepWebSocketActive = true в ChatConfig
    • Иначе WebSocket закрывается при уходе с экрана чата
    примечание

    Параметр помечен устаревшим — итоговое поведение управляется серверной конфигурацией. См. ChatConfig → Устаревшие параметры.

  3. Включено ли автоматическое переподключение?

    • Если в логах видны частые единичные разрывы — установите WSConfig.isReconnectEnabled = true; SDK будет восстанавливать соединение самостоятельно с экспоненциальным backoff и заголовком «Подключение...» в тулбаре чата.
    • Если переподключение уже включено, но соединение всё равно периодически отваливается без восстановления — увеличьте maxReconnectAttempts или проверьте стабильность сети устройства.
    • Полное описание поведения и поведение pending-сообщений — в Network config → Автоматическое переподключение.
  4. SSL pinning настроен корректно?

    • Сертификат, заданный в ChatNetworkConfig(sslPinning = SSLPinningConfig(...)), должен соответствовать серверному
    • Рекомендуется указывать минимум 2 сертификата (текущий + резервный): при ротации на стороне сервера резервный обеспечит непрерывную работу приложения у всех клиентов
    warning

    Ошибка SSL pinning приводит к полной невозможности коммуникации с сервером и не сопровождается понятным сообщением в UI — только networkErrorReceived(error) в listener. Перед публикацией release-сборки протестируйте pinning отдельно.

Как проверить

  • В ChatCenterUIListener.networkErrorReceived(error) события приходят реже одного раза в минуту при стабильной сети.

Краши в release-сборке

Симптомы

  • Работает в debug, падает в release
  • ClassNotFoundException или NoSuchMethodException в стектрейсе

Чеклист

  1. ProGuard/R8 правила добавлены?

    warning

    Без -keep-правил release-сборка падает при первой загрузке конфигурации или приёме сообщения. Проверяйте обфускацию в первую очередь при любых крашах release.

    -keep-правила для SDK и его транзитивных зависимостей (Gson, Retrofit, OkHttp, Markwon, Jsoup) собраны в Установка → Обфускация. Скопируйте их в proguard-rules.pro приложения целиком.

  2. mapping.txt сохранён?

    • При включённом R8 имена классов в стектрейсе обфусцированы (a.b.c.d). Без mapping.txt от той же сборки восстановить читаемый стектрейс невозможно.
    • Файл генерируется в app/build/outputs/mapping/release/mapping.txt при каждой release-сборке.
  3. Релиз-сборка воспроизводит проблему локально?

    • Соберите assembleRelease локально и установите APK на устройство
    • Включите ChatLogLevel.VERBOSE — стектрейс в Logcat покажет, какой класс не нашёлся
    • Добавьте отсутствующий класс в -keep-правила, пересоберите

Как проверить

  • После добавления правил release-сборка проходит smoke-тест: открытие чата, отправка сообщения, приём сообщения — без FATAL EXCEPTION в Logcat.
  • В Crashlytics/Sentry за сутки после релиза не появилось новых событий с ClassNotFoundException/NoSuchMethodException/JsonSyntaxException от пакетов edna.chatcenter.*.

Push-уведомления приходят непредсказуемо

Часть push-сообщений доходит, часть теряется (из десяти — четыре-семь); либо доставка приходит с минутной задержкой после долгого фона; либо первый push после перезагрузки устройства теряется до открытия приложения. Возможные причины:

  1. Гонка с холодным стартом SDK. При синхронной init() ранний push блокируется до завершения инициализации и обрабатывается после неё. Если на полном холодном старте Application первый push прилетает раньше init() и приложение закрывается сразу после прихода — push теряется. Решение — initAsync(): push кладётся в очередь и доставляется по готовности SDK.

  2. Дубли с одинаковым message_id. SDK дедуплицирует push по id сообщения; повторный push с тем же id молча игнорируется. Решения о дедупликации видны в VERBOSE-логах.

  3. OEM-ограничения энергосбережения. Xiaomi MIUI, Huawei, Samsung и др. могут применять собственные политики (whitelist приложений, «защищённые приложения», «спящие приложения»). В справке для конечных пользователей укажите, как добавить ваше приложение в whitelist.

В фоне при priority: high доходит 90%+ сообщений; при priority: normal push доходит при следующем активном использовании приложения.


Пользователь отказал в разрешении (CAMERA / RECORD_AUDIO / Storage)

Симптомы

  • Соответствующая кнопка в чате не реагирует на нажатие
  • Системный диалог запроса разрешения больше не показывается
  • Логика чата работает, но прикрепление файлов / запись голоса / фото — нет

Чеклист

  1. Превентивный диалог-объяснение появлялся перед системным запросом?

    • Если в ChatConfig включён permissionsDescriptionDialogsEnabled = true, SDK сначала показывает собственный диалог с объяснением, зачем нужно разрешение, и только потом — системный диалог Android
    • Если флаг выключен, системный диалог появляется сразу
    • Стиль превентивного диалога настраивается через PermissionDescriptionPopupStyle — см. Design system
  2. После двух отказов: SDK предлагает перейти в настройки приложения?

    • После «Не спрашивать снова» Android 11+ переключает разрешение в режим «Denied permanently»
    • Для CAMERA и storage: SDK показывает AlertDialog с кнопкой «Настройки», по нажатию открывается экран приложения (Settings.ACTION_APPLICATION_DETAILS_SETTINGS). Интегратору руками ничего делать не нужно.
    • Для RECORD_AUDIO: SDK показывает только Toast о невозможности записать сообщение, без перехода в настройки. В этом случае подскажите пользователю перейти в настройки в собственном UI или обработайте кейс через свой listener.
  3. Разрешение не запрашивается вообще?

    • SDK запрашивает разрешение лениво — при первой попытке использовать соответствующую функцию (камера, микрофон, файлы)
    • Если запрос не появляется при нажатии кнопки — соответствующая фича отключена в ChatConfig (например, прикрепление файлов запрещено настройками сервера)
  4. POST_NOTIFICATIONS на Android 13+ не выдан?

    • Это влияет только на показ push-уведомлений в системной шторке, не на обработку push внутри SDK (handleFCMMessage / handlePushMessage отрабатывают независимо)
    • SDK запрашивает это разрешение при первом открытии чата на Android 13+. Если пользователь отказал — push будут обрабатываться SDK, но не отображаться в системной шторке. При желании можно дополнительно запросить разрешение в собственном UI (например, при входе пользователя) до открытия чата.

Как проверить

  • В Settings → Apps → <приложение> → Permissions соответствующее разрешение в состоянии Allow или Ask every time.
  • Кнопка прикрепления / микрофон / камера в чате открывает соответствующий UI без задержки.
  • Таблица всех runtime-разрешений SDK и сценариев их запроса — Разрешения Android.

Счётчик непрочитанных не обновляется

Симптомы

  • Бейдж показывает устаревшее значение
  • unreadMessageCountChanged() не вызывается

Чеклист

  1. Пользователь авторизован?

    • Счётчик работает только после успешного authorize(). Это самая частая причина — проверяйте в первую очередь.
  2. ChatCenterUIListener установлен?

    chatCenterUI.setChatCenterUIListener(object : ChatCenterUIListener {
    override fun unreadMessageCountChanged(count: UInt) {
    updateBadge(count.toInt())
    }
    })
    примечание

    Тип параметра — kotlin.UInt. Для использования из Java вам потребуется получить int-представление через рефлексию или wrapper-метод на Kotlin: прямое переопределение из Java невозможно из-за mangling имени.

  3. keepWebSocketActive = true если чат закрыт?

    • Без активного WebSocket счётчик обновляется только при открытии чата
    • Параметр помечен устаревшим, итоговое поведение управляется сервером — см. ChatConfig

Как проверить

  • В Logcat при получении нового сообщения вызывается unreadMessageCountChanged с увеличенным значением count.
  • При открытии чата и прочтении всех сообщений unreadMessageCountChanged вызывается с count = 0u.

Сбор логов для поддержки

Персональные данные в логах

На уровне ChatLogLevel.VERBOSE SDK логирует, в том числе, тексты сообщений, идентификаторы пользователей, метаданные авторизации и URL обращений. Перед отправкой логов в support@edna.ru:

  1. Получите согласие пользователя (или используйте обезличенный тестовый аккаунт) — это требование GDPR/152-ФЗ.
  2. Удалите токены авторизации (Authorization: Bearer ..., JWT в payload) — они дают доступ к сессии пользователя.
  3. Маскируйте тексты переписки или используйте репродукцию на синтетических данных.

Не отправляйте сырые VERBOSE-логи с production-устройств клиента без юридического согласования.

Если проблема не решается — соберите логи и отправьте в support@edna.ru:

  1. Включите максимальный уровень логирования: ChatLoggerConfig(applicationContext, logLevel = ChatLogLevel.VERBOSE) (передайте конфиг в конструктор ChatCenterUI).
  2. Воспроизведите проблему.
  3. Выгрузите логи: через 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Логгер.


Связанные разделы

Проблема не решается?

Если ни один из чек-листов не помог, обратитесь в службу поддержки support@edna.ru. Перед обращением попробуйте воспроизвести проблему на минимальном тестовом проекте — если в нём проблема не воспроизводится, это поможет локализовать дефект в интеграции, а не в SDK.