Как подключить мобильный SDK к приложению Android

Обновлено: 9 октября 2026 · 11 мин чтения

SDK для Android написан на Kotlin и работает и из Java. Кроме доступа к сети он не просит разрешений и ничего не добавляет на Ваши экраны. С 1.0.2 в диалоге можно снимать фото и видео камерой и отправлять голосовые сообщения. Камере разрешение не нужно: SDK открывает системное приложение камеры, FileProvider уже есть в SDK; если в манифесте приложения объявлено CAMERA, SDK сначала запросит его. Голосовым сообщениям нужно RECORD_AUDIO: приложение объявляет его в своём AndroidManifest.xml, без него кнопка микрофона не показывается, а SDK пишет об этом в лог.

Шаги

  1. 1

    Требования

    • Android 6.0 (API 23) или новее, compileSdk 35 или новее, Kotlin 1.8 или новее.
    • App ID и ключ API для Android (android_…) из раздела «Installation» в панели.
  2. 2

    Добавьте пакет

    Пакет в Maven Central. В большинстве проектов mavenCentral() уже есть в settings.gradle.kts.

    // app/build.gradle.kts
    dependencies {
        implementation("ai.clomni:messenger:1.0.5")
    }
  3. 3

    Запустите SDK

    Вызывайте initialize один раз, в классе Application. Уведомление может запустить процесс приложения, а открытому им Messenger нужен готовый SDK, поэтому Activity уже поздно.

    // App.kt
    import android.app.Application
    import ai.clomni.messenger.Clomni
    import ai.clomni.messenger.ClomniLogLevel
    
    class App : Application() {
        override fun onCreate() {
            super.onCreate()
            Clomni.initialize(this, appId = "app_…", apiKey = "android_…")
            if (BuildConfig.DEBUG) Clomni.setLogLevel(ClomniLogLevel.DEBUG)
        }
    }
    <!-- AndroidManifest.xml -->
    <application
        android:name=".App"
        ...>

    С AGP 8 и новее для BuildConfig.DEBUG нужно buildFeatures { buildConfig = true } в app/build.gradle.kts. Методы Clomni можно вызывать из любого треда, слушатели вызываются в главном треде (main thread). Повторный initialize игнорируется.

  4. 4

    Вход пользователя

    После Вашего собственного входа, с user_hash от сервера:

    val user = ClomniUser(userId = "12345", email = "[email protected]", name = "Aysel")
    Clomni.loginUser(user, userHash = hashFromYourServer)
    
    Clomni.updateUser(language = "az", customAttributes = mapOf("plan" to "premium"))
    
    // Together with your app's own logout:
    Clomni.logout()

    Код сервера для хеша есть в статье «Ключи мобильного SDK и идентификация пользователей».

    Пока пользователь вошёл в приложение, вызывайте loginUser при каждом запуске, как будто он только что вошёл. Для того же пользователя SDK использует сохранённую сессию.

  5. 5

    Откройте Messenger

    findViewById<View>(R.id.support).setOnClickListener {
        Clomni.present(source = "profile_support")
    }
    
    // Jetpack Compose
    Button(onClick = { Clomni.present(source = "profile_support") }) {
        Text("Support")
    }
    • Clomni.presentNewConversation(source): сразу новый диалог.
    • Clomni.presentConversation(id): известный диалог, ID приходит из onConversationStarted.
    • Clomni.dismiss(): закрывает Messenger из кода.

    Счётчик непрочитанных, чтобы показать рядом с кнопкой:

    class ProfileActivity : AppCompatActivity() {
        private val unread = UnreadCountListener { count ->
            supportBadge.isVisible = count > 0
            supportBadge.text = count.toString()
        }
    
        override fun onStart() {
            super.onStart()
            Clomni.addUnreadCountListener(unread)
        }
    
        override fun onStop() {
            Clomni.removeUnreadCountListener(unread)
            super.onStop()
        }
    }

    Плавающая кнопка по умолчанию выключена: Clomni.setLauncherVisible(true), а Clomni.setBottomPadding(72) (dp) поднимает её над нижней навигацией.

  6. 6

    События, ссылки, язык и внешний вид

    Чтобы слушать события Messenger:

    Clomni.onMessengerOpened { source -> Log.d("App", "opened from $source") }
    Clomni.onMessengerClosed { Log.d("App", "closed") }
    Clomni.onConversationStarted { id -> Log.d("App", "conversation $id") }
    Clomni.onFlowCompleted { flowId -> Log.d("App", "flow $flowId completed") }
    Clomni.onUnreadCountChanged { count -> Log.d("App", "unread $count") }

    У каждого события один слушатель: новый заменяет старый, null удаляет его.

    Кнопка новости может вести на веб-адрес или deep link приложения. Если задан onLink, ссылка сначала приходит в приложение. Верните true, если приложение открыло её само; при false или без слушателя ссылку открывает система.

    Clomni.onLink { url ->
        if (url.startsWith("example://")) {
            startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)).setPackage(packageName))
            true
        } else {
            false
        }
    }

    Язык, звуки и собственный цвет приложения:

    Clomni.setLanguage("en")          // az, en or ru; null follows the phone
    Clomni.setSoundsEnabled(false)    // off whatever the panel says
    Clomni.setTheme(
        primaryColor = "#0A66C2",
        typeface = ResourcesCompat.getFont(context, R.font.montserrat),
        mode = ClomniThemeMode.DARK,      // LIGHT, DARK or SYSTEM
    )
    • setLanguage выбирает один из языков, включённых в панели (Appearance › «Languages»). Пустое значение или выключенный язык: используется язык телефона, а если его нет, основной язык панели.
    • Звуки: короткий звук отправленного и полученного сообщения, пока диалог открыт. Подчиняется беззвучному режиму телефона.
    • setTheme накладывает собственный цвет, шрифт и режим приложения поверх настроек панели. Цвет в формате #RRGGBB, остальные цвета бренда выводятся из него. Каждый вызов заменяет предыдущий, не переданное значение остаётся из панели. При неверном формате в логе будет setTheme: primaryColor "…" is not #RRGGBB.
    • Только шрифт: Clomni.setTypeface(typeface). Шрифт по-прежнему следует настройке размера текста у пользователя.
  7. 7

    Push: подключите Firebase к приложению

    Ответы операторов приходят в закрытое приложение как data-сообщения FCM. У SDK нет зависимости от Firebase: приложение сохраняет свою библиотеку firebase-messaging, и Ваши собственные push остаются Вашими.

    Firebase console › Ваш проект › Project Overview › + Add app › Android: введите имя пакета, «Register app», скачайте google-services.json и положите в папку app/.

    // settings.gradle.kts (or the root build.gradle.kts)
    plugins {
        id("com.google.gms.google-services") version "4.4.2" apply false
    }
    // app/build.gradle.kts
    plugins {
        id("com.android.application")
        id("org.jetbrains.kotlin.android")
        id("com.google.gms.google-services")
    }
    
    dependencies {
        implementation("ai.clomni:messenger:1.0.5")
        implementation(platform("com.google.firebase:firebase-bom:33.4.0"))
        implementation("com.google.firebase:firebase-messaging")
    }

    В панель загружается не google-services.json, а файл service account JSON проекта: смотрите статью «Ключи push для мобильного SDK».

  8. 8

    Push: передайте токен и сообщения

    // AppMessagingService.kt
    import ai.clomni.messenger.Clomni
    import ai.clomni.messenger.ClomniPush
    import com.google.firebase.messaging.FirebaseMessagingService
    import com.google.firebase.messaging.RemoteMessage
    
    class AppMessagingService : FirebaseMessagingService() {
        override fun onNewToken(token: String) {
            Clomni.setDeviceToken(token)
            // and to your own server, if the app has its own pushes
        }
    
        override fun onMessageReceived(message: RemoteMessage) {
            if (ClomniPush.handle(this, message.data)) return
            // your app's own push
        }
    }
    <!-- AndroidManifest.xml, inside <application> -->
    <service
        android:name=".AppMessagingService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>

    FCM вызывает onNewToken только при смене токена. Передавайте текущий токен и при каждом запуске, в Application.onCreate после initialize:

    FirebaseMessaging.getInstance().token.addOnSuccessListener(Clomni::setDeviceToken)

    В приложении бывает только один FirebaseMessagingService. Если он уже есть, передавайте сообщения Clomni в нём. ClomniPush.isClomniPush(data) говорит, принадлежит ли push Clomni, не обрабатывая его.

  9. 9

    Push: разрешение Android 13 и иконка

    На Android 13 и новее для уведомлений нужно разрешение POST_NOTIFICATIONS. SDK сам его не запрашивает: объявите его в манифесте и запросите в подходящий момент, например после первого сообщения.

    <!-- AndroidManifest.xml -->
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
    class MainActivity : AppCompatActivity() {
        private val askNotifications = registerForActivityResult(ActivityResultContracts.RequestPermission()) { }
    
        private fun askForNotifications() {
            if (Build.VERSION.SDK_INT >= 33 &&
                ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) !=
                PackageManager.PERMISSION_GRANTED
            ) {
                askNotifications.launch(Manifest.permission.POST_NOTIFICATIONS)
            }
        }
    }

    Без разрешения уведомление не показывается, но счётчик непрочитанных обновляется. Маленькая иконка является иконкой приложения. Если это не силуэт, Android рисует серый квадрат: передайте белую силуэтную иконку через Clomni.setNotificationIcon(R.drawable.ic_notification).

    Пользователь видит одно уведомление на диалог: заголовок из оператора и бренда, текст из самого сообщения (до 180 символов). Канал уведомлений clomni_messages. Нажатие открывает приложение с этим диалогом поверх. Пока Messenger открыт, уведомления Clomni не показываются.

  10. 10

    Проверьте

    1. Запустите приложение на телефоне, разрешите уведомления и один раз откройте Messenger.
    2. Панель › Ваш канал › колонка настроек › «Push» › «Test push» › выберите устройство › «Send».

    Логи в logcat с тегом Clomni. Частые ошибки:

    • Строка лога, начинающаяся с api_key, о том, что ключ неверный или не для этой платформы (ошибка сервера invalid_api_key; SDK пишет эту строку на азербайджанском): используйте ключ android_… и проверьте, что он не отозван.
    • call Clomni.initialize first: вызывайте initialize в Application.onCreate и укажите класс в манифесте через android:name.
    • notification not shown (POST_NOTIFICATIONS?): запросите разрешение Android 13+.
    • onMessageReceived Вашего сервиса не вызывается: сервиса нет в манифесте, или сообщения забирает другой FirebaseMessagingService.

    Из Java: Clomni.initialize(context, "app_…", "android_…");, Clomni.loginUser(new ClomniUser("12345", "[email protected]"), hashFromYourServer);, Clomni.present("profile_support");.

  11. 11

    Полное руководство

Документ