Библиотека Core-Telecom
упрощает процесс интеграции вашего приложения для звонков с платформой Android, предоставляя надежный и согласованный набор API.
Если вы хотите изучить практические реализации, вы можете найти примеры приложений на GitHub:
- Облегченный образец приложения — минимальный пример, демонстрирующий использование API
Core-Telecom
. Идеально подходит для быстрого понимания фундаментальных концепций. - Комплексный образец приложения (разработанный командой Core-Telecom) — более многофункциональное приложение, демонстрирующее расширенные функции телекоммуникаций и лучшие практики. Это отличный ресурс для понимания сложных сценариев интеграции.
Настройка 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
для обработки действий, инициированных этими устройствами.
Когда происходит удаленное действие, вызывается соответствующая лямбда.
Успешное завершение лямбды сигнализирует о том, что команда обработана. Если команду невозможно выполнить, лямбда должна выдать исключение.
Правильная реализация обеспечивает плавное управление вызовами на разных устройствах. Тщательно проверьте различные удаленные поверхности.