Core-Telecom
库通过提供一组强大且一致的 API,简化了将调用应用与 Android 平台集成的过程
如果您想探索实际实现,可以前往 GitHub 查找示例应用:
- 轻量级示例应用 - 一个最小示例,演示了
Core-Telecom
API 的使用。非常适合快速了解基本概念。 - 全面的示例应用(由 Core-Telecom 团队开发) - 功能更丰富的应用,展示了高级 Telecom 功能和最佳实践。这是一个非常有用的资源,可帮助您了解复杂的集成场景。
设置 Core-Telecom
将 androidx.core:core-telecom
依赖项添加到应用的 build.gradle
文件中:
dependencies {
implementation ("androidx.core:core-telecom:1.0.0")
}
在 AndroidManifest.xml
中声明 MANAGE_OWN_CALLS
权限:
<uses-permission android:name="android.permission.MANAGE_OWN_CALLS" />
注册您的应用程序
使用 CallsManager
向 Android 注册调用应用,以开始向系统添加调用。注册时,请指定应用的功能(例如音频、视频支持):
val callsManager = CallsManager(context)
val capabilities: @CallsManager.Companion.Capability Int =
(CallsManager.CAPABILITY_BASELINE or
CallsManager.CAPABILITY_SUPPORTS_VIDEO_CALLING)
callsManager.registerAppWithTelecom(capabilities)
通话管理
使用 Core-Telecom API 创建和管理通话生命周期。
创建通话
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
和回调结合使用,可向系统添加新调用并管理远程 Surface 更新。addCall
块中的 callControlScope
主要用于让应用转换通话状态并接收音频更新:
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 */ }
}
拒绝来电
在 CallControlScope
中使用 DisconnectCause.REJECTED
与 disconnect()
拒接来电:
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))
管理通话音频端点
使用 CallControlScope
中的 currentCallEndpoint
、availableEndpoints
和 isMuted
Flow
监控和管理音频端点
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
(Android 13 API 级别 33 及更低版本)或 foregroundtypes(Android 14 API 级别 34 及更高版本)来提供前台支持。
根据前台运行要求,应用必须发布通知,以便用户知道应用正在前台运行。
为确保您的应用获得前台执行优先级,请在添加与平台的调用后创建通知。当您的应用终止调用或通知不再有效时,系统会移除前台优先级。
远程 Surface 支持
远程设备(智能手表、蓝牙耳机、Android Auto)无需直接与手机互动,即可管理通话。您的应用必须实现提供给 CallsManager.addCall
的回调 lambda(onAnswerCall
、onSetCallDisconnected
、onSetCallActive
、onSetCallInactive
),以处理这些设备发起的操作。
当发生远程操作时,系统会调用相应的 lambda。
成功完成 lambda 会指示系统已处理该命令。如果无法执行该命令,lambda 应抛出异常。
正确的实现可确保在不同设备上无缝控制通话。使用各种远程 Surface 进行全面测试。