Кор-Телеком

Библиотека Core-Telecom упрощает процесс интеграции вашего приложения для звонков с платформой Android, предоставляя надежный и согласованный набор API.

Если вы хотите изучить практические реализации, вы можете найти примеры приложений на GitHub:

Настройка Core-Telecom

Добавьте зависимость androidx.core:core-telecom в файл build.gradle вашего приложения:

dependencies {
    implementation ("androidx.core:core-telecom:1.0.0")
}

Объявите разрешение MANAGE_OWN_CALLS в своем AndroidManifest.xml :

<uses-permission android:name="android.permission.MANAGE_OWN_CALLS" />

Зарегистрируйте свое приложение

Зарегистрируйте свое приложение для звонков на Android с помощью CallsManager , чтобы начать добавлять звонки в систему. При регистрации укажите возможности вашего приложения (например, поддержка аудио, видео):

val callsManager = CallsManager(context)

val capabilities: @CallsManager.Companion.Capability Int =
    (CallsManager.CAPABILITY_BASELINE or
          CallsManager.CAPABILITY_SUPPORTS_VIDEO_CALLING)

callsManager.registerAppWithTelecom(capabilities)

Управление вызовами

Используйте API Core-Telecom для создания жизненного цикла вызова и управления им.

Создать звонок

Объект CallAttributesCompat определяет свойства уникального вызова, который может иметь следующие характеристики:

  • displayName : имя вызывающего абонента.
  • address : адрес вызова (например, номер телефона, ссылка на встречу).
  • direction : входящее или исходящее.
  • callType : Аудио или видео.
  • callCapabilities : поддерживает передачу и удержание.

Вот пример того, как создать входящий звонок:

fun createIncomingCallAttributes(
    callerName: String,
    callerNumber: String,
    isVideoCall: Boolean): CallAttributesCompat {
    val addressUri = Uri.parse("YourAppScheme:$callerNumber")

    // Define capabilities supported by your call.
    val callCapabilities = CallAttributesCompat.CallCapability(
        supportsSetInactive = CallAttributesCompat.SUPPORTS_SET_INACTIVE // Call can be made inactive (implies hold)
    )

    return CallAttributesCompat(
        displayName = callerName,
        address = addressUri,
        direction = CallAttributesCompat.DIRECTION_INCOMING,
        callType = if (isVideoCall) CallAttributesCompat.CALL_TYPE_VIDEO_CALL else CallAttributesCompat.CALL_TYPE_AUDIO_CALL,
        callCapabilitiesCompat = callCapabilities
    )
}

Добавить звонок

Используйте callsManager.addCall с CallAttributesCompat и обратными вызовами, чтобы добавить новый вызов в систему и управлять обновлениями удаленной поверхности. callControlScope в блоке addCall в первую очередь позволяет вашему приложению изменять состояние вызова и получать аудиообновления:

try {
    callsManager.addCall(
        INCOMING_CALL_ATTRIBUTES,
        onAnswerCall, // Watch needs to know if it can answer the call.
        onSetCallDisconnected,
        onSetCallActive,
        onSetCallInactive
    ) {
        // The call was successfully added once this scope runs.
        callControlScope = this
    }
}
catch(addCallException: Exception){
   // Handle the addCall failure.
}

Ответить на звонок

Ответьте на входящий вызов в CallControlScope :

when (val result = answer(CallAttributesCompat.CALL_TYPE_AUDIO_CALL)) {
    is CallControlResult.Success -> { /* Call answered */ }
    is CallControlResult.Error -> { /* Handle error */ }
}

Отклонить вызов

Отклоните вызов с помощью disconnect() с DisconnectCause.REJECTED в CallControlScope :

disconnect(DisconnectCause(DisconnectCause.REJECTED))

Сделать исходящий звонок активным

Сделайте исходящий вызов активным, как только удаленный абонент ответит:

when (val result = setActive()) {
    is CallControlResult.Success -> { /* Call active */ }
    is CallControlResult.Error -> { /* Handle error */ }
}

Поставить звонок на удержание

Используйте setInactive() , чтобы поставить вызов на удержание:

when (val result = setInactive()) {
    is CallControlResult.Success -> { /* Call on hold */ }
    is CallControlResult.Error -> { /* Handle error */ }
}

Отключить вызов

Разъедините вызов с помощью disconnect() с DisconnectCause :

disconnect(DisconnectCause(DisconnectCause.LOCAL))

Управление конечными точками аудиовызова

Наблюдайте за конечными точками аудио и управляйте ими с помощью currentCallEndpoint , availableEndpoints и isMuted Flow в CallControlScope

fun observeAudioStateChanges(callControlScope: CallControlScope) {
    with(callControlScope) {
        launch { currentCallEndpoint.collect { /* Update UI */ } }
        launch { availableEndpoints.collect { /* Update UI */ } }
        launch { isMuted.collect { /* Handle mute state */ } }
    }
}

Измените активное аудиоустройство с помощью requestEndpointChange() :

coroutineScope.launch {
     callControlScope.requestEndpointChange(callEndpoint)
}

Поддержка переднего плана

Библиотека использует ConnectionService (API Android 13 уровня 33 и ниже) или типы переднего плана (API Android 14 уровня 34 и выше) для поддержки переднего плана.

В рамках требований к приоритетному режиму приложение должно опубликовать уведомление, чтобы пользователи знали, что приложение работает на переднем плане.

Чтобы гарантировать, что ваше приложение получает приоритет выполнения на переднем плане, создайте уведомление после добавления вызова на платформу. Приоритет переднего плана удаляется, когда ваше приложение завершает вызов или когда ваше уведомление становится недействительным.

Узнайте больше о службах переднего плана .

Поддержка удаленной поверхности

Удаленные устройства (умные часы, Bluetooth-гарнитуры, Android Auto) способны управлять вызовами без прямого взаимодействия с телефоном. Ваше приложение должно реализовать лямбда-выражения обратного вызова ( onAnswerCall , onSetCallDisconnected , onSetCallActive , onSetCallInactive ), предоставленные CallsManager.addCall для обработки действий, инициированных этими устройствами.

Когда происходит удаленное действие, вызывается соответствующая лямбда.

Успешное завершение лямбды сигнализирует о том, что команда обработана. Если команду невозможно выполнить, лямбда должна выдать исключение.

Правильная реализация обеспечивает плавное управление вызовами на разных устройствах. Тщательно проверьте различные удаленные поверхности.